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"; 54bdc48fa1SJoe 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 100bdc48fa1SJoe Perches --max-line-length=n set the maximum line length, (default $max_line_length) 101bdc48fa1SJoe Perches if exceeded, warn on patches 102bdc48fa1SJoe Perches requires --strict for use with --file 10356193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 104bdc48fa1SJoe 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 3065*7ccf41a8SJoe Perches# check MAINTAINERS entries 3066*7ccf41a8SJoe Perches if ($realfile =~ /^MAINTAINERS$/) { 3067*7ccf41a8SJoe Perches# check MAINTAINERS entries for the right form 3068*7ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3069628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3070628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3071628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3072628f91a2SJoe Perches $fix) { 3073628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3074628f91a2SJoe Perches } 3075628f91a2SJoe Perches } 3076*7ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too 3077*7ccf41a8SJoe Perches my $preferred_order = 'MRLSWQBCPTFXNK'; 3078*7ccf41a8SJoe Perches if ($rawline =~ /^\+[A-Z]:/ && 3079*7ccf41a8SJoe Perches $prevrawline =~ /^[\+ ][A-Z]:/) { 3080*7ccf41a8SJoe Perches $rawline =~ /^\+([A-Z]):\s*(.*)/; 3081*7ccf41a8SJoe Perches my $cur = $1; 3082*7ccf41a8SJoe Perches my $curval = $2; 3083*7ccf41a8SJoe Perches $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; 3084*7ccf41a8SJoe Perches my $prev = $1; 3085*7ccf41a8SJoe Perches my $prevval = $2; 3086*7ccf41a8SJoe Perches my $curindex = index($preferred_order, $cur); 3087*7ccf41a8SJoe Perches my $previndex = index($preferred_order, $prev); 3088*7ccf41a8SJoe Perches if ($curindex < 0) { 3089*7ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 3090*7ccf41a8SJoe Perches "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); 3091*7ccf41a8SJoe Perches } else { 3092*7ccf41a8SJoe Perches if ($previndex >= 0 && $curindex < $previndex) { 3093*7ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 3094*7ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); 3095*7ccf41a8SJoe Perches } elsif ((($prev eq 'F' && $cur eq 'F') || 3096*7ccf41a8SJoe Perches ($prev eq 'X' && $cur eq 'X')) && 3097*7ccf41a8SJoe Perches ($prevval cmp $curval) > 0) { 3098*7ccf41a8SJoe Perches WARN("MAINTAINERS_STYLE", 3099*7ccf41a8SJoe Perches "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); 3100*7ccf41a8SJoe Perches } 3101*7ccf41a8SJoe Perches } 3102*7ccf41a8SJoe Perches } 3103*7ccf41a8SJoe Perches } 3104628f91a2SJoe Perches 3105327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 3106327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 3107327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 3108327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 3109327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 3110327953e9SChristoph Jaeger } 3111327953e9SChristoph Jaeger 3112c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3113c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3114c68e5878SArnaud Lacombe my $flag = $1; 3115c68e5878SArnaud Lacombe my $replacement = { 3116c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3117c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3118c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3119c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3120c68e5878SArnaud Lacombe }; 3121c68e5878SArnaud Lacombe 3122c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3123c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3124c68e5878SArnaud Lacombe } 3125c68e5878SArnaud Lacombe 3126bff5da43SRob Herring# check for DT compatible documentation 31277dd05b38SFlorian Vaussard if (defined $root && 31287dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 31297dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 31307dd05b38SFlorian Vaussard 3131bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3132bff5da43SRob Herring 3133cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3134852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3135cc93319bSFlorian Vaussard 3136bff5da43SRob Herring foreach my $compat (@compats) { 3137bff5da43SRob Herring my $compat2 = $compat; 3138185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3139185d566bSRob Herring my $compat3 = $compat; 3140185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3141185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3142bff5da43SRob Herring if ( $? >> 8 ) { 3143bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3144bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3145bff5da43SRob Herring } 3146bff5da43SRob Herring 31474fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 31484fbf32a6SFlorian Vaussard my $vendor = $1; 3149852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3150bff5da43SRob Herring if ( $? >> 8 ) { 3151bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3152cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3153bff5da43SRob Herring } 3154bff5da43SRob Herring } 3155bff5da43SRob Herring } 3156bff5da43SRob Herring 31579f3a8992SRob Herring# check for using SPDX license tag at beginning of files 31589f3a8992SRob Herring if ($realline == $checklicenseline) { 31599f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 31609f3a8992SRob Herring $checklicenseline = 2; 31619f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 31629f3a8992SRob Herring my $comment = ""; 31639f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 31649f3a8992SRob Herring $comment = '/*'; 31659f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 31669f3a8992SRob Herring $comment = '//'; 3167c8df0ab6SLubomir Rintel } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { 31689f3a8992SRob Herring $comment = '#'; 31699f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 31709f3a8992SRob Herring $comment = '..'; 31719f3a8992SRob Herring } 31729f3a8992SRob Herring 3173fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3174fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3175fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3176ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3177fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3178fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3179fdf13693SJoe Perches } 3180fdf13693SJoe Perches 31819f3a8992SRob Herring if ($comment !~ /^$/ && 3182ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 31839f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 31849f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 31853b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 31863b6e8ac9SJoe Perches my $spdx_license = $1; 31873b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 31883b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 31893b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 31903b6e8ac9SJoe Perches } 319150c92900SLubomir Rintel if ($realfile =~ m@^Documentation/devicetree/bindings/@ && 319250c92900SLubomir Rintel not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { 319350c92900SLubomir Rintel my $msg_level = \&WARN; 319450c92900SLubomir Rintel $msg_level = \&CHK if ($file); 319550c92900SLubomir Rintel if (&{$msg_level}("SPDX_LICENSE_TAG", 319650c92900SLubomir Rintel 319750c92900SLubomir Rintel "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && 319850c92900SLubomir Rintel $fix) { 319950c92900SLubomir Rintel $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; 320050c92900SLubomir Rintel } 320150c92900SLubomir Rintel } 32029f3a8992SRob Herring } 32039f3a8992SRob Herring } 32049f3a8992SRob Herring } 32059f3a8992SRob Herring 32065368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3207d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 32085368df20SAndy Whitcroft 3209a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3210a8da38a9SJoe Perches if ($realline != $checklicenseline && 3211a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3212a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3213a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3214a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3215a8da38a9SJoe Perches } 3216a8da38a9SJoe Perches 321747e0c88bSJoe Perches# line length limit (with some exclusions) 321847e0c88bSJoe Perches# 321947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 322047e0c88bSJoe Perches# logging functions like pr_info that end in a string 322147e0c88bSJoe Perches# lines with a single string 322247e0c88bSJoe Perches# #defines that are a single string 32232e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 322447e0c88bSJoe Perches# 322547e0c88bSJoe Perches# There are 3 different line length message types: 3226ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 322747e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 322847e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 322947e0c88bSJoe Perches# 323047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 323147e0c88bSJoe Perches# 323247e0c88bSJoe Perches 3233b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 323447e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 323547e0c88bSJoe Perches 323647e0c88bSJoe Perches # Check the allowed long line types first 323747e0c88bSJoe Perches 323847e0c88bSJoe Perches # logging functions that end in a string that starts 323947e0c88bSJoe Perches # before $max_line_length 324047e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 324147e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 324247e0c88bSJoe Perches $msg_type = ""; 324347e0c88bSJoe Perches 324447e0c88bSJoe Perches # lines with only strings (w/ possible termination) 324547e0c88bSJoe Perches # #defines with only strings 324647e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 324747e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 324847e0c88bSJoe Perches $msg_type = ""; 324947e0c88bSJoe Perches 3250cc147506SJoe Perches # More special cases 3251cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3252cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3253d560a5f8SJoe Perches $msg_type = ""; 3254d560a5f8SJoe Perches 32552e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 32562e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 32572e4bbbc5SAndreas Brauchli $msg_type = ""; 32582e4bbbc5SAndreas Brauchli 325947e0c88bSJoe Perches # Otherwise set the alternate message types 326047e0c88bSJoe Perches 326147e0c88bSJoe Perches # a comment starts before $max_line_length 326247e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 326347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 326447e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 326547e0c88bSJoe Perches 326647e0c88bSJoe Perches # a quoted string starts before $max_line_length 326747e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 326847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 326947e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 327047e0c88bSJoe Perches } 327147e0c88bSJoe Perches 327247e0c88bSJoe Perches if ($msg_type ne "" && 327347e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 3274bdc48fa1SJoe Perches my $msg_level = \&WARN; 3275bdc48fa1SJoe Perches $msg_level = \&CHK if ($file); 3276bdc48fa1SJoe Perches &{$msg_level}($msg_type, 3277bdc48fa1SJoe Perches "line length of $length exceeds $max_line_length columns\n" . $herecurr); 32780a920b5bSAndy Whitcroft } 327947e0c88bSJoe Perches } 32800a920b5bSAndy Whitcroft 32818905a67cSAndy Whitcroft# check for adding lines without a newline. 32828905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 3283000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 3284000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 32858905a67cSAndy Whitcroft } 32868905a67cSAndy Whitcroft 3287b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3288de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 32890a920b5bSAndy Whitcroft 32900a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 3291713a09deSAntonio Borneo# more than $tabsize must use tabs. 3292c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3293c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3294c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3295d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 32963705ce5bSJoe Perches if (ERROR("CODE_INDENT", 32973705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 32983705ce5bSJoe Perches $fix) { 3299194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 33003705ce5bSJoe Perches } 33010a920b5bSAndy Whitcroft } 33020a920b5bSAndy Whitcroft 330308e44365SAlberto Panizzo# check for space before tabs. 330408e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 330508e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 33063705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 33073705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 33083705ce5bSJoe Perches $fix) { 3309194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3310713a09deSAntonio Borneo s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} 3311194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3312c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 33133705ce5bSJoe Perches } 331408e44365SAlberto Panizzo } 331508e44365SAlberto Panizzo 33166a487211SJoe Perches# check for assignments on the start of a line 33176a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 33186a487211SJoe Perches CHK("ASSIGNMENT_CONTINUATIONS", 33196a487211SJoe Perches "Assignment operator '$1' should be on the previous line\n" . $hereprev); 33206a487211SJoe Perches } 33216a487211SJoe Perches 3322d1fe9c09SJoe Perches# check for && or || at the start of a line 3323d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 3324d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 3325d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 3326d1fe9c09SJoe Perches } 3327d1fe9c09SJoe Perches 3328a91e8994SJoe Perches# check indentation starts on a tab stop 33295b57980dSJoe Perches if ($perl_version_ok && 3330bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3331a91e8994SJoe Perches my $indent = length($1); 3332713a09deSAntonio Borneo if ($indent % $tabsize) { 3333a91e8994SJoe Perches if (WARN("TABSTOP", 3334a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3335a91e8994SJoe Perches $fix) { 3336713a09deSAntonio Borneo $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; 3337a91e8994SJoe Perches } 3338a91e8994SJoe Perches } 3339a91e8994SJoe Perches } 3340a91e8994SJoe Perches 3341d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 33425b57980dSJoe Perches if ($perl_version_ok && 3343fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3344d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3345d1fe9c09SJoe Perches my $oldindent = $1; 3346d1fe9c09SJoe Perches my $rest = $2; 3347d1fe9c09SJoe Perches 3348d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3349d1fe9c09SJoe Perches if ($pos >= 0) { 3350b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3351b34a26f3SJoe Perches my $newindent = $2; 3352d1fe9c09SJoe Perches 3353d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3354713a09deSAntonio Borneo "\t" x ($pos / $tabsize) . 3355713a09deSAntonio Borneo " " x ($pos % $tabsize); 3356d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3357d1fe9c09SJoe Perches 3358d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3359d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 33603705ce5bSJoe Perches 33613705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 33623705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 33633705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3364194f66fcSJoe Perches $fixed[$fixlinenr] =~ 33653705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 33663705ce5bSJoe Perches } 3367d1fe9c09SJoe Perches } 3368d1fe9c09SJoe Perches } 3369d1fe9c09SJoe Perches } 3370d1fe9c09SJoe Perches 33716ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 33726ab3a970SJoe Perches# avoid checking a few false positives: 33736ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 33746ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 33756ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 33766ab3a970SJoe Perches# multiline macros that define functions 33776ab3a970SJoe Perches# known attributes or the __attribute__ keyword 33786ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 33796ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 33803705ce5bSJoe Perches if (CHK("SPACING", 3381f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 33823705ce5bSJoe Perches $fix) { 3383194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3384f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 33853705ce5bSJoe Perches } 3386aad4f614SJoe Perches } 3387aad4f614SJoe Perches 338886406b1cSJoe Perches# Block comment styles 338986406b1cSJoe Perches# Networking with an initial /* 339005880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3391fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 339285ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 339385ad978cSJoe Perches $realline > 2) { 339405880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 339505880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 339605880600SJoe Perches } 339705880600SJoe Perches 339886406b1cSJoe Perches# Block comments use * on subsequent lines 339986406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 340086406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3401a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 340261135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3403a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 340486406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 340586406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3406a605e32eSJoe Perches } 3407a605e32eSJoe Perches 340886406b1cSJoe Perches# Block comments use */ on trailing lines 340986406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3410c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3411c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3412c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 341386406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 341486406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 341505880600SJoe Perches } 341605880600SJoe Perches 341708eb9b80SJoe Perches# Block comment * alignment 341808eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3419af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3420af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3421af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 342208eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3423af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3424af207524SJoe Perches my $oldindent; 342508eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3426af207524SJoe Perches if (defined($1)) { 3427af207524SJoe Perches $oldindent = expand_tabs($1); 3428af207524SJoe Perches } else { 3429af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3430af207524SJoe Perches $oldindent = expand_tabs($1); 3431af207524SJoe Perches } 343208eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 343308eb9b80SJoe Perches my $newindent = $1; 343408eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3435af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 343608eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 343708eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 343808eb9b80SJoe Perches } 343908eb9b80SJoe Perches } 344008eb9b80SJoe Perches 34417f619191SJoe Perches# check for missing blank lines after struct/union declarations 34427f619191SJoe Perches# with exceptions for various attributes and macros 34437f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 34447f619191SJoe Perches $line =~ /^\+/ && 34457f619191SJoe Perches !($line =~ /^\+\s*$/ || 34467f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 34477f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 34487f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 34497f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 34507f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 34517f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 34520bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 34537f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3454d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3455d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3456d752fcc8SJoe Perches $fix) { 3457f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3458d752fcc8SJoe Perches } 34597f619191SJoe Perches } 34607f619191SJoe Perches 3461365dd4eaSJoe Perches# check for multiple consecutive blank lines 3462365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3463365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3464365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3465d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3466d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3467d752fcc8SJoe Perches $fix) { 3468f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3469d752fcc8SJoe Perches } 3470d752fcc8SJoe Perches 3471365dd4eaSJoe Perches $last_blank_line = $linenr; 3472365dd4eaSJoe Perches } 3473365dd4eaSJoe Perches 34743b617e3bSJoe Perches# check for missing blank lines after declarations 34753f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 34763f7bac03SJoe Perches # actual declarations 34773f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 34785a4e1fd3SJoe Perches # function pointer declarations 34795a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 34803f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 34813f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 34823f7bac03SJoe Perches # known declaration macros 34833f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 34843f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 34853f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 34863f7bac03SJoe Perches # other possible extensions of declaration lines 34873f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 34883f7bac03SJoe Perches # not starting a section or a macro "\" extended line 34893f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 34903f7bac03SJoe Perches # looks like a declaration 34913f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 34925a4e1fd3SJoe Perches # function pointer declarations 34935a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 34943f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 34953f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 34963f7bac03SJoe Perches # known declaration macros 34973f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 34983f7bac03SJoe Perches # start of struct or union or enum 3499328b5f41SJoe Perches $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 35003f7bac03SJoe Perches # start or end of block or continuation of declaration 35013f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 35023f7bac03SJoe Perches # bitfield continuation 35033f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 35043f7bac03SJoe Perches # other possible extensions of declaration lines 35053f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 35063f7bac03SJoe Perches # indentation of previous and current line are the same 35073f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3508d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3509d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3510d752fcc8SJoe Perches $fix) { 3511f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3512d752fcc8SJoe Perches } 35133b617e3bSJoe Perches } 35143b617e3bSJoe Perches 35155f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 35166b4c5bebSAndy Whitcroft# Exceptions: 35176b4c5bebSAndy Whitcroft# 1) within comments 35186b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 35196b4c5bebSAndy Whitcroft# 3) hanging labels 35203705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 35215f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 35223705ce5bSJoe Perches if (WARN("LEADING_SPACE", 35233705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 35243705ce5bSJoe Perches $fix) { 3525194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 35263705ce5bSJoe Perches } 35275f7ddae6SRaffaele Recalcati } 35285f7ddae6SRaffaele Recalcati 3529b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3530b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3531b9ea10d6SAndy Whitcroft 35325751a24eSJoe Perches# check for unusual line ending [ or ( 35335751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 35345751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 35355751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 35365751a24eSJoe Perches } 35375751a24eSJoe Perches 35384dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 35394dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 35404dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 35414dbed76fSJoe Perches $context_function = $1; 35424dbed76fSJoe Perches } 35434dbed76fSJoe Perches 35444dbed76fSJoe Perches# check if this appears to be the end of function declaration 35454dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 35464dbed76fSJoe Perches undef $context_function; 35474dbed76fSJoe Perches } 35484dbed76fSJoe Perches 3549032a4c0fSJoe Perches# check indentation of any line with a bare else 3550840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3551032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3552032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3553032a4c0fSJoe Perches my $tabs = length($1) + 1; 3554840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3555840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3556840080a0SJoe Perches defined $lines[$linenr] && 3557840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3558032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3559032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3560032a4c0fSJoe Perches } 3561032a4c0fSJoe Perches } 3562032a4c0fSJoe Perches 3563c00df19aSJoe Perches# check indentation of a line with a break; 3564c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3565c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3566c00df19aSJoe Perches my $tabs = $1; 3567c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3568c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3569c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3570c00df19aSJoe Perches } 3571c00df19aSJoe Perches } 3572c00df19aSJoe Perches 3573c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3574cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3575000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3576000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3577c2fdda0dSAndy Whitcroft } 357822f2a2efSAndy Whitcroft 357956e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 358056e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 358156e77d70SJoe Perches WARN("HOTPLUG_SECTION", 358256e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 358356e77d70SJoe Perches } 358456e77d70SJoe Perches 35859c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 35862b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 35872b474a1aSAndy Whitcroft $realline_next); 35883e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3589ca819864SJoe Perches if ($linenr > $suppress_statement && 35901b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3591170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3592f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3593171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3594171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3595171ae1a4SAndy Whitcroft 35963e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 35973e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 35983e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 35993e469cdcSAndy Whitcroft # until we hit end of it. 36003e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 36013e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 36023e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 36033e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 36043e469cdcSAndy Whitcroft } 3605f74bd194SAndy Whitcroft 36062b474a1aSAndy Whitcroft # Find the real next line. 36072b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 36082b474a1aSAndy Whitcroft if (defined $realline_next && 36092b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 36102b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 36112b474a1aSAndy Whitcroft $realline_next++; 36122b474a1aSAndy Whitcroft } 36132b474a1aSAndy Whitcroft 3614171ae1a4SAndy Whitcroft my $s = $stat; 3615171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3616cf655043SAndy Whitcroft 3617c2fdda0dSAndy Whitcroft # Ignore goto labels. 3618171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3619c2fdda0dSAndy Whitcroft 3620c2fdda0dSAndy Whitcroft # Ignore functions being called 3621171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3622c2fdda0dSAndy Whitcroft 3623463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3624463f2864SAndy Whitcroft 3625c45dcabdSAndy Whitcroft # declarations always start with types 3626d2506586SAndy 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) { 3627c45dcabdSAndy Whitcroft my $type = $1; 3628c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3629c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3630c45dcabdSAndy Whitcroft 36316c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3632a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3633c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3634c2fdda0dSAndy Whitcroft } 36358905a67cSAndy Whitcroft 36366c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 363765863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3638c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 36399c0ca6f9SAndy Whitcroft } 36408905a67cSAndy Whitcroft 36418905a67cSAndy Whitcroft # Check for any sort of function declaration. 36428905a67cSAndy Whitcroft # int foo(something bar, other baz); 36438905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3644171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 36458905a67cSAndy Whitcroft my ($name_len) = length($1); 36468905a67cSAndy Whitcroft 3647cf655043SAndy Whitcroft my $ctx = $s; 3648773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 36498905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3650cf655043SAndy Whitcroft 36518905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3652c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 36538905a67cSAndy Whitcroft 3654c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 36558905a67cSAndy Whitcroft } 36568905a67cSAndy Whitcroft } 36578905a67cSAndy Whitcroft } 36588905a67cSAndy Whitcroft 36599c0ca6f9SAndy Whitcroft } 36609c0ca6f9SAndy Whitcroft 366100df344fSAndy Whitcroft# 366200df344fSAndy Whitcroft# Checks which may be anchored in the context. 366300df344fSAndy Whitcroft# 366400df344fSAndy Whitcroft 366500df344fSAndy Whitcroft# Check for switch () and associated case and default 366600df344fSAndy Whitcroft# statements should be at the same indent. 366700df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 366800df344fSAndy Whitcroft my $err = ''; 366900df344fSAndy Whitcroft my $sep = ''; 367000df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 367100df344fSAndy Whitcroft shift(@ctx); 367200df344fSAndy Whitcroft for my $ctx (@ctx) { 367300df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 367400df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 367500df344fSAndy Whitcroft $indent != $cindent) { 367600df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 367700df344fSAndy Whitcroft $sep = ''; 367800df344fSAndy Whitcroft } else { 367900df344fSAndy Whitcroft $sep = "[...]\n"; 368000df344fSAndy Whitcroft } 368100df344fSAndy Whitcroft } 368200df344fSAndy Whitcroft if ($err ne '') { 3683000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3684000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3685de7d4f0eSAndy Whitcroft } 3686de7d4f0eSAndy Whitcroft } 3687de7d4f0eSAndy Whitcroft 3688de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3689de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 36900fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3691773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3692773647a0SAndy Whitcroft 36939c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 36948eef05ddSJoe Perches 36958eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 36968eef05ddSJoe Perches WARN("DEEP_INDENTATION", 36978eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 36988eef05ddSJoe Perches } 36998eef05ddSJoe Perches 3700de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3701de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3702de7d4f0eSAndy Whitcroft 3703548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3704548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3705de7d4f0eSAndy Whitcroft 3706548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3707548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3708548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3709548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3710548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3711773647a0SAndy Whitcroft $ctx_ln++; 3712773647a0SAndy Whitcroft } 3713548596d5SAndy Whitcroft 371453210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 371553210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3716773647a0SAndy Whitcroft 3717773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3718000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3719000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 372001464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 372100df344fSAndy Whitcroft } 3722773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3723773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3724773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3725773647a0SAndy Whitcroft { 37269c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 37279c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3728000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3729000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 373001464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 37319c0ca6f9SAndy Whitcroft } 37329c0ca6f9SAndy Whitcroft } 373300df344fSAndy Whitcroft } 373400df344fSAndy Whitcroft 37354d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3736f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 37373e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 37383e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 37393e469cdcSAndy Whitcroft if (!defined $stat); 37404d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 37414d001e4dSAndy Whitcroft 37424d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 37434d001e4dSAndy Whitcroft 37449f5af480SJoe Perches # remove inline comments 37459f5af480SJoe Perches $s =~ s/$;/ /g; 37469f5af480SJoe Perches $c =~ s/$;/ /g; 37474d001e4dSAndy Whitcroft 37484d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 37496f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 37506f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 37514d001e4dSAndy Whitcroft 37529f5af480SJoe Perches # Make sure we remove the line prefixes as we have 37539f5af480SJoe Perches # none on the first line, and are going to readd them 37549f5af480SJoe Perches # where necessary. 37559f5af480SJoe Perches $s =~ s/\n./\n/gs; 37569f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 37579f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 37589f5af480SJoe Perches } 37599f5af480SJoe Perches 37604d001e4dSAndy Whitcroft # We want to check the first line inside the block 37614d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 37624d001e4dSAndy Whitcroft # 1) any blank line termination 37634d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 37644d001e4dSAndy Whitcroft # 3) any do (...) { 37654d001e4dSAndy Whitcroft my $continuation = 0; 37664d001e4dSAndy Whitcroft my $check = 0; 37674d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 37684d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 37694d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 37704d001e4dSAndy Whitcroft $continuation = 1; 37714d001e4dSAndy Whitcroft } 37729bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 37734d001e4dSAndy Whitcroft $check = 1; 37744d001e4dSAndy Whitcroft $cond_lines++; 37754d001e4dSAndy Whitcroft } 37764d001e4dSAndy Whitcroft 37774d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 37784d001e4dSAndy Whitcroft # preprocessor statement. 37794d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 37804d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 37814d001e4dSAndy Whitcroft $check = 0; 37824d001e4dSAndy Whitcroft } 37834d001e4dSAndy Whitcroft 37849bd49efeSAndy Whitcroft my $cond_ptr = -1; 3785740504c6SAndy Whitcroft $continuation = 0; 37869bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 37879bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 37884d001e4dSAndy Whitcroft 3789f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3790f16fa28fSAndy Whitcroft # is not linear. 3791f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3792f16fa28fSAndy Whitcroft $check = 0; 3793f16fa28fSAndy Whitcroft } 3794f16fa28fSAndy Whitcroft 37959bd49efeSAndy Whitcroft # Ignore: 37969bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 37979bd49efeSAndy Whitcroft # 2) preprocessor lines, and 37989bd49efeSAndy Whitcroft # 3) labels. 3799740504c6SAndy Whitcroft if ($continuation || 3800740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 38019bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 38029bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3803740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 380430dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 38059bd49efeSAndy Whitcroft $cond_lines++; 38069bd49efeSAndy Whitcroft } 38074d001e4dSAndy Whitcroft } 380830dad6ebSAndy Whitcroft } 38094d001e4dSAndy Whitcroft 38104d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 38114d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 38124d001e4dSAndy Whitcroft 38134d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 38144d001e4dSAndy Whitcroft # this is not this patch's fault. 38154d001e4dSAndy Whitcroft if (!defined($stat_real) || 38164d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 38174d001e4dSAndy Whitcroft $check = 0; 38184d001e4dSAndy Whitcroft } 38194d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 38204d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 38214d001e4dSAndy Whitcroft } 38224d001e4dSAndy Whitcroft 38239bd49efeSAndy 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"; 38244d001e4dSAndy Whitcroft 38259f5af480SJoe Perches if ($check && $s ne '' && 3826713a09deSAntonio Borneo (($sindent % $tabsize) != 0 || 38279f5af480SJoe Perches ($sindent < $indent) || 3828f6950a73SJoe Perches ($sindent == $indent && 3829f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 3830713a09deSAntonio Borneo ($sindent > $indent + $tabsize))) { 3831000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3832000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 38334d001e4dSAndy Whitcroft } 38344d001e4dSAndy Whitcroft } 38354d001e4dSAndy Whitcroft 38366c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 38376c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 38381f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 38391f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 38406c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3841c2fdda0dSAndy Whitcroft if ($dbg_values) { 3842c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3843cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3844cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 38451f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3846c2fdda0dSAndy Whitcroft } 38476c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 38486c72ffaaSAndy Whitcroft 384900df344fSAndy Whitcroft#ignore lines not being added 38503705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 385100df344fSAndy Whitcroft 385211ca40a0SJoe Perches# check for dereferences that span multiple lines 385311ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 385411ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 385511ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 385611ca40a0SJoe Perches my $ref = $1; 385711ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 385811ca40a0SJoe Perches $ref .= $1; 385911ca40a0SJoe Perches $ref =~ s/\s//g; 386011ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 386111ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 386211ca40a0SJoe Perches } 386311ca40a0SJoe Perches 3864a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3865c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3866a1ce18e4SJoe Perches my $type = $1; 3867a1ce18e4SJoe Perches my $var = $2; 3868207a8e84SJoe Perches $var = "" if (!defined $var); 3869207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3870a1ce18e4SJoe Perches my $sign = $1; 3871a1ce18e4SJoe Perches my $pointer = $2; 3872a1ce18e4SJoe Perches 3873a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3874a1ce18e4SJoe Perches 3875a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3876a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3877a1ce18e4SJoe Perches $fix) { 3878a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3879207a8e84SJoe Perches my $comp_pointer = $pointer; 3880207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3881207a8e84SJoe Perches $decl .= $comp_pointer; 3882207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3883207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3884a1ce18e4SJoe Perches } 3885a1ce18e4SJoe Perches } 3886a1ce18e4SJoe Perches } 3887a1ce18e4SJoe Perches 3888653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 38897429c690SAndy Whitcroft if ($dbg_type) { 38907429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3891000d1cc1SJoe Perches ERROR("TEST_TYPE", 3892000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 38937429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3894000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3895000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 38967429c690SAndy Whitcroft } 3897653d4876SAndy Whitcroft next; 3898653d4876SAndy Whitcroft } 3899a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3900a1ef277eSAndy Whitcroft if ($dbg_attr) { 39019360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3902000d1cc1SJoe Perches ERROR("TEST_ATTR", 3903000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 39049360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3905000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3906000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3907a1ef277eSAndy Whitcroft } 3908a1ef277eSAndy Whitcroft next; 3909a1ef277eSAndy Whitcroft } 3910653d4876SAndy Whitcroft 3911f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 391299423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 391399423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3914d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3915d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3916f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3917f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3918f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3919d752fcc8SJoe Perches my $fixedline = $prevrawline; 3920d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3921f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3922d752fcc8SJoe Perches $fixedline = $line; 39238d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 3924f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3925d752fcc8SJoe Perches } 3926f0a594c1SAndy Whitcroft } 3927f0a594c1SAndy Whitcroft 392800df344fSAndy Whitcroft# 392900df344fSAndy Whitcroft# Checks which are anchored on the added line. 393000df344fSAndy Whitcroft# 393100df344fSAndy Whitcroft 3932653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3933c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3934653d4876SAndy Whitcroft my $path = $1; 3935653d4876SAndy Whitcroft if ($path =~ m{//}) { 3936000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3937495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3938495e9d84SJoe Perches } 3939495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3940495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3941495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3942653d4876SAndy Whitcroft } 3943653d4876SAndy Whitcroft } 3944653d4876SAndy Whitcroft 394500df344fSAndy Whitcroft# no C99 // comments 394600df344fSAndy Whitcroft if ($line =~ m{//}) { 39473705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 39483705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 39493705ce5bSJoe Perches $fix) { 3950194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 39513705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 39523705ce5bSJoe Perches my $comment = trim($1); 3953194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 39543705ce5bSJoe Perches } 39553705ce5bSJoe Perches } 395600df344fSAndy Whitcroft } 395700df344fSAndy Whitcroft # Remove C99 comments. 39580a920b5bSAndy Whitcroft $line =~ s@//.*@@; 39596c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 39600a920b5bSAndy Whitcroft 39612b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 39622b474a1aSAndy Whitcroft# the whole statement. 39632b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 39642b474a1aSAndy Whitcroft if (defined $realline_next && 39652b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 39662b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 39672b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 39682b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 39693cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 39703cbf62dfSAndy Whitcroft # a prefix: 39713cbf62dfSAndy Whitcroft # XXX(foo); 39723cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3973653d4876SAndy Whitcroft my $name = $1; 397487a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 39753cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 39763cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 39773cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 39783cbf62dfSAndy Whitcroft 39793cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 39802b474a1aSAndy Whitcroft \n.}\s*$| 398148012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 398248012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 398348012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 39842b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 39852b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 398648012058SAndy Whitcroft )/x) { 39872b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 39882b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 39892b474a1aSAndy Whitcroft } else { 39902b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 39910a920b5bSAndy Whitcroft } 39920a920b5bSAndy Whitcroft } 39932b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 39942b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 39952b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 39962b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 39972b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 39982b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 39992b474a1aSAndy Whitcroft } 40002b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 40012b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 4002000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 4003000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 40042b474a1aSAndy Whitcroft } 40050a920b5bSAndy Whitcroft 40065150bda4SJoe Eloff# check for global initialisers. 40076d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 4008d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 40096d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 4010d5e616fcSJoe Perches $fix) { 40116d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 4012d5e616fcSJoe Perches } 4013f0a594c1SAndy Whitcroft } 40140a920b5bSAndy Whitcroft# check for static initialisers. 40156d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 4016d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 40176d32f7a3SJoe Perches "do not initialise statics to $1\n" . 4018d5e616fcSJoe Perches $herecurr) && 4019d5e616fcSJoe Perches $fix) { 40206d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 4021d5e616fcSJoe Perches } 40220a920b5bSAndy Whitcroft } 40230a920b5bSAndy Whitcroft 40241813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 40251813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 40261813087dSJoe Perches my $tmp = trim($1); 40271813087dSJoe Perches WARN("MISORDERED_TYPE", 40281813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 40291813087dSJoe Perches } 40301813087dSJoe Perches 4031809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 4032809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 4033809e082eSJoe Perches my $type = trim($1); 4034809e082eSJoe Perches next if ($type !~ /\bint\b/); 4035809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 4036809e082eSJoe Perches my $new_type = $type; 4037809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 4038809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 4039809e082eSJoe Perches $new_type =~ s/^const\s+//; 4040809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 4041809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 4042809e082eSJoe Perches $new_type =~ s/\s+/ /g; 4043809e082eSJoe Perches $new_type = trim($new_type); 4044809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 4045809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 4046809e082eSJoe Perches $fix) { 4047809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 4048809e082eSJoe Perches } 4049809e082eSJoe Perches } 4050809e082eSJoe Perches 4051cb710ecaSJoe Perches# check for static const char * arrays. 4052cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 4053000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4054000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 4055cb710ecaSJoe Perches $herecurr); 4056cb710ecaSJoe Perches } 4057cb710ecaSJoe Perches 405877b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 405977b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 406077b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 406177b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 406277b8c0a8SJoe Perches $fix) { 406377b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 406477b8c0a8SJoe Perches } 406577b8c0a8SJoe Perches } 406677b8c0a8SJoe Perches 4067cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 4068cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 4069000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 4070000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 4071cb710ecaSJoe Perches $herecurr); 4072cb710ecaSJoe Perches } 4073cb710ecaSJoe Perches 4074ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 4075ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 4076ab7e23f3SJoe Perches my $found = $1; 4077ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 4078ab7e23f3SJoe Perches WARN("CONST_CONST", 4079ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 4080ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 4081ab7e23f3SJoe Perches WARN("CONST_CONST", 4082ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 4083ab7e23f3SJoe Perches } 4084ab7e23f3SJoe Perches } 4085ab7e23f3SJoe Perches 40869b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 40879b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 40889b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 40899b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 40909b0fa60dSJoe Perches $herecurr); 40919b0fa60dSJoe Perches } 40929b0fa60dSJoe Perches 4093b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 4094b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 4095b598b670SJoe Perches my $array = $1; 4096b598b670SJoe 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*\))@) { 4097b598b670SJoe Perches my $array_div = $1; 4098b598b670SJoe Perches if (WARN("ARRAY_SIZE", 4099b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 4100b598b670SJoe Perches $fix) { 4101b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4102b598b670SJoe Perches } 4103b598b670SJoe Perches } 4104b598b670SJoe Perches } 4105b598b670SJoe Perches 4106b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 410716b7f3c8SJoe Perches if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { 4108b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4109b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4110b36190c5SJoe Perches $fix) { 4111194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4112b36190c5SJoe Perches } 4113b36190c5SJoe Perches } 4114b36190c5SJoe Perches 4115653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4116653d4876SAndy Whitcroft# make sense. 4117653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 41188054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4119c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 41208ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 412146d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4122000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4123000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 41240a920b5bSAndy Whitcroft } 41250a920b5bSAndy Whitcroft 41260a920b5bSAndy Whitcroft# * goes on variable not on type 412765863862SAndy Whitcroft # (char*[ const]) 4128bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4129bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 41303705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4131d8aaf121SAndy Whitcroft 413265863862SAndy Whitcroft # Should start with a space. 413365863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 413465863862SAndy Whitcroft # Should not end with a space. 413565863862SAndy Whitcroft $to =~ s/\s+$//; 413665863862SAndy Whitcroft # '*'s should not have spaces between. 4137f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 413865863862SAndy Whitcroft } 4139d8aaf121SAndy Whitcroft 41403705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 414165863862SAndy Whitcroft if ($from ne $to) { 41423705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 41433705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 41443705ce5bSJoe Perches $fix) { 41453705ce5bSJoe Perches my $sub_from = $ident; 41463705ce5bSJoe Perches my $sub_to = $ident; 41473705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4148194f66fcSJoe Perches $fixed[$fixlinenr] =~ 41493705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 41503705ce5bSJoe Perches } 415165863862SAndy Whitcroft } 4152bfcb2cc7SAndy Whitcroft } 4153bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4154bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 41553705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4156d8aaf121SAndy Whitcroft 415765863862SAndy Whitcroft # Should start with a space. 415865863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 415965863862SAndy Whitcroft # Should not end with a space. 416065863862SAndy Whitcroft $to =~ s/\s+$//; 416165863862SAndy Whitcroft # '*'s should not have spaces between. 4162f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 416365863862SAndy Whitcroft } 416465863862SAndy Whitcroft # Modifiers should have spaces. 416565863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 416665863862SAndy Whitcroft 41673705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4168667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 41693705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 41703705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 41713705ce5bSJoe Perches $fix) { 41723705ce5bSJoe Perches 41733705ce5bSJoe Perches my $sub_from = $match; 41743705ce5bSJoe Perches my $sub_to = $match; 41753705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4176194f66fcSJoe Perches $fixed[$fixlinenr] =~ 41773705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 41783705ce5bSJoe Perches } 417965863862SAndy Whitcroft } 41800a920b5bSAndy Whitcroft } 41810a920b5bSAndy Whitcroft 41829d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 41839d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 41840675a8fbSJean Delvare my $msg_level = \&WARN; 41850675a8fbSJean Delvare $msg_level = \&CHK if ($file); 41860675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 41879d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 41889d3e3c70SJoe Perches } 41890a920b5bSAndy Whitcroft 41909d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 41918905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4192000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4193000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 41948905a67cSAndy Whitcroft } 41958905a67cSAndy Whitcroft 419617441227SJoe Perches# check for uses of printk_ratelimit 419717441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4198000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4199000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 420017441227SJoe Perches } 420117441227SJoe Perches 4202eeef5733SJoe Perches# printk should use KERN_* levels 4203eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4204000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4205eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 420600df344fSAndy Whitcroft } 42070a920b5bSAndy Whitcroft 4208243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 4209243f3803SJoe Perches my $orig = $1; 4210243f3803SJoe Perches my $level = lc($orig); 4211243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 42128f26b837SJoe Perches my $level2 = $level; 42138f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4214243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4215daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 4216243f3803SJoe Perches } 4217243f3803SJoe Perches 4218dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4219dc139313SJoe Perches my $orig = $1; 4220dc139313SJoe Perches my $level = lc($orig); 4221dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4222dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4223dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4224dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4225dc139313SJoe Perches } 4226dc139313SJoe Perches 422791c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 422891c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 422991c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 423091c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 423191c9afafSAndy Lutomirski WARN("ENOSYS", 423291c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 423391c9afafSAndy Lutomirski } 423491c9afafSAndy Lutomirski 42356b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches. 42366b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. 42376b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected. 42386b9ea5ffSJakub Kicinski if (!$file && $line =~ /\bENOTSUPP\b/) { 42396b9ea5ffSJakub Kicinski if (WARN("ENOTSUPP", 42406b9ea5ffSJakub Kicinski "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && 42416b9ea5ffSJakub Kicinski $fix) { 42426b9ea5ffSJakub Kicinski $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; 42436b9ea5ffSJakub Kicinski } 42446b9ea5ffSJakub Kicinski } 42456b9ea5ffSJakub Kicinski 4246653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4247653d4876SAndy Whitcroft# or if closed on same line 42485b57980dSJoe Perches if ($perl_version_ok && 42492d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 42502d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 42512d453e3bSJoe Perches $sline !~ /}/) { 42528d182478SJoe Perches if (ERROR("OPEN_BRACE", 42532d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 42548d182478SJoe Perches $fix) { 42558d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 42568d182478SJoe Perches my $fixed_line = $rawline; 42578d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 42588d182478SJoe Perches my $line1 = $1; 42598d182478SJoe Perches my $line2 = $2; 42608d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 42618d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 42628d182478SJoe Perches if ($line2 !~ /^\s*$/) { 42638d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 42648d182478SJoe Perches } 42658d182478SJoe Perches } 42660a920b5bSAndy Whitcroft } 4267653d4876SAndy Whitcroft 42688905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 42698905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 42708905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 42718d182478SJoe Perches if (ERROR("OPEN_BRACE", 42728d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 42738d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 42748d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 42758d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 42768d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 42778d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42788d182478SJoe Perches $fixedline = $rawline; 42798d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 42808d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 42818d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 42828d182478SJoe Perches } 42838d182478SJoe Perches } 42848905a67cSAndy Whitcroft } 42858905a67cSAndy Whitcroft 42860c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 42873705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 42883705ce5bSJoe Perches if (WARN("SPACING", 42893705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 42903705ce5bSJoe Perches $fix) { 4291194f66fcSJoe Perches $fixed[$fixlinenr] =~ 42923705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 42933705ce5bSJoe Perches } 42940c73b4ebSAndy Whitcroft } 42950c73b4ebSAndy Whitcroft 429631070b5dSJoe Perches# Function pointer declarations 429731070b5dSJoe Perches# check spacing between type, funcptr, and args 429831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 429991f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 430031070b5dSJoe Perches my $declare = $1; 430131070b5dSJoe Perches my $pre_pointer_space = $2; 430231070b5dSJoe Perches my $post_pointer_space = $3; 430331070b5dSJoe Perches my $funcname = $4; 430431070b5dSJoe Perches my $post_funcname_space = $5; 430531070b5dSJoe Perches my $pre_args_space = $6; 430631070b5dSJoe Perches 430791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 430891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 430991f72e9cSJoe Perches# don't need a space so don't warn for those. 431091f72e9cSJoe Perches my $post_declare_space = ""; 431191f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 431291f72e9cSJoe Perches $post_declare_space = $1; 431391f72e9cSJoe Perches $declare = rtrim($declare); 431491f72e9cSJoe Perches } 431591f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 431631070b5dSJoe Perches WARN("SPACING", 431731070b5dSJoe Perches "missing space after return type\n" . $herecurr); 431891f72e9cSJoe Perches $post_declare_space = " "; 431931070b5dSJoe Perches } 432031070b5dSJoe Perches 432131070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 432291f72e9cSJoe Perches# This test is not currently implemented because these declarations are 432391f72e9cSJoe Perches# equivalent to 432491f72e9cSJoe Perches# int foo(int bar, ...) 432591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 432691f72e9cSJoe Perches# 432791f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 432891f72e9cSJoe Perches# WARN("SPACING", 432991f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 433091f72e9cSJoe Perches# } 433131070b5dSJoe Perches 433231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 433331070b5dSJoe Perches if (defined $pre_pointer_space && 433431070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 433531070b5dSJoe Perches WARN("SPACING", 433631070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 433731070b5dSJoe Perches } 433831070b5dSJoe Perches 433931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 434031070b5dSJoe Perches if (defined $post_pointer_space && 434131070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 434231070b5dSJoe Perches WARN("SPACING", 434331070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 434431070b5dSJoe Perches } 434531070b5dSJoe Perches 434631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 434731070b5dSJoe Perches if (defined $post_funcname_space && 434831070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 434931070b5dSJoe Perches WARN("SPACING", 435031070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 435131070b5dSJoe Perches } 435231070b5dSJoe Perches 435331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 435431070b5dSJoe Perches if (defined $pre_args_space && 435531070b5dSJoe Perches $pre_args_space =~ /^\s/) { 435631070b5dSJoe Perches WARN("SPACING", 435731070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 435831070b5dSJoe Perches } 435931070b5dSJoe Perches 436031070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4361194f66fcSJoe Perches $fixed[$fixlinenr] =~ 436291f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 436331070b5dSJoe Perches } 436431070b5dSJoe Perches } 436531070b5dSJoe Perches 43668d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 43678d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4368fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4369fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 43708d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 43718d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 43728d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4373fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 437438dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 43753705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 43763705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 43773705ce5bSJoe Perches $fix) { 4378194f66fcSJoe Perches $fixed[$fixlinenr] =~ 43793705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 43803705ce5bSJoe Perches } 43818d31cfceSAndy Whitcroft } 43828d31cfceSAndy Whitcroft } 43838d31cfceSAndy Whitcroft 4384f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 43856c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4386c2fdda0dSAndy Whitcroft my $name = $1; 4387773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4388773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4389c2fdda0dSAndy Whitcroft 4390c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4391773647a0SAndy Whitcroft if ($name =~ /^(?: 4392773647a0SAndy Whitcroft if|for|while|switch|return|case| 4393773647a0SAndy Whitcroft volatile|__volatile__| 4394773647a0SAndy Whitcroft __attribute__|format|__extension__| 4395773647a0SAndy Whitcroft asm|__asm__)$/x) 4396773647a0SAndy Whitcroft { 4397c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4398c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4399c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4400c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4401773647a0SAndy Whitcroft 4402773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4403c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4404c2fdda0dSAndy Whitcroft 4405c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4406c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4407773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4408c2fdda0dSAndy Whitcroft 4409c2fdda0dSAndy Whitcroft } else { 44103705ce5bSJoe Perches if (WARN("SPACING", 44113705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 44123705ce5bSJoe Perches $fix) { 4413194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44143705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 44153705ce5bSJoe Perches } 4416f0a594c1SAndy Whitcroft } 44176c72ffaaSAndy Whitcroft } 44189a4cad4eSEric Nelson 4419653d4876SAndy Whitcroft# Check operator spacing. 44200a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 44213705ce5bSJoe Perches my $fixed_line = ""; 44223705ce5bSJoe Perches my $line_fixed = 0; 44233705ce5bSJoe Perches 44249c0ca6f9SAndy Whitcroft my $ops = qr{ 44259c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 44269c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 44279c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 44281f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 442984731623SJoe Perches \?:|\?|: 44309c0ca6f9SAndy Whitcroft }x; 4431cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 44323705ce5bSJoe Perches 44333705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 44343705ce5bSJoe Perches## foreach my $el (@elements) { 44353705ce5bSJoe Perches## print("el: <$el>\n"); 44363705ce5bSJoe Perches## } 44373705ce5bSJoe Perches 44383705ce5bSJoe Perches my @fix_elements = (); 443900df344fSAndy Whitcroft my $off = 0; 44406c72ffaaSAndy Whitcroft 44413705ce5bSJoe Perches foreach my $el (@elements) { 44423705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 44433705ce5bSJoe Perches $off += length($el); 44443705ce5bSJoe Perches } 44453705ce5bSJoe Perches 44463705ce5bSJoe Perches $off = 0; 44473705ce5bSJoe Perches 44486c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4449b34c648bSJoe Perches my $last_after = -1; 44506c72ffaaSAndy Whitcroft 44510a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 44523705ce5bSJoe Perches 44533705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 44543705ce5bSJoe Perches 44553705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 44563705ce5bSJoe Perches 44574a0df2efSAndy Whitcroft $off += length($elements[$n]); 44584a0df2efSAndy Whitcroft 445925985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4460773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4461773647a0SAndy Whitcroft my $cc = ''; 4462773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4463773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4464773647a0SAndy Whitcroft } 4465773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4466773647a0SAndy Whitcroft 44674a0df2efSAndy Whitcroft my $a = ''; 44684a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 44694a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4470cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 44714a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 44724a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4473773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 44744a0df2efSAndy Whitcroft 44750a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 44764a0df2efSAndy Whitcroft 44774a0df2efSAndy Whitcroft my $c = ''; 44780a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 44794a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 44804a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4481cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 44824a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 44834a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 44848b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 44854a0df2efSAndy Whitcroft } else { 44864a0df2efSAndy Whitcroft $c = 'E'; 44870a920b5bSAndy Whitcroft } 44880a920b5bSAndy Whitcroft 44894a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 44904a0df2efSAndy Whitcroft 44914a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 44924a0df2efSAndy Whitcroft 44936c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4494de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 44950a920b5bSAndy Whitcroft 449674048ed8SAndy Whitcroft # Pull out the value of this operator. 44976c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 44980a920b5bSAndy Whitcroft 44991f65f947SAndy Whitcroft # Get the full operator variant. 45001f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 45011f65f947SAndy Whitcroft 450213214adfSAndy Whitcroft # Ignore operators passed as parameters. 450313214adfSAndy Whitcroft if ($op_type ne 'V' && 4504d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 450513214adfSAndy Whitcroft 4506cf655043SAndy Whitcroft# # Ignore comments 4507cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 450813214adfSAndy Whitcroft 4509d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 451013214adfSAndy Whitcroft } elsif ($op eq ';') { 4511cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4512cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 45133705ce5bSJoe Perches if (ERROR("SPACING", 45143705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4515b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 45163705ce5bSJoe Perches $line_fixed = 1; 45173705ce5bSJoe Perches } 4518d8aaf121SAndy Whitcroft } 4519d8aaf121SAndy Whitcroft 4520d8aaf121SAndy Whitcroft # // is a comment 4521d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 45220a920b5bSAndy Whitcroft 4523b00e4814SJoe Perches # : when part of a bitfield 4524b00e4814SJoe Perches } elsif ($opv eq ':B') { 4525b00e4814SJoe Perches # skip the bitfield test for now 4526b00e4814SJoe Perches 45271f65f947SAndy Whitcroft # No spaces for: 45281f65f947SAndy Whitcroft # -> 4529b00e4814SJoe Perches } elsif ($op eq '->') { 45304a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 45313705ce5bSJoe Perches if (ERROR("SPACING", 45323705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4533b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45343705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 45353705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 45363705ce5bSJoe Perches } 4537b34c648bSJoe Perches $line_fixed = 1; 45383705ce5bSJoe Perches } 45390a920b5bSAndy Whitcroft } 45400a920b5bSAndy Whitcroft 45412381097bSJoe Perches # , must not have a space before and must have a space on the right. 45420a920b5bSAndy Whitcroft } elsif ($op eq ',') { 45432381097bSJoe Perches my $rtrim_before = 0; 45442381097bSJoe Perches my $space_after = 0; 45452381097bSJoe Perches if ($ctx =~ /Wx./) { 45462381097bSJoe Perches if (ERROR("SPACING", 45472381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 45482381097bSJoe Perches $line_fixed = 1; 45492381097bSJoe Perches $rtrim_before = 1; 45502381097bSJoe Perches } 45512381097bSJoe Perches } 4552cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 45533705ce5bSJoe Perches if (ERROR("SPACING", 45543705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 45553705ce5bSJoe Perches $line_fixed = 1; 4556b34c648bSJoe Perches $last_after = $n; 45572381097bSJoe Perches $space_after = 1; 45582381097bSJoe Perches } 45592381097bSJoe Perches } 45602381097bSJoe Perches if ($rtrim_before || $space_after) { 45612381097bSJoe Perches if ($rtrim_before) { 45622381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45632381097bSJoe Perches } else { 45642381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 45652381097bSJoe Perches } 45662381097bSJoe Perches if ($space_after) { 45672381097bSJoe Perches $good .= " "; 45683705ce5bSJoe Perches } 45690a920b5bSAndy Whitcroft } 45700a920b5bSAndy Whitcroft 45719c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 457274048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 45739c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 45749c0ca6f9SAndy Whitcroft 45759c0ca6f9SAndy Whitcroft # unary operators should have a space before and 45769c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 45779c0ca6f9SAndy Whitcroft # unary operator, or a cast 45789c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 457974048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 45800d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4581cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 45823705ce5bSJoe Perches if (ERROR("SPACING", 45833705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4584b34c648bSJoe Perches if ($n != $last_after + 2) { 4585b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 45863705ce5bSJoe Perches $line_fixed = 1; 45873705ce5bSJoe Perches } 45880a920b5bSAndy Whitcroft } 4589b34c648bSJoe Perches } 4590a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4591171ae1a4SAndy Whitcroft # A unary '*' may be const 4592171ae1a4SAndy Whitcroft 4593171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 45943705ce5bSJoe Perches if (ERROR("SPACING", 45953705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4596b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 45973705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 45983705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 45993705ce5bSJoe Perches } 4600b34c648bSJoe Perches $line_fixed = 1; 46013705ce5bSJoe Perches } 46020a920b5bSAndy Whitcroft } 46030a920b5bSAndy Whitcroft 46040a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 46050a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4606773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 46073705ce5bSJoe Perches if (ERROR("SPACING", 46083705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4609b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 46103705ce5bSJoe Perches $line_fixed = 1; 46113705ce5bSJoe Perches } 46120a920b5bSAndy Whitcroft } 4613773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4614773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 46153705ce5bSJoe Perches if (ERROR("SPACING", 46163705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4617b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 46183705ce5bSJoe Perches $line_fixed = 1; 46193705ce5bSJoe Perches } 4620653d4876SAndy Whitcroft } 4621773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 46223705ce5bSJoe Perches if (ERROR("SPACING", 46233705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4624b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 46253705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 46263705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4627773647a0SAndy Whitcroft } 4628b34c648bSJoe Perches $line_fixed = 1; 46293705ce5bSJoe Perches } 46303705ce5bSJoe Perches } 46310a920b5bSAndy Whitcroft 46320a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 46339c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 46349c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 46359c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4636c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4637c2fdda0dSAndy Whitcroft $op eq '%') 46380a920b5bSAndy Whitcroft { 4639d2e025f3SJoe Perches if ($check) { 4640d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4641d2e025f3SJoe Perches if (CHK("SPACING", 4642d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4643d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4644d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4645d2e025f3SJoe Perches $line_fixed = 1; 4646d2e025f3SJoe Perches } 4647d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4648d2e025f3SJoe Perches if (CHK("SPACING", 4649d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4650d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4651d2e025f3SJoe Perches $line_fixed = 1; 4652d2e025f3SJoe Perches } 4653d2e025f3SJoe Perches } 4654d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 46553705ce5bSJoe Perches if (ERROR("SPACING", 46563705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4657b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4658b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4659b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4660b34c648bSJoe Perches } 46613705ce5bSJoe Perches $line_fixed = 1; 46623705ce5bSJoe Perches } 46630a920b5bSAndy Whitcroft } 46640a920b5bSAndy Whitcroft 46651f65f947SAndy Whitcroft # A colon needs no spaces before when it is 46661f65f947SAndy Whitcroft # terminating a case value or a label. 46671f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 46681f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 46693705ce5bSJoe Perches if (ERROR("SPACING", 46703705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4671b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 46723705ce5bSJoe Perches $line_fixed = 1; 46733705ce5bSJoe Perches } 46741f65f947SAndy Whitcroft } 46751f65f947SAndy Whitcroft 46760a920b5bSAndy Whitcroft # All the others need spaces both sides. 4677cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 46781f65f947SAndy Whitcroft my $ok = 0; 46791f65f947SAndy Whitcroft 468022f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 46811f65f947SAndy Whitcroft if (($op eq '<' && 46821f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 46831f65f947SAndy Whitcroft ($op eq '>' && 46841f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 46851f65f947SAndy Whitcroft { 46861f65f947SAndy Whitcroft $ok = 1; 46871f65f947SAndy Whitcroft } 46881f65f947SAndy Whitcroft 4689e0df7e1fSJoe Perches # for asm volatile statements 4690e0df7e1fSJoe Perches # ignore a colon with another 4691e0df7e1fSJoe Perches # colon immediately before or after 4692e0df7e1fSJoe Perches if (($op eq ':') && 4693e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4694e0df7e1fSJoe Perches $ok = 1; 4695e0df7e1fSJoe Perches } 4696e0df7e1fSJoe Perches 469784731623SJoe Perches # messages are ERROR, but ?: are CHK 46981f65f947SAndy Whitcroft if ($ok == 0) { 46990675a8fbSJean Delvare my $msg_level = \&ERROR; 47000675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 470184731623SJoe Perches 47020675a8fbSJean Delvare if (&{$msg_level}("SPACING", 47033705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4704b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4705b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4706b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4707b34c648bSJoe Perches } 47083705ce5bSJoe Perches $line_fixed = 1; 47093705ce5bSJoe Perches } 47100a920b5bSAndy Whitcroft } 471122f2a2efSAndy Whitcroft } 47124a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 47133705ce5bSJoe Perches 47143705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 47153705ce5bSJoe Perches 47163705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 47170a920b5bSAndy Whitcroft } 47183705ce5bSJoe Perches 47193705ce5bSJoe Perches if (($#elements % 2) == 0) { 47203705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 47213705ce5bSJoe Perches } 47223705ce5bSJoe Perches 4723194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4724194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 47253705ce5bSJoe Perches } 47263705ce5bSJoe Perches 47273705ce5bSJoe Perches 47280a920b5bSAndy Whitcroft } 47290a920b5bSAndy Whitcroft 4730786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4731d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4732786b6326SJoe Perches if (WARN("SPACING", 4733786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4734786b6326SJoe Perches $fix) { 4735194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4736786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4737786b6326SJoe Perches } 4738786b6326SJoe Perches } 4739786b6326SJoe Perches 4740f0a594c1SAndy Whitcroft# check for multiple assignments 4741f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4742000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4743000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4744f0a594c1SAndy Whitcroft } 4745f0a594c1SAndy Whitcroft 474622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 474722f2a2efSAndy Whitcroft## # continuation. 474822f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 474922f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 475022f2a2efSAndy Whitcroft## 475122f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 475222f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 475322f2a2efSAndy Whitcroft## my $ln = $line; 475422f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 475522f2a2efSAndy Whitcroft## } 475622f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4757000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4758000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 475922f2a2efSAndy Whitcroft## } 476022f2a2efSAndy Whitcroft## } 4761f0a594c1SAndy Whitcroft 47620a920b5bSAndy Whitcroft#need space before brace following if, while, etc 47636b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 47646ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 47653705ce5bSJoe Perches if (ERROR("SPACING", 47663705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 47673705ce5bSJoe Perches $fix) { 47686ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 47693705ce5bSJoe Perches } 4770de7d4f0eSAndy Whitcroft } 4771de7d4f0eSAndy Whitcroft 4772c4a62ef9SJoe Perches## # check for blank lines before declarations 4773c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4774c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4775c4a62ef9SJoe Perches## WARN("SPACING", 4776c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4777c4a62ef9SJoe Perches## } 4778c4a62ef9SJoe Perches## 4779c4a62ef9SJoe Perches 4780de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4781de7d4f0eSAndy Whitcroft# on the line 478294fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 4783d5e616fcSJoe Perches if (ERROR("SPACING", 4784d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4785d5e616fcSJoe Perches $fix) { 4786194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4787d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4788d5e616fcSJoe Perches } 47890a920b5bSAndy Whitcroft } 47900a920b5bSAndy Whitcroft 479122f2a2efSAndy Whitcroft# check spacing on square brackets 479222f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 47933705ce5bSJoe Perches if (ERROR("SPACING", 47943705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 47953705ce5bSJoe Perches $fix) { 4796194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47973705ce5bSJoe Perches s/\[\s+/\[/; 47983705ce5bSJoe Perches } 479922f2a2efSAndy Whitcroft } 480022f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 48013705ce5bSJoe Perches if (ERROR("SPACING", 48023705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 48033705ce5bSJoe Perches $fix) { 4804194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48053705ce5bSJoe Perches s/\s+\]/\]/; 48063705ce5bSJoe Perches } 480722f2a2efSAndy Whitcroft } 480822f2a2efSAndy Whitcroft 4809c45dcabdSAndy Whitcroft# check spacing on parentheses 48109c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 48119c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 48123705ce5bSJoe Perches if (ERROR("SPACING", 48133705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 48143705ce5bSJoe Perches $fix) { 4815194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48163705ce5bSJoe Perches s/\(\s+/\(/; 48173705ce5bSJoe Perches } 481822f2a2efSAndy Whitcroft } 481913214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4820c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4821c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 48223705ce5bSJoe Perches if (ERROR("SPACING", 48233705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 48243705ce5bSJoe Perches $fix) { 4825194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48263705ce5bSJoe Perches s/\s+\)/\)/; 48273705ce5bSJoe Perches } 482822f2a2efSAndy Whitcroft } 482922f2a2efSAndy Whitcroft 4830e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4831e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4832e2826fd0SJoe Perches 4833e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4834ea4acbb1SJoe Perches my $var = $1; 4835ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4836ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4837ea4acbb1SJoe Perches $fix) { 4838ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4839ea4acbb1SJoe Perches } 4840ea4acbb1SJoe Perches } 4841ea4acbb1SJoe Perches 4842ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4843ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4844ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4845ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4846ea4acbb1SJoe Perches my $var = $2; 4847ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4848ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4849ea4acbb1SJoe Perches $fix) { 4850ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4851ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4852ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4853ea4acbb1SJoe Perches } 4854e2826fd0SJoe Perches } 4855e2826fd0SJoe Perches 485663b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 4857a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 4858a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 48595b57980dSJoe Perches $perl_version_ok && defined($stat) && 486063b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 486163b7c73eSJoe Perches my $if_stat = $1; 486263b7c73eSJoe Perches my $test = substr($2, 1, -1); 486363b7c73eSJoe Perches my $herectx; 486463b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 486563b7c73eSJoe Perches my $match = $1; 486663b7c73eSJoe Perches # avoid parentheses around potential macro args 486763b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 486863b7c73eSJoe Perches if (!defined($herectx)) { 486963b7c73eSJoe Perches $herectx = $here . "\n"; 487063b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 487163b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 487263b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 487363b7c73eSJoe Perches $herectx .= $rl . "\n"; 487463b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 487563b7c73eSJoe Perches } 487663b7c73eSJoe Perches } 487763b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 487863b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 487963b7c73eSJoe Perches } 488063b7c73eSJoe Perches } 488163b7c73eSJoe Perches 48820a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 48834a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 48840a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 48853705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 48863705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 48873705ce5bSJoe Perches $fix) { 4888194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48893705ce5bSJoe Perches s/^(.)\s+/$1/; 48903705ce5bSJoe Perches } 48910a920b5bSAndy Whitcroft } 48920a920b5bSAndy Whitcroft 48935b9553abSJoe Perches# return is not a function 4894507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4895c45dcabdSAndy Whitcroft my $spacing = $1; 48965b57980dSJoe Perches if ($perl_version_ok && 48975b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 48985b9553abSJoe Perches my $value = $1; 48995b9553abSJoe Perches $value = deparenthesize($value); 49005b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4901000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4902000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 49035b9553abSJoe Perches } 4904c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4905000d1cc1SJoe Perches ERROR("SPACING", 4906000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4907c45dcabdSAndy Whitcroft } 4908c45dcabdSAndy Whitcroft } 4909507e5141SJoe Perches 4910b43ae21bSJoe Perches# unnecessary return in a void function 4911b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4912b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4913b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4914b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4915b43ae21bSJoe Perches $linenr >= 3 && 4916b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4917b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 49189819cf25SJoe Perches WARN("RETURN_VOID", 4919b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 49209819cf25SJoe Perches } 49219819cf25SJoe Perches 4922189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 49235b57980dSJoe Perches if ($perl_version_ok && 4924189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4925189248d8SJoe Perches my $openparens = $1; 4926189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4927189248d8SJoe Perches my $msg = ""; 4928189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4929189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4930189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4931189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4932189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4933189248d8SJoe Perches } 4934189248d8SJoe Perches } 4935189248d8SJoe Perches 4936c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4937c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4938c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4939c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 49405b57980dSJoe Perches if ($perl_version_ok && 4941c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4942c5595fa2SJoe Perches my $lead = $1; 4943c5595fa2SJoe Perches my $const = $2; 4944c5595fa2SJoe Perches my $comp = $3; 4945c5595fa2SJoe Perches my $to = $4; 4946c5595fa2SJoe Perches my $newcomp = $comp; 4947f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4948c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4949c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4950c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4951c5595fa2SJoe Perches $fix) { 4952c5595fa2SJoe Perches if ($comp eq "<") { 4953c5595fa2SJoe Perches $newcomp = ">"; 4954c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4955c5595fa2SJoe Perches $newcomp = ">="; 4956c5595fa2SJoe Perches } elsif ($comp eq ">") { 4957c5595fa2SJoe Perches $newcomp = "<"; 4958c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4959c5595fa2SJoe Perches $newcomp = "<="; 4960c5595fa2SJoe Perches } 4961c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4962c5595fa2SJoe Perches } 4963c5595fa2SJoe Perches } 4964c5595fa2SJoe Perches 4965f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4966f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 496753a3c448SAndy Whitcroft my $name = $1; 496853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4969000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4970f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 497153a3c448SAndy Whitcroft } 497253a3c448SAndy Whitcroft } 4973c45dcabdSAndy Whitcroft 49740a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 49754a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 49763705ce5bSJoe Perches if (ERROR("SPACING", 49773705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 49783705ce5bSJoe Perches $fix) { 4979194f66fcSJoe Perches $fixed[$fixlinenr] =~ 49803705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 49813705ce5bSJoe Perches } 49820a920b5bSAndy Whitcroft } 49830a920b5bSAndy Whitcroft 4984f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4985f5fe35ddSAndy Whitcroft# statements after the conditional. 4986170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 49873e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 49883e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 49893e469cdcSAndy Whitcroft if (!defined $stat); 4990170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4991170d3a22SAndy Whitcroft $remain_next, $off_next); 4992170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4993170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4994170d3a22SAndy Whitcroft 4995170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4996170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4997170d3a22SAndy Whitcroft # then count those as offsets. 4998170d3a22SAndy Whitcroft my ($whitespace) = 4999170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 5000170d3a22SAndy Whitcroft my $offset = 5001170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 5002170d3a22SAndy Whitcroft 5003170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 5004170d3a22SAndy Whitcroft $offset} = 1; 5005170d3a22SAndy Whitcroft } 5006170d3a22SAndy Whitcroft } 5007170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 5008c11230f4SJoe Perches defined($stat) && defined($cond) && 5009170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 5010171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 50118905a67cSAndy Whitcroft 5012b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 5013000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 5014000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 50158905a67cSAndy Whitcroft } 50168905a67cSAndy Whitcroft 50178905a67cSAndy Whitcroft # Find out what is on the end of the line after the 50188905a67cSAndy Whitcroft # conditional. 5019773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 50208905a67cSAndy Whitcroft $s =~ s/\n.*//g; 502113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 502253210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 502353210168SAndy Whitcroft $c !~ /}\s*while\s*/) 5024773647a0SAndy Whitcroft { 5025bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 5026bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 5027bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 502842bdf74cSHidetoshi Seto my $stat_real = ''; 5029bb44ad39SAndy Whitcroft 503042bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 503142bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 5032bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 5033bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 5034bb44ad39SAndy Whitcroft } 5035bb44ad39SAndy Whitcroft 5036000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5037000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 50388905a67cSAndy Whitcroft } 50398905a67cSAndy Whitcroft } 50408905a67cSAndy Whitcroft 504113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 504213214adfSAndy Whitcroft if ($line =~ / 504313214adfSAndy Whitcroft (?: 504413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 504513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 504613214adfSAndy Whitcroft (?:\&\&|\|\|) 504713214adfSAndy Whitcroft | 504813214adfSAndy Whitcroft (?:\&\&|\|\|) 504913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 505013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 505113214adfSAndy Whitcroft )/x) 505213214adfSAndy Whitcroft { 5053000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 5054000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 505513214adfSAndy Whitcroft } 505613214adfSAndy Whitcroft 50578905a67cSAndy Whitcroft# if and else should not have general statements after it 505813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 505913214adfSAndy Whitcroft my $s = $1; 506013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 506113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 5062000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5063000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 50640a920b5bSAndy Whitcroft } 506513214adfSAndy Whitcroft } 506639667782SAndy Whitcroft# if should not continue a brace 506739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 5068000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5069048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 507039667782SAndy Whitcroft $herecurr); 507139667782SAndy Whitcroft } 5072a1080bf8SAndy Whitcroft# case and default should not have general statements after them 5073a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 5074a1080bf8SAndy Whitcroft $line !~ /\G(?: 50753fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 5076a1080bf8SAndy Whitcroft \s*return\s+ 5077a1080bf8SAndy Whitcroft )/xg) 5078a1080bf8SAndy Whitcroft { 5079000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 5080000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 5081a1080bf8SAndy Whitcroft } 50820a920b5bSAndy Whitcroft 50830a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 50840a920b5bSAndy Whitcroft # indent level to be relevant to each other. 50858b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 50860a920b5bSAndy Whitcroft $previndent == $indent) { 50878b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 50888b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 50898b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 50908b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 50918b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 50928b8856f4SJoe Perches my $fixedline = $prevrawline; 50938b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 50948b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 50958b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 50968b8856f4SJoe Perches } 50978b8856f4SJoe Perches $fixedline = $rawline; 50988b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 50998b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51008b8856f4SJoe Perches } 51010a920b5bSAndy Whitcroft } 51020a920b5bSAndy Whitcroft 51038b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5104c2fdda0dSAndy Whitcroft $previndent == $indent) { 5105c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5106c2fdda0dSAndy Whitcroft 5107c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5108c2fdda0dSAndy Whitcroft # conditional. 5109773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5110c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5111c2fdda0dSAndy Whitcroft 5112c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 51138b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 51148b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 51158b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 51168b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51178b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 51188b8856f4SJoe Perches my $fixedline = $prevrawline; 51198b8856f4SJoe Perches my $trailing = $rawline; 51208b8856f4SJoe Perches $trailing =~ s/^\+//; 51218b8856f4SJoe Perches $trailing = trim($trailing); 51228b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 51238b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51248b8856f4SJoe Perches } 5125c2fdda0dSAndy Whitcroft } 5126c2fdda0dSAndy Whitcroft } 5127c2fdda0dSAndy Whitcroft 512895e2c602SJoe Perches#Specific variable tests 5129323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5130323c1260SJoe Perches my $var = $1; 513195e2c602SJoe Perches 513295e2c602SJoe Perches#CamelCase 5133807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5134be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 513522735ce8SJoe Perches#Ignore Page<foo> variants 5136807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 5137d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB 5138d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) 5139d439e6a5SJoe Perches $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && 5140f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5141f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 51427e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 51437e781f67SJoe Perches my $word = $1; 51447e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5145d8b07710SJoe Perches if ($check) { 5146d8b07710SJoe Perches seed_camelcase_includes(); 5147d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5148d8b07710SJoe Perches seed_camelcase_file($realfile); 5149d8b07710SJoe Perches $camelcase_file_seeded = 1; 5150d8b07710SJoe Perches } 5151d8b07710SJoe Perches } 51527e781f67SJoe Perches if (!defined $camelcase{$word}) { 51537e781f67SJoe Perches $camelcase{$word} = 1; 5154be79794bSJoe Perches CHK("CAMELCASE", 51557e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 51567e781f67SJoe Perches } 5157323c1260SJoe Perches } 5158323c1260SJoe Perches } 51593445686aSJoe Perches } 51600a920b5bSAndy Whitcroft 51610a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5162d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5163d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5164d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5165d5e616fcSJoe Perches $fix) { 5166194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5167d5e616fcSJoe Perches } 51680a920b5bSAndy Whitcroft } 51690a920b5bSAndy Whitcroft 51700e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 51710e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5172c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5173e09dec48SAndy Whitcroft my $file = "$1.h"; 5174e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5175e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5176e09dec48SAndy Whitcroft $realfile ne $checkfile && 51777840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5178c45dcabdSAndy Whitcroft { 51790e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 51800e212e0aSFabian Frederick if ($asminclude > 0) { 5181e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5182000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5183000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5184e09dec48SAndy Whitcroft } else { 5185000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5186000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5187e09dec48SAndy Whitcroft } 51880a920b5bSAndy Whitcroft } 51890a920b5bSAndy Whitcroft } 51900e212e0aSFabian Frederick } 51910a920b5bSAndy Whitcroft 5192653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5193653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5194cf655043SAndy Whitcroft# in a known good container 5195b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5196b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5197d8aaf121SAndy Whitcroft my $ln = $linenr; 5198d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5199c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5200c45dcabdSAndy Whitcroft my $ctx = ''; 520108a2843eSJoe Perches my $has_flow_statement = 0; 520208a2843eSJoe Perches my $has_arg_concat = 0; 5203c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5204f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5205f74bd194SAndy Whitcroft $ctx = $dstat; 5206c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5207a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5208c45dcabdSAndy Whitcroft 520908a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 521062e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 521108a2843eSJoe Perches 5212f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5213f59b64bfSJoe Perches my $define_args = $1; 5214f59b64bfSJoe Perches my $define_stmt = $dstat; 5215f59b64bfSJoe Perches my @def_args = (); 5216f59b64bfSJoe Perches 5217f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5218f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5219f59b64bfSJoe Perches $define_args =~ s/\s*//g; 52208c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5221f59b64bfSJoe Perches @def_args = split(",", $define_args); 5222f59b64bfSJoe Perches } 5223f59b64bfSJoe Perches 5224292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5225c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5226c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5227c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5228c45dcabdSAndy Whitcroft 5229c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 5230bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 5231bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 52326b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 5233bf30d6edSAndy Whitcroft { 5234c45dcabdSAndy Whitcroft } 5235c45dcabdSAndy Whitcroft 5236342d3d2fSAntonio Borneo # Flatten any obvious string concatenation. 523733acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 523833acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5239e45bab8eSAndy Whitcroft { 5240e45bab8eSAndy Whitcroft } 5241e45bab8eSAndy Whitcroft 524242e15293SJoe Perches # Make asm volatile uses seem like a generic function 524342e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 524442e15293SJoe Perches 5245c45dcabdSAndy Whitcroft my $exceptions = qr{ 5246c45dcabdSAndy Whitcroft $Declare| 5247c45dcabdSAndy Whitcroft module_param_named| 5248a0a0a7a9SKees Cook MODULE_PARM_DESC| 5249c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5250c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5251383099fdSAndy Whitcroft __typeof__\(| 525222fd2d3eSStefani Seibold union| 525322fd2d3eSStefani Seibold struct| 5254ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 52556b10df42SVladimir Zapolskiy ^\"|\"$| 52566b10df42SVladimir Zapolskiy ^\[ 5257c45dcabdSAndy Whitcroft }x; 52585eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5259f59b64bfSJoe Perches 5260f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5261f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5262e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5263f59b64bfSJoe Perches 5264f74bd194SAndy Whitcroft if ($dstat ne '' && 5265f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5266f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 52673cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5268356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5269f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5270f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5271e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 527272f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 5273f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5274f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5275f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 52764e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5277f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5278c45dcabdSAndy Whitcroft { 5279e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5280e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5281e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5282e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5283f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5284f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5285f74bd194SAndy Whitcroft } else { 5286000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5287388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5288d8aaf121SAndy Whitcroft } 5289f59b64bfSJoe Perches 5290f59b64bfSJoe Perches } 52915207649bSJoe Perches 52925207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 52935207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 52945207649bSJoe Perches my $first = 1; 52955207649bSJoe Perches $define_stmt = ""; 52965207649bSJoe Perches foreach my $l (@stmt_array) { 52975207649bSJoe Perches $l =~ s/\\$//; 52985207649bSJoe Perches if ($first) { 52995207649bSJoe Perches $define_stmt = $l; 53005207649bSJoe Perches $first = 0; 53015207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 53025207649bSJoe Perches $define_stmt .= substr($l, 1); 53035207649bSJoe Perches } 53045207649bSJoe Perches } 53055207649bSJoe Perches $define_stmt =~ s/$;//g; 53065207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 53075207649bSJoe Perches $define_stmt = trim($define_stmt); 53085207649bSJoe Perches 5309f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5310f59b64bfSJoe Perches foreach my $arg (@def_args) { 5311f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 53129192d41aSJoe Perches next if ($arg =~ /^type$/i); 53137fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 53146dba824eSBrendan Jackman $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 53157fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 53167fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5317d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5318f59b64bfSJoe Perches if ($use_cnt > 1) { 5319f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5320f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5321f59b64bfSJoe Perches } 53229192d41aSJoe Perches# check if any macro arguments may have other precedence issues 53237fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 53249192d41aSJoe Perches ((defined($1) && $1 ne ',') || 53259192d41aSJoe Perches (defined($2) && $2 ne ','))) { 53269192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 53279192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 53289192d41aSJoe Perches } 53290a920b5bSAndy Whitcroft } 53305023d347SJoe Perches 533108a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 533208a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 533308a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 533408a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5335e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 533608a2843eSJoe Perches 533708a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 533808a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 533908a2843eSJoe Perches } 534008a2843eSJoe Perches 5341481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 53425023d347SJoe Perches 53435023d347SJoe Perches } else { 53445023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5345481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5346481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 53475023d347SJoe Perches $line =~ /^\+.*\\$/) { 53485023d347SJoe Perches WARN("LINE_CONTINUATIONS", 53495023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 53505023d347SJoe Perches } 5351653d4876SAndy Whitcroft } 53520a920b5bSAndy Whitcroft 5353b13edf7fSJoe Perches# do {} while (0) macro tests: 5354b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5355b13edf7fSJoe Perches# macro should not end with a semicolon 53565b57980dSJoe Perches if ($perl_version_ok && 5357b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5358b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5359b13edf7fSJoe Perches my $ln = $linenr; 5360b13edf7fSJoe Perches my $cnt = $realcnt; 5361b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5362b13edf7fSJoe Perches my $ctx = ''; 5363b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5364b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5365b13edf7fSJoe Perches $ctx = $dstat; 5366b13edf7fSJoe Perches 5367b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 53681b36b201SJoe Perches $dstat =~ s/$;/ /g; 5369b13edf7fSJoe Perches 5370b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5371b13edf7fSJoe Perches my $stmts = $2; 5372b13edf7fSJoe Perches my $semis = $3; 5373b13edf7fSJoe Perches 5374b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5375b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5376e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5377b13edf7fSJoe Perches 5378ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5379ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5380b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5381b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5382b13edf7fSJoe Perches } 5383b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5384b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5385b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5386b13edf7fSJoe Perches } 5387f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5388f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5389f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5390e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5391f5ef95b1SJoe Perches 5392f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5393f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5394b13edf7fSJoe Perches } 5395b13edf7fSJoe Perches } 5396b13edf7fSJoe Perches 5397f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 539813214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 539913214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5400cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 540113214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5402cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5403cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5404aad4f614SJoe Perches my @allowed = (); 5405aad4f614SJoe Perches my $allow = 0; 540613214adfSAndy Whitcroft my $seen = 0; 5407773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5408cf655043SAndy Whitcroft my $ln = $linenr - 1; 540913214adfSAndy Whitcroft for my $chunk (@chunks) { 541013214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 541113214adfSAndy Whitcroft 5412773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5413773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5414773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5415773647a0SAndy Whitcroft 5416aad4f614SJoe Perches $allowed[$allow] = 0; 5417773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5418773647a0SAndy Whitcroft 5419773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5420773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5421773647a0SAndy Whitcroft 5422773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5423cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5424cf655043SAndy Whitcroft 5425773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 542613214adfSAndy Whitcroft 542713214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 542813214adfSAndy Whitcroft 5429aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5430cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5431cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5432aad4f614SJoe Perches $allowed[$allow] = 1; 543313214adfSAndy Whitcroft } 543413214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5435cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5436aad4f614SJoe Perches $allowed[$allow] = 1; 543713214adfSAndy Whitcroft } 5438cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5439cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5440aad4f614SJoe Perches $allowed[$allow] = 1; 544113214adfSAndy Whitcroft } 5442aad4f614SJoe Perches $allow++; 544313214adfSAndy Whitcroft } 5444aad4f614SJoe Perches if ($seen) { 5445aad4f614SJoe Perches my $sum_allowed = 0; 5446aad4f614SJoe Perches foreach (@allowed) { 5447aad4f614SJoe Perches $sum_allowed += $_; 5448aad4f614SJoe Perches } 5449aad4f614SJoe Perches if ($sum_allowed == 0) { 5450000d1cc1SJoe Perches WARN("BRACES", 5451000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5452aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5453aad4f614SJoe Perches $seen != $allow) { 5454aad4f614SJoe Perches CHK("BRACES", 5455aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5456aad4f614SJoe Perches } 545713214adfSAndy Whitcroft } 545813214adfSAndy Whitcroft } 545913214adfSAndy Whitcroft } 5460773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 546113214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5462cf655043SAndy Whitcroft my $allowed = 0; 5463f0a594c1SAndy Whitcroft 5464cf655043SAndy Whitcroft # Check the pre-context. 5465cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5466cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5467cf655043SAndy Whitcroft $allowed = 1; 5468f0a594c1SAndy Whitcroft } 5469773647a0SAndy Whitcroft 5470773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5471773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5472773647a0SAndy Whitcroft 5473cf655043SAndy Whitcroft # Check the condition. 5474cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5475773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5476cf655043SAndy Whitcroft if (defined $cond) { 5477773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5478cf655043SAndy Whitcroft } 5479cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5480cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5481cf655043SAndy Whitcroft $allowed = 1; 5482cf655043SAndy Whitcroft } 5483cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5484cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5485cf655043SAndy Whitcroft $allowed = 1; 5486cf655043SAndy Whitcroft } 5487cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5488cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5489cf655043SAndy Whitcroft $allowed = 1; 5490cf655043SAndy Whitcroft } 5491cf655043SAndy Whitcroft # Check the post-context. 5492cf655043SAndy Whitcroft if (defined $chunks[1]) { 5493cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5494cf655043SAndy Whitcroft if (defined $cond) { 5495773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5496cf655043SAndy Whitcroft } 5497cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5498cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5499cf655043SAndy Whitcroft $allowed = 1; 5500cf655043SAndy Whitcroft } 5501cf655043SAndy Whitcroft } 5502cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5503f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5504e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5505cf655043SAndy Whitcroft 5506000d1cc1SJoe Perches WARN("BRACES", 5507000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5508f0a594c1SAndy Whitcroft } 5509f0a594c1SAndy Whitcroft } 5510f0a594c1SAndy Whitcroft 5511e4c5babdSJoe Perches# check for single line unbalanced braces 551295330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 551395330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5514e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5515e4c5babdSJoe Perches } 5516e4c5babdSJoe Perches 55170979ae66SJoe Perches# check for unnecessary blank lines around braces 551877b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5519f8e58219SJoe Perches if (CHK("BRACES", 5520f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5521f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5522f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5523f8e58219SJoe Perches } 55240979ae66SJoe Perches } 552577b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5526f8e58219SJoe Perches if (CHK("BRACES", 5527f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5528f8e58219SJoe Perches $fix) { 5529f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5530f8e58219SJoe Perches } 55310979ae66SJoe Perches } 55320979ae66SJoe Perches 55334a0df2efSAndy Whitcroft# no volatiles please 55346c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 55356c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5536000d1cc1SJoe Perches WARN("VOLATILE", 55378c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 55384a0df2efSAndy Whitcroft } 55394a0df2efSAndy Whitcroft 55405e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 55415e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 55425e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 55435e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 554433acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 55455e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 55465e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 55475e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 55485e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 55495e4f6ba5SJoe Perches $fix && 55505e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 55515e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 55525e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 55535e4f6ba5SJoe Perches my $comma_close = ""; 55545e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 55555e4f6ba5SJoe Perches $comma_close = $1; 55565e4f6ba5SJoe Perches } 55575e4f6ba5SJoe Perches 55585e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 55595e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 55605e4f6ba5SJoe Perches my $fixedline = $prevrawline; 55615e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 55625e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 55635e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 55645e4f6ba5SJoe Perches $fixedline = $rawline; 55655e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 55665e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 55675e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 55685e4f6ba5SJoe Perches } 55695e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 55705e4f6ba5SJoe Perches } 55715e4f6ba5SJoe Perches } 55725e4f6ba5SJoe Perches 55735e4f6ba5SJoe Perches# check for missing a space in a string concatenation 55745e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 55755e4f6ba5SJoe Perches WARN('MISSING_SPACE', 55765e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 55775e4f6ba5SJoe Perches } 55785e4f6ba5SJoe Perches 557977cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5580e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5581e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5582e4b7d309SJoe Perches# function declarations 558377cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 558477cb8546SJoe Perches defined($context_function) && 5585e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5586e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 558777cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5588e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 558977cb8546SJoe Perches } 559077cb8546SJoe Perches 55915e4f6ba5SJoe Perches# check for spaces before a quoted newline 55925e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 55935e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 55945e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 55955e4f6ba5SJoe Perches $fix) { 55965e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 55975e4f6ba5SJoe Perches } 55985e4f6ba5SJoe Perches 55995e4f6ba5SJoe Perches } 56005e4f6ba5SJoe Perches 5601f17dba4fSJoe Perches# concatenated string without spaces between elements 560279682c0cSJoe Perches if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { 560379682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 560479682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 560579682c0cSJoe Perches $fix) { 560679682c0cSJoe Perches while ($line =~ /($String)/g) { 560779682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 560879682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 560979682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 561079682c0cSJoe Perches } 561179682c0cSJoe Perches } 5612f17dba4fSJoe Perches } 5613f17dba4fSJoe Perches 561490ad30e5SJoe Perches# uncoalesced string fragments 561533acb54aSJoe Perches if ($line =~ /$String\s*"/) { 561679682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 561779682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 561879682c0cSJoe Perches $fix) { 561979682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 562079682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 562179682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 562279682c0cSJoe Perches } 562379682c0cSJoe Perches } 562490ad30e5SJoe Perches } 562590ad30e5SJoe Perches 5626522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5627522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5628522b837cSAlexey Dobriyan my $show_Z = 1; 56295e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5630522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 56315e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5632522b837cSAlexey Dobriyan # check for %L 5633522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 56345e4f6ba5SJoe Perches WARN("PRINTF_L", 5635522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5636522b837cSAlexey Dobriyan $show_L = 0; 56375e4f6ba5SJoe Perches } 5638522b837cSAlexey Dobriyan # check for %Z 5639522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5640522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5641522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5642522b837cSAlexey Dobriyan $show_Z = 0; 5643522b837cSAlexey Dobriyan } 5644522b837cSAlexey Dobriyan # check for 0x<decimal> 5645522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5646522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 56476e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 56486e300757SJoe Perches } 56495e4f6ba5SJoe Perches } 56505e4f6ba5SJoe Perches 56515e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 56523f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 56535e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 56545e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 56555e4f6ba5SJoe Perches } 56565e4f6ba5SJoe Perches 565700df344fSAndy Whitcroft# warn about #if 0 5658c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 565960f89010SPrakruthi Deepak Heragu WARN("IF_0", 566060f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 566160f89010SPrakruthi Deepak Heragu } 566260f89010SPrakruthi Deepak Heragu 566360f89010SPrakruthi Deepak Heragu# warn about #if 1 566460f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 566560f89010SPrakruthi Deepak Heragu WARN("IF_1", 566660f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 56674a0df2efSAndy Whitcroft } 56684a0df2efSAndy Whitcroft 566903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 567003df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5671100425deSJoe Perches my $tested = quotemeta($1); 5672100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5673100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5674100425deSJoe Perches my $func = $1; 5675100425deSJoe Perches if (WARN('NEEDLESS_IF', 5676100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5677100425deSJoe Perches $fix) { 5678100425deSJoe Perches my $do_fix = 1; 5679100425deSJoe Perches my $leading_tabs = ""; 5680100425deSJoe Perches my $new_leading_tabs = ""; 5681100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5682100425deSJoe Perches $leading_tabs = $1; 5683100425deSJoe Perches } else { 5684100425deSJoe Perches $do_fix = 0; 5685100425deSJoe Perches } 5686100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5687100425deSJoe Perches $new_leading_tabs = $1; 5688100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5689100425deSJoe Perches $do_fix = 0; 5690100425deSJoe Perches } 5691100425deSJoe Perches } else { 5692100425deSJoe Perches $do_fix = 0; 5693100425deSJoe Perches } 5694100425deSJoe Perches if ($do_fix) { 5695100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5696100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5697100425deSJoe Perches } 5698100425deSJoe Perches } 56994c432a8fSGreg Kroah-Hartman } 57004c432a8fSGreg Kroah-Hartman } 5701f0a594c1SAndy Whitcroft 5702ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5703ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5704ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5705ebfdc409SJoe Perches (defined $1 || defined $3) && 5706ebfdc409SJoe Perches $linenr > 3) { 5707ebfdc409SJoe Perches my $testval = $2; 5708ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5709ebfdc409SJoe Perches 5710ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5711ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5712ebfdc409SJoe Perches 5713e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 5714e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 5715ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5716ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5717ebfdc409SJoe Perches } 5718ebfdc409SJoe Perches } 5719ebfdc409SJoe Perches 5720f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5721dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5722f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5723f78d98f6SJoe Perches my $level = $1; 5724f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5725f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5726f78d98f6SJoe Perches $fix) { 5727f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5728f78d98f6SJoe Perches } 5729f78d98f6SJoe Perches } 5730f78d98f6SJoe Perches 573145c55e92SJoe Perches# check for logging continuations 573245c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 573345c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 573445c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 573545c55e92SJoe Perches } 573645c55e92SJoe Perches 5737abb08a53SJoe Perches# check for mask then right shift without a parentheses 57385b57980dSJoe Perches if ($perl_version_ok && 5739abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5740abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5741abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5742abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5743abb08a53SJoe Perches } 5744abb08a53SJoe Perches 5745b75ac618SJoe Perches# check for pointer comparisons to NULL 57465b57980dSJoe Perches if ($perl_version_ok) { 5747b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5748b75ac618SJoe Perches my $val = $1; 5749b75ac618SJoe Perches my $equal = "!"; 5750b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5751b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5752b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5753b75ac618SJoe Perches $fix) { 5754b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5755b75ac618SJoe Perches } 5756b75ac618SJoe Perches } 5757b75ac618SJoe Perches } 5758b75ac618SJoe Perches 57598716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 57608716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 57618716de38SJoe Perches my $attr = $1; 57628716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 57638716de38SJoe Perches my $ptr = $1; 57648716de38SJoe Perches my $var = $2; 57658716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 57668716de38SJoe Perches ERROR("MISPLACED_INIT", 57678716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 57688716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 57698716de38SJoe Perches WARN("MISPLACED_INIT", 57708716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 57718716de38SJoe Perches $fix) { 5772194f66fcSJoe 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; 57738716de38SJoe Perches } 57748716de38SJoe Perches } 57758716de38SJoe Perches } 57768716de38SJoe Perches 5777e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5778e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5779e970b884SJoe Perches my $attr = $1; 5780e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5781e970b884SJoe Perches my $attr_prefix = $1; 5782e970b884SJoe Perches my $attr_type = $2; 5783e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5784e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5785e970b884SJoe Perches $fix) { 5786194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5787e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5788e970b884SJoe Perches } 5789e970b884SJoe Perches } 5790e970b884SJoe Perches 5791e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5792e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5793e970b884SJoe Perches my $attr = $1; 5794e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5795e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5796e970b884SJoe Perches $fix) { 5797194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5798e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5799e970b884SJoe Perches $lead = rtrim($1); 5800e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5801e970b884SJoe Perches $lead = "${lead}const "; 5802194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5803e970b884SJoe Perches } 5804e970b884SJoe Perches } 5805e970b884SJoe Perches 5806c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5807c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5808c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5809c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5810c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5811c17893c7SJoe Perches $fix) { 5812c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5813c17893c7SJoe Perches } 5814c17893c7SJoe Perches } 5815c17893c7SJoe Perches 5816fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5817fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5818fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5819fbdb8138SJoe Perches my $constant_func = $1; 5820fbdb8138SJoe Perches my $func = $constant_func; 5821fbdb8138SJoe Perches $func =~ s/^__constant_//; 5822fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5823fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5824fbdb8138SJoe Perches $fix) { 5825194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5826fbdb8138SJoe Perches } 5827fbdb8138SJoe Perches } 5828fbdb8138SJoe Perches 58291a15a250SPatrick Pannuto# prefer usleep_range over udelay 583037581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 583143c1d77cSJoe Perches my $delay = $1; 58321a15a250SPatrick Pannuto # ignore udelay's < 10, however 583343c1d77cSJoe Perches if (! ($delay < 10) ) { 5834000d1cc1SJoe Perches CHK("USLEEP_RANGE", 5835458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 583643c1d77cSJoe Perches } 583743c1d77cSJoe Perches if ($delay > 2000) { 583843c1d77cSJoe Perches WARN("LONG_UDELAY", 583943c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 58401a15a250SPatrick Pannuto } 58411a15a250SPatrick Pannuto } 58421a15a250SPatrick Pannuto 584309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 584409ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 584509ef8725SPatrick Pannuto if ($1 < 20) { 5846000d1cc1SJoe Perches WARN("MSLEEP", 5847458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 584809ef8725SPatrick Pannuto } 584909ef8725SPatrick Pannuto } 585009ef8725SPatrick Pannuto 585136ec1939SJoe Perches# check for comparisons of jiffies 585236ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 585336ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 585436ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 585536ec1939SJoe Perches } 585636ec1939SJoe Perches 58579d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 58589d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 58599d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 58609d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 58619d7a34a5SJoe Perches } 58629d7a34a5SJoe Perches 586300df344fSAndy Whitcroft# warn about #ifdefs in C files 5864c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 586500df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 586600df344fSAndy Whitcroft# print "$herecurr"; 586700df344fSAndy Whitcroft# $clean = 0; 586800df344fSAndy Whitcroft# } 586900df344fSAndy Whitcroft 587022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5871c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 58723705ce5bSJoe Perches if (ERROR("SPACING", 58733705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 58743705ce5bSJoe Perches $fix) { 5875194f66fcSJoe Perches $fixed[$fixlinenr] =~ 58763705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 58773705ce5bSJoe Perches } 58783705ce5bSJoe Perches 587922f2a2efSAndy Whitcroft } 588022f2a2efSAndy Whitcroft 58814a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5882171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5883171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 58844a0df2efSAndy Whitcroft my $which = $1; 58854a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5886000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5887000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 58884a0df2efSAndy Whitcroft } 58894a0df2efSAndy Whitcroft } 58904a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5891402c2553SMichael S. Tsirkin 5892402c2553SMichael S. Tsirkin my $barriers = qr{ 5893402c2553SMichael S. Tsirkin mb| 5894402c2553SMichael S. Tsirkin rmb| 5895402c2553SMichael S. Tsirkin wmb| 5896402c2553SMichael S. Tsirkin read_barrier_depends 5897402c2553SMichael S. Tsirkin }x; 5898402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5899402c2553SMichael S. Tsirkin mb__before_atomic| 5900402c2553SMichael S. Tsirkin mb__after_atomic| 5901402c2553SMichael S. Tsirkin store_release| 5902402c2553SMichael S. Tsirkin load_acquire| 5903402c2553SMichael S. Tsirkin store_mb| 5904402c2553SMichael S. Tsirkin (?:$barriers) 5905402c2553SMichael S. Tsirkin }x; 5906402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5907402c2553SMichael S. Tsirkin (?:$barriers)| 590843e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 590943e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5910402c2553SMichael S. Tsirkin }x; 5911402c2553SMichael S. Tsirkin 5912402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 59134a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5914c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5915000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 59164a0df2efSAndy Whitcroft } 59174a0df2efSAndy Whitcroft } 59183ad81779SPaul E. McKenney 5919f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5920f4073b0fSMichael S. Tsirkin 5921f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5922f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5923f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5924f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5925f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5926f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5927f4073b0fSMichael S. Tsirkin } 5928f4073b0fSMichael S. Tsirkin 5929cb426e99SJoe Perches# check for waitqueue_active without a comment. 5930cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5931cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5932cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5933cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5934cb426e99SJoe Perches } 5935cb426e99SJoe Perches } 59363ad81779SPaul E. McKenney 593791db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends 593891db2592SPaul E. McKenney if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { 593991db2592SPaul E. McKenney WARN("READ_BARRIER_DEPENDS", 594091db2592SPaul E. McKenney "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); 594191db2592SPaul E. McKenney } 594291db2592SPaul E. McKenney 59434a0df2efSAndy Whitcroft# check of hardware specific defines 5944c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5945000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5946000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 59470a920b5bSAndy Whitcroft } 5948653d4876SAndy Whitcroft 5949596ed45bSJoe Perches# check that the storage class is not after a type 5950596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 5951000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5952596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 5953596ed45bSJoe Perches } 5954596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 5955596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 5956596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 5957596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 5958596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 5959596ed45bSJoe Perches WARN("STORAGE_CLASS", 5960596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 5961d4977c78STobias Klauser } 5962d4977c78STobias Klauser 5963de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5964de7d4f0eSAndy Whitcroft# storage class and type. 59659c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 59669c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5967000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5968000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5969de7d4f0eSAndy Whitcroft } 5970de7d4f0eSAndy Whitcroft 59718905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 59722b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59732b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5974d5e616fcSJoe Perches if (WARN("INLINE", 5975d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5976d5e616fcSJoe Perches $fix) { 5977194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5978d5e616fcSJoe Perches 5979d5e616fcSJoe Perches } 59808905a67cSAndy Whitcroft } 59818905a67cSAndy Whitcroft 59823d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 59832b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59842b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5985000d1cc1SJoe Perches WARN("PREFER_PACKED", 5986000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 59873d130fd0SJoe Perches } 59883d130fd0SJoe Perches 598939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 59902b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59912b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5992000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5993000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 599439b7e287SJoe Perches } 599539b7e287SJoe Perches 5996462811d9SJoe Perches# Check for __attribute__ section, prefer __section 5997462811d9SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5998462811d9SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { 5999462811d9SJoe Perches my $old = substr($rawline, $-[1], $+[1] - $-[1]); 6000462811d9SJoe Perches my $new = substr($old, 1, -1); 6001462811d9SJoe Perches if (WARN("PREFER_SECTION", 6002462811d9SJoe Perches "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && 6003462811d9SJoe Perches $fix) { 6004462811d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; 6005462811d9SJoe Perches } 6006462811d9SJoe Perches } 6007462811d9SJoe Perches 60085f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 60092b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 60102b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 6011d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 6012d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 6013d5e616fcSJoe Perches $fix) { 6014194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 6015d5e616fcSJoe Perches 6016d5e616fcSJoe Perches } 60175f14d3bdSJoe Perches } 60185f14d3bdSJoe Perches 60196061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 60202b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 60212b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 6022d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 6023d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 6024d5e616fcSJoe Perches $fix) { 6025194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 6026d5e616fcSJoe Perches } 60276061d949SJoe Perches } 60286061d949SJoe Perches 6029619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 60305b57980dSJoe Perches if ($perl_version_ok && 6031619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 6032619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 6033619a908aSJoe Perches $line =~ /\b__weak\b/)) { 6034619a908aSJoe Perches ERROR("WEAK_DECLARATION", 6035619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 6036619a908aSJoe Perches } 6037619a908aSJoe Perches 6038fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 6039e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 6040fd39f904STomas Winkler $realfile !~ m@\btools/@ && 6041e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 6042e6176fa4SJoe Perches my $type = $1; 6043e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 6044e6176fa4SJoe Perches $type = $1; 6045e6176fa4SJoe Perches my $kernel_type = 'u'; 6046e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 6047e6176fa4SJoe Perches $type =~ /(\d+)/; 6048e6176fa4SJoe Perches $kernel_type .= $1; 6049e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 6050e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 6051e6176fa4SJoe Perches $fix) { 6052e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 6053e6176fa4SJoe Perches } 6054e6176fa4SJoe Perches } 6055e6176fa4SJoe Perches } 6056e6176fa4SJoe Perches 6057938224b5SJoe Perches# check for cast of C90 native int or longer types constants 6058938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 6059938224b5SJoe Perches my $cast = $1; 6060938224b5SJoe Perches my $const = $2; 6061938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 6062938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 6063938224b5SJoe Perches $fix) { 6064938224b5SJoe Perches my $suffix = ""; 6065938224b5SJoe Perches my $newconst = $const; 6066938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 6067938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 6068938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 6069938224b5SJoe Perches $suffix .= 'LL'; 6070938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 6071938224b5SJoe Perches $suffix .= 'L'; 6072938224b5SJoe Perches } 6073938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 6074938224b5SJoe Perches } 6075938224b5SJoe Perches } 6076938224b5SJoe Perches 60778f53a9b8SJoe Perches# check for sizeof(&) 60788f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 6079000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 6080000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 60818f53a9b8SJoe Perches } 60828f53a9b8SJoe Perches 608366c80b60SJoe Perches# check for sizeof without parenthesis 608466c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 6085d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 6086d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 6087d5e616fcSJoe Perches $fix) { 6088194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 6089d5e616fcSJoe Perches } 609066c80b60SJoe Perches } 609166c80b60SJoe Perches 609288982feaSJoe Perches# check for struct spinlock declarations 609388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 609488982feaSJoe Perches WARN("USE_SPINLOCK_T", 609588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 609688982feaSJoe Perches } 609788982feaSJoe Perches 6098a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 609906668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 6100a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 6101caac1d5fSHeba Aamer $fmt =~ s/%%//g; 6102caac1d5fSHeba Aamer if ($fmt !~ /%/) { 6103d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 6104d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6105d5e616fcSJoe Perches $fix) { 6106194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6107d5e616fcSJoe Perches } 6108a6962d72SJoe Perches } 6109a6962d72SJoe Perches } 6110a6962d72SJoe Perches 61110b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 61125b57980dSJoe Perches if ($perl_version_ok && 61130b523769SJoe Perches defined $stat && 61140b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 61150b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6116e3c6bc95STobin C. Harding my $stat_real; 6117e3c6bc95STobin C. Harding 61180b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 61190b523769SJoe Perches $lc = $lc + $linenr; 61200b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6121ffe07513SJoe Perches my $specifier; 6122ffe07513SJoe Perches my $extension; 61233bd32d6aSSakari Ailus my $qualifier; 6124ffe07513SJoe Perches my $bad_specifier = ""; 61250b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 61260b523769SJoe Perches $fmt =~ s/%%//g; 6127e3c6bc95STobin C. Harding 61283bd32d6aSSakari Ailus while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { 6129e3c6bc95STobin C. Harding $specifier = $1; 6130e3c6bc95STobin C. Harding $extension = $2; 61313bd32d6aSSakari Ailus $qualifier = $3; 6132361b0d28SLinus Torvalds if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ || 61333bd32d6aSSakari Ailus ($extension eq "f" && 61343bd32d6aSSakari Ailus defined $qualifier && $qualifier !~ /^w/)) { 6135e3c6bc95STobin C. Harding $bad_specifier = $specifier; 61360b523769SJoe Perches last; 61370b523769SJoe Perches } 6138e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6139e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6140e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 61410b523769SJoe Perches } 6142e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6143e3c6bc95STobin 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"); 6144e3c6bc95STobin C. Harding } 6145e3c6bc95STobin C. Harding } 6146e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 61472a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 61481df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 61491df7338aSSergey Senozhatsky my $use = ""; 6150e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 61511df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6152e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 61531df7338aSSergey Senozhatsky } 61542a9f9d85STobin C. Harding 61550b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6156e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6157e3c6bc95STobin C. Harding } 61580b523769SJoe Perches } 61590b523769SJoe Perches } 61600b523769SJoe Perches 6161554e165cSAndy Whitcroft# Check for misused memsets 61625b57980dSJoe Perches if ($perl_version_ok && 6163d1fe9c09SJoe Perches defined $stat && 61649e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6165554e165cSAndy Whitcroft 6166d7c76ba7SJoe Perches my $ms_addr = $2; 6167d1fe9c09SJoe Perches my $ms_val = $7; 6168d1fe9c09SJoe Perches my $ms_size = $12; 6169d7c76ba7SJoe Perches 6170554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6171554e165cSAndy Whitcroft ERROR("MEMSET", 6172d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6173554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6174554e165cSAndy Whitcroft WARN("MEMSET", 6175d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6176d7c76ba7SJoe Perches } 6177d7c76ba7SJoe Perches } 6178d7c76ba7SJoe Perches 617998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 61805b57980dSJoe Perches# if ($perl_version_ok && 6181f333195dSJoe Perches# defined $stat && 6182f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6183f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6184f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6185f333195dSJoe Perches# $fix) { 6186f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6187f333195dSJoe Perches# } 6188f333195dSJoe Perches# } 618998a9bba5SJoe Perches 6190b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 61915b57980dSJoe Perches# if ($perl_version_ok && 6192f333195dSJoe Perches# defined $stat && 6193f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6194f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6195f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6196f333195dSJoe Perches# } 6197b6117d17SMateusz Kulikowski 61988617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 61998617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 62005b57980dSJoe Perches# if ($perl_version_ok && 6201f333195dSJoe Perches# defined $stat && 6202f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6203f333195dSJoe Perches# 6204f333195dSJoe Perches# my $ms_val = $7; 6205f333195dSJoe Perches# 6206f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6207f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6208f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6209f333195dSJoe Perches# $fix) { 6210f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6211f333195dSJoe Perches# } 6212f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6213f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6214f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6215f333195dSJoe Perches# $fix) { 6216f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6217f333195dSJoe Perches# } 6218f333195dSJoe Perches# } 6219f333195dSJoe Perches# } 62208617cd09SMateusz Kulikowski 6221d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 62225b57980dSJoe Perches if ($perl_version_ok && 6223d1fe9c09SJoe Perches defined $stat && 6224d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6225d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6226d7c76ba7SJoe Perches my $call = $1; 6227d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6228d7c76ba7SJoe Perches my $arg1 = $3; 6229d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6230d1fe9c09SJoe Perches my $arg2 = $8; 6231d7c76ba7SJoe Perches my $cast; 6232d7c76ba7SJoe Perches 6233d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6234d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6235d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6236d7c76ba7SJoe Perches $cast = $cast1; 6237d7c76ba7SJoe Perches } else { 6238d7c76ba7SJoe Perches $cast = $cast2; 6239d7c76ba7SJoe Perches } 6240d7c76ba7SJoe Perches WARN("MINMAX", 6241d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6242554e165cSAndy Whitcroft } 6243554e165cSAndy Whitcroft } 6244554e165cSAndy Whitcroft 62454a273195SJoe Perches# check usleep_range arguments 62465b57980dSJoe Perches if ($perl_version_ok && 62474a273195SJoe Perches defined $stat && 62484a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 62494a273195SJoe Perches my $min = $1; 62504a273195SJoe Perches my $max = $7; 62514a273195SJoe Perches if ($min eq $max) { 62524a273195SJoe Perches WARN("USLEEP_RANGE", 6253458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 62544a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 62554a273195SJoe Perches $min > $max) { 62564a273195SJoe Perches WARN("USLEEP_RANGE", 6257458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 62584a273195SJoe Perches } 62594a273195SJoe Perches } 62604a273195SJoe Perches 6261823b794cSJoe Perches# check for naked sscanf 62625b57980dSJoe Perches if ($perl_version_ok && 6263823b794cSJoe Perches defined $stat && 62646c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6265823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6266823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6267823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6268823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6269823b794cSJoe Perches $lc = $lc + $linenr; 62702a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6271823b794cSJoe Perches WARN("NAKED_SSCANF", 6272823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6273823b794cSJoe Perches } 6274823b794cSJoe Perches 6275afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 62765b57980dSJoe Perches if ($perl_version_ok && 6277afc819abSJoe Perches defined $stat && 6278afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6279afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6280afc819abSJoe Perches $lc = $lc + $linenr; 62812a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6282afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6283afc819abSJoe Perches my $format = $6; 6284afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6285afc819abSJoe Perches if ($count == 1 && 6286afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6287afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6288afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6289afc819abSJoe Perches } 6290afc819abSJoe Perches } 6291afc819abSJoe Perches } 6292afc819abSJoe Perches 629370dc8a48SJoe Perches# check for new externs in .h files. 629470dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 629570dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6296d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 629770dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 629870dc8a48SJoe Perches $fix) { 6299194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 630070dc8a48SJoe Perches } 630170dc8a48SJoe Perches } 630270dc8a48SJoe Perches 6303de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6304171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6305c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6306171ae1a4SAndy Whitcroft { 6307c45dcabdSAndy Whitcroft my $function_name = $1; 6308c45dcabdSAndy Whitcroft my $paren_space = $2; 6309171ae1a4SAndy Whitcroft 6310171ae1a4SAndy Whitcroft my $s = $stat; 6311171ae1a4SAndy Whitcroft if (defined $cond) { 6312171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6313171ae1a4SAndy Whitcroft } 6314c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 6315c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 6316c45dcabdSAndy Whitcroft { 6317000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6318000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6319de7d4f0eSAndy Whitcroft } 6320de7d4f0eSAndy Whitcroft 6321171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6322000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6323000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6324171ae1a4SAndy Whitcroft } 63259c9ba34eSAndy Whitcroft 63269c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 63279c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 63289c9ba34eSAndy Whitcroft { 6329000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6330000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6331171ae1a4SAndy Whitcroft } 6332171ae1a4SAndy Whitcroft 6333a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 633416b7f3c8SJoe Perches# while avoiding uninitialized_var(x) 6335a0ad7596SJoe Perches if (defined $stat && 633616b7f3c8SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 633716b7f3c8SJoe Perches (!defined($1) || 633816b7f3c8SJoe Perches (defined($1) && $1 ne "uninitialized_var")) && 633916b7f3c8SJoe Perches $2 ne "void") { 634016b7f3c8SJoe Perches my $args = trim($2); 6341ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6342ca0d8929SJoe Perches my $arg = trim($1); 634316b7f3c8SJoe Perches if ($arg =~ /^$Type$/ && 634416b7f3c8SJoe Perches $arg !~ /enum\s+$Ident$/) { 6345ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6346ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6347ca0d8929SJoe Perches } 6348ca0d8929SJoe Perches } 6349ca0d8929SJoe Perches } 6350ca0d8929SJoe Perches 6351a0ad7596SJoe Perches# check for function definitions 63525b57980dSJoe Perches if ($perl_version_ok && 6353a0ad7596SJoe Perches defined $stat && 6354a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6355a0ad7596SJoe Perches $context_function = $1; 6356a0ad7596SJoe Perches 6357a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6358a0ad7596SJoe Perches my $ok = 0; 6359a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6360a0ad7596SJoe Perches my $herectx = $here . "\n"; 6361a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6362a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6363a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6364a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6365a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6366a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6367a0ad7596SJoe Perches } 6368a0ad7596SJoe Perches if (!$ok) { 6369a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6370a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6371a0ad7596SJoe Perches } 6372a0ad7596SJoe Perches } 6373a0ad7596SJoe Perches 6374de7d4f0eSAndy Whitcroft# checks for new __setup's 6375de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6376de7d4f0eSAndy Whitcroft my $name = $1; 6377de7d4f0eSAndy Whitcroft 6378de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6379000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 63808c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 6381de7d4f0eSAndy Whitcroft } 6382653d4876SAndy Whitcroft } 63839c0ca6f9SAndy Whitcroft 6384e29a70f1SJoe Perches# check for pointless casting of alloc functions 6385e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6386000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6387000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 63889c0ca6f9SAndy Whitcroft } 638913214adfSAndy Whitcroft 6390a640d25cSJoe Perches# alloc style 6391a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 63925b57980dSJoe Perches if ($perl_version_ok && 6393e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6394a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6395a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6396a640d25cSJoe Perches } 6397a640d25cSJoe Perches 639860a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 63995b57980dSJoe Perches if ($perl_version_ok && 64001b4a2ed4SJoe Perches defined $stat && 64011b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 640260a55369SJoe Perches my $oldfunc = $3; 640360a55369SJoe Perches my $a1 = $4; 640460a55369SJoe Perches my $a2 = $10; 640560a55369SJoe Perches my $newfunc = "kmalloc_array"; 640660a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 640760a55369SJoe Perches my $r1 = $a1; 640860a55369SJoe Perches my $r2 = $a2; 640960a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 641060a55369SJoe Perches $r1 = $a2; 641160a55369SJoe Perches $r2 = $a1; 641260a55369SJoe Perches } 6413e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6414e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 64151b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 6416e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6417e3d95a2aSTobin C. Harding 6418e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 64191b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 64201b4a2ed4SJoe Perches $cnt == 1 && 6421e367455aSJoe Perches $fix) { 6422194f66fcSJoe 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; 642360a55369SJoe Perches } 642460a55369SJoe Perches } 642560a55369SJoe Perches } 642660a55369SJoe Perches 6427972fdea2SJoe Perches# check for krealloc arg reuse 64285b57980dSJoe Perches if ($perl_version_ok && 64294cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 64304cab63ceSJoe Perches $1 eq $3) { 6431972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 6432972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6433972fdea2SJoe Perches } 6434972fdea2SJoe Perches 64355ce59ae0SJoe Perches# check for alloc argument mismatch 64365ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 64375ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 64385ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 64395ce59ae0SJoe Perches } 64405ce59ae0SJoe Perches 6441caf2a54fSJoe Perches# check for multiple semicolons 6442caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6443d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6444d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6445d5e616fcSJoe Perches $fix) { 6446194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6447d5e616fcSJoe Perches } 6448d1e2ad07SJoe Perches } 6449d1e2ad07SJoe Perches 6450cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6451cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6452cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 64530ab90191SJoe Perches my $ull = ""; 64540ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 64550ab90191SJoe Perches if (CHK("BIT_MACRO", 64560ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 64570ab90191SJoe Perches $fix) { 64580ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 64590ab90191SJoe Perches } 64600ab90191SJoe Perches } 64610ab90191SJoe Perches 64622d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 64632d632745SJoe 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*$/) { 64642d632745SJoe Perches my $config = $1; 64652d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 64662d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 64672d632745SJoe Perches $fix) { 64682d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 64692d632745SJoe Perches } 64702d632745SJoe Perches } 64712d632745SJoe Perches 6472e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6473c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6474c34c09a8SJoe Perches my $has_break = 0; 6475c34c09a8SJoe Perches my $has_statement = 0; 6476c34c09a8SJoe Perches my $count = 0; 6477c34c09a8SJoe Perches my $prevline = $linenr; 6478e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6479c34c09a8SJoe Perches $prevline--; 6480c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6481c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6482c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6483c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6484c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6485c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6486c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6487c34c09a8SJoe Perches $has_statement = 1; 6488c34c09a8SJoe Perches $count++; 6489258f79d5SHeinrich Schuchardt $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); 6490c34c09a8SJoe Perches } 6491c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6492c34c09a8SJoe Perches WARN("MISSING_BREAK", 6493224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6494c34c09a8SJoe Perches } 6495c34c09a8SJoe Perches } 6496c34c09a8SJoe Perches 6497f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough; 6498f36d3eb8SJoe Perches my @fallthroughs = ( 6499f36d3eb8SJoe Perches 'fallthrough', 6500f36d3eb8SJoe Perches '@fallthrough@', 6501f36d3eb8SJoe Perches 'lint -fallthrough[ \t]*', 6502f36d3eb8SJoe Perches 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', 6503f36d3eb8SJoe Perches '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', 6504f36d3eb8SJoe Perches 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6505f36d3eb8SJoe Perches 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', 6506f36d3eb8SJoe Perches ); 6507f36d3eb8SJoe Perches if ($raw_comment ne '') { 6508f36d3eb8SJoe Perches foreach my $ft (@fallthroughs) { 6509f36d3eb8SJoe Perches if ($raw_comment =~ /$ft/) { 6510f36d3eb8SJoe Perches my $msg_level = \&WARN; 6511f36d3eb8SJoe Perches $msg_level = \&CHK if ($file); 6512f36d3eb8SJoe Perches &{$msg_level}("PREFER_FALLTHROUGH", 6513f36d3eb8SJoe Perches "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); 6514f36d3eb8SJoe Perches last; 6515f36d3eb8SJoe Perches } 6516f36d3eb8SJoe Perches } 6517f36d3eb8SJoe Perches } 6518f36d3eb8SJoe Perches 6519d1e2ad07SJoe Perches# check for switch/default statements without a break; 65205b57980dSJoe Perches if ($perl_version_ok && 6521d1e2ad07SJoe Perches defined $stat && 6522d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6523d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6524e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6525e3d95a2aSTobin C. Harding 6526d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6527d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6528caf2a54fSJoe Perches } 6529caf2a54fSJoe Perches 653013214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6531d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6532d5e616fcSJoe Perches if (WARN("USE_FUNC", 6533d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6534d5e616fcSJoe Perches $fix) { 6535194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6536d5e616fcSJoe Perches } 653713214adfSAndy Whitcroft } 6538773647a0SAndy Whitcroft 653962ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 654062ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 654162ec818fSJoe Perches ERROR("DATE_TIME", 654262ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 654362ec818fSJoe Perches } 654462ec818fSJoe Perches 65452c92488aSJoe Perches# check for use of yield() 65462c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 65472c92488aSJoe Perches WARN("YIELD", 65482c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 65492c92488aSJoe Perches } 65502c92488aSJoe Perches 6551179f8f40SJoe Perches# check for comparisons against true and false 6552179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6553179f8f40SJoe Perches my $lead = $1; 6554179f8f40SJoe Perches my $arg = $2; 6555179f8f40SJoe Perches my $test = $3; 6556179f8f40SJoe Perches my $otype = $4; 6557179f8f40SJoe Perches my $trail = $5; 6558179f8f40SJoe Perches my $op = "!"; 6559179f8f40SJoe Perches 6560179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6561179f8f40SJoe Perches 6562179f8f40SJoe Perches my $type = lc($otype); 6563179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6564179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6565179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6566179f8f40SJoe Perches $op = ""; 6567179f8f40SJoe Perches } 6568179f8f40SJoe Perches 6569179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6570179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6571179f8f40SJoe Perches 6572179f8f40SJoe Perches## maybe suggesting a correct construct would better 6573179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6574179f8f40SJoe Perches 6575179f8f40SJoe Perches } 6576179f8f40SJoe Perches } 6577179f8f40SJoe Perches 65784882720bSThomas Gleixner# check for semaphores initialized locked 65794882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6580000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6581000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6582773647a0SAndy Whitcroft } 65836712d858SJoe Perches 658467d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 658567d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6586000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 658767d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6588773647a0SAndy Whitcroft } 65896712d858SJoe Perches 6590ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6591f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6592000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6593ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6594f3db6639SMichael Ellerman } 65956712d858SJoe Perches 65963d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 65973d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 65983d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 65993d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 66003d709ab5SPaul E. McKenney } 66013d709ab5SPaul E. McKenney 66029189c7e7SJoe Perches# check for deprecated apis 66039189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 66049189c7e7SJoe Perches my $deprecated_api = $1; 66059189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 66069189c7e7SJoe Perches WARN("DEPRECATED_API", 66079189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 66089189c7e7SJoe Perches } 66099189c7e7SJoe Perches 66100f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6611d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 66126903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6613d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6614000d1cc1SJoe Perches WARN("CONST_STRUCT", 6615d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 66162b6db5cbSAndy Whitcroft } 6617773647a0SAndy Whitcroft 6618773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6619773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6620773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6621c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6622c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6623171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6624171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6625171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6626773647a0SAndy Whitcroft { 6627000d1cc1SJoe Perches WARN("NR_CPUS", 6628000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6629773647a0SAndy Whitcroft } 66309c9ba34eSAndy Whitcroft 663152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 663252ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 663352ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 663452ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 663552ea8506SJoe Perches } 663652ea8506SJoe Perches 6637acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 66385b57980dSJoe Perches if ($perl_version_ok && 6639acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6640acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6641acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6642acd9362cSJoe Perches } 6643acd9362cSJoe Perches 6644de3f186fSDenis Efremov# nested likely/unlikely calls 6645de3f186fSDenis Efremov if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { 6646de3f186fSDenis Efremov WARN("LIKELY_MISUSE", 6647de3f186fSDenis Efremov "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); 6648de3f186fSDenis Efremov } 6649de3f186fSDenis Efremov 6650691d77b6SAndy Whitcroft# whine mightly about in_atomic 6651691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6652691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6653000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6654000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6655f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6656000d1cc1SJoe Perches WARN("IN_ATOMIC", 6657000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6658691d77b6SAndy Whitcroft } 6659691d77b6SAndy Whitcroft } 66601704f47bSPeter Zijlstra 66610f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 66620f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 66630f5225b0SPeter Zijlstra ERROR("LOCKING", 66640f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 66650f5225b0SPeter Zijlstra } 66660f5225b0SPeter Zijlstra 66671704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 66681704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 66691704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 66701704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 66711704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 66721704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6673000d1cc1SJoe Perches ERROR("LOCKDEP", 6674000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 66751704f47bSPeter Zijlstra } 66761704f47bSPeter Zijlstra } 667788f8831cSDave Jones 6678b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6679b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6680000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6681000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 668288f8831cSDave Jones } 66832435880fSJoe Perches 668400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 668500180468SJoe Perches# and whether or not function naming is typical and if 668600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 66875b57980dSJoe Perches if ($perl_version_ok && 668800180468SJoe Perches defined $stat && 668900180468SJoe 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*\)/) { 669000180468SJoe Perches my $var = $1; 669100180468SJoe Perches my $perms = $2; 669200180468SJoe Perches my $show = $3; 669300180468SJoe Perches my $store = $4; 669400180468SJoe Perches my $octal_perms = perms_to_octal($perms); 669500180468SJoe Perches if ($show =~ /^${var}_show$/ && 669600180468SJoe Perches $store =~ /^${var}_store$/ && 669700180468SJoe Perches $octal_perms eq "0644") { 669800180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 669900180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 670000180468SJoe Perches $fix) { 670100180468SJoe 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})/; 670200180468SJoe Perches } 670300180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 670400180468SJoe Perches $store =~ /^NULL$/ && 670500180468SJoe Perches $octal_perms eq "0444") { 670600180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 670700180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 670800180468SJoe Perches $fix) { 670900180468SJoe 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})/; 671000180468SJoe Perches } 671100180468SJoe Perches } elsif ($show =~ /^NULL$/ && 671200180468SJoe Perches $store =~ /^${var}_store$/ && 671300180468SJoe Perches $octal_perms eq "0200") { 671400180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 671500180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 671600180468SJoe Perches $fix) { 671700180468SJoe 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})/; 671800180468SJoe Perches } 671900180468SJoe Perches } elsif ($octal_perms eq "0644" || 672000180468SJoe Perches $octal_perms eq "0444" || 672100180468SJoe Perches $octal_perms eq "0200") { 672200180468SJoe Perches my $newshow = "$show"; 672300180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 672400180468SJoe Perches my $newstore = $store; 672500180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 672600180468SJoe Perches my $rename = ""; 672700180468SJoe Perches if ($show ne $newshow) { 672800180468SJoe Perches $rename .= " '$show' to '$newshow'"; 672900180468SJoe Perches } 673000180468SJoe Perches if ($store ne $newstore) { 673100180468SJoe Perches $rename .= " '$store' to '$newstore'"; 673200180468SJoe Perches } 673300180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 673400180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 673500180468SJoe Perches } else { 673600180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 673700180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 673800180468SJoe Perches } 673900180468SJoe Perches } 674000180468SJoe Perches 6741515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6742515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 674373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 674473121534SJoe Perches# specific definition of not visible in sysfs. 674573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 674673121534SJoe Perches# use the default permissions 67475b57980dSJoe Perches if ($perl_version_ok && 6748459cf0aeSJoe Perches defined $stat && 6749515a235eSJoe Perches $line =~ /$mode_perms_search/) { 67502435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 67512435880fSJoe Perches my $func = $entry->[0]; 67522435880fSJoe Perches my $arg_pos = $entry->[1]; 67532435880fSJoe Perches 6754459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6755459cf0aeSJoe Perches $lc = $lc + $linenr; 67562a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6757459cf0aeSJoe Perches 67582435880fSJoe Perches my $skip_args = ""; 67592435880fSJoe Perches if ($arg_pos > 1) { 67602435880fSJoe Perches $arg_pos--; 67612435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 67622435880fSJoe Perches } 6763f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6764459cf0aeSJoe Perches if ($stat =~ /$test/) { 67652435880fSJoe Perches my $val = $1; 67662435880fSJoe Perches $val = $6 if ($skip_args ne ""); 676773121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 676873121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 676973121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 67702435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6771459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6772f90774e1SJoe Perches } 6773f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6774c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6775459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 67762435880fSJoe Perches } 6777459cf0aeSJoe Perches } 6778459cf0aeSJoe Perches } 6779459cf0aeSJoe Perches } 6780459cf0aeSJoe Perches 6781459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6782bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 678300180468SJoe Perches my $oval = $1; 678400180468SJoe Perches my $octal = perms_to_octal($oval); 6785f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6786459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6787f90774e1SJoe Perches $fix) { 678800180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 67892435880fSJoe Perches } 679013214adfSAndy Whitcroft } 67915a6d20ceSBjorn Andersson 67925a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 67935a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 67945a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 67955a6d20ceSBjorn Andersson my $valid_licenses = qr{ 67965a6d20ceSBjorn Andersson GPL| 67975a6d20ceSBjorn Andersson GPL\ v2| 67985a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 67995a6d20ceSBjorn Andersson Dual\ BSD/GPL| 68005a6d20ceSBjorn Andersson Dual\ MIT/GPL| 68015a6d20ceSBjorn Andersson Dual\ MPL/GPL| 68025a6d20ceSBjorn Andersson Proprietary 68035a6d20ceSBjorn Andersson }x; 68045a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 68055a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 68065a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 68075a6d20ceSBjorn Andersson } 68085a6d20ceSBjorn Andersson } 68096a8d76cbSMatteo Croce 68106a8d76cbSMatteo Croce# check for sysctl duplicate constants 68116a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 68126a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 68136a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 68146a8d76cbSMatteo Croce } 6815515a235eSJoe Perches } 681613214adfSAndy Whitcroft 681713214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 681813214adfSAndy Whitcroft # so just keep quiet. 681913214adfSAndy Whitcroft if ($#rawlines == -1) { 682013214adfSAndy Whitcroft exit(0); 68210a920b5bSAndy Whitcroft } 68220a920b5bSAndy Whitcroft 68238905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 68248905a67cSAndy Whitcroft # things that appear to be patches. 68258905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 68268905a67cSAndy Whitcroft exit(0); 68278905a67cSAndy Whitcroft } 68288905a67cSAndy Whitcroft 68298905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 68308905a67cSAndy Whitcroft # just keep quiet. 68318905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 68328905a67cSAndy Whitcroft exit(0); 68338905a67cSAndy Whitcroft } 68348905a67cSAndy Whitcroft 6835a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 6836000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6837000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 68380a920b5bSAndy Whitcroft } 6839cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 6840cd261496SGeert Uytterhoeven if ($signoff == 0) { 6841000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6842000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 6843cd261496SGeert Uytterhoeven } elsif (!$authorsignoff) { 6844cd261496SGeert Uytterhoeven WARN("NO_AUTHOR_SIGN_OFF", 6845cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 6846cd261496SGeert Uytterhoeven } 68470a920b5bSAndy Whitcroft } 68480a920b5bSAndy Whitcroft 6849f0a594c1SAndy Whitcroft print report_dump(); 685013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 685113214adfSAndy Whitcroft print "$filename " if ($summary_file); 68526c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 68536c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 68546c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 68556c72ffaaSAndy Whitcroft } 68568905a67cSAndy Whitcroft 6857d2c0a235SAndy Whitcroft if ($quiet == 0) { 6858ef212196SJoe Perches # If there were any defects found and not already fixing them 6859ef212196SJoe Perches if (!$clean and !$fix) { 6860ef212196SJoe Perches print << "EOM" 6861ef212196SJoe Perches 6862ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6863ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6864ef212196SJoe PerchesEOM 6865ef212196SJoe Perches } 6866d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6867d2c0a235SAndy Whitcroft # then suggest that. 6868d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6869b0781216SMike Frysinger $rpt_cleaners = 0; 6870d8469f16SJoe Perches print << "EOM" 6871d8469f16SJoe Perches 6872d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6873d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6874d8469f16SJoe PerchesEOM 6875d2c0a235SAndy Whitcroft } 6876d2c0a235SAndy Whitcroft } 6877d2c0a235SAndy Whitcroft 6878d752fcc8SJoe Perches if ($clean == 0 && $fix && 6879d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6880d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 68819624b8d6SJoe Perches my $newfile = $filename; 68829624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 68833705ce5bSJoe Perches my $linecount = 0; 68843705ce5bSJoe Perches my $f; 68853705ce5bSJoe Perches 6886d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6887d752fcc8SJoe Perches 68883705ce5bSJoe Perches open($f, '>', $newfile) 68893705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 68903705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 68913705ce5bSJoe Perches $linecount++; 68923705ce5bSJoe Perches if ($file) { 68933705ce5bSJoe Perches if ($linecount > 3) { 68943705ce5bSJoe Perches $fixed_line =~ s/^\+//; 68953705ce5bSJoe Perches print $f $fixed_line . "\n"; 68963705ce5bSJoe Perches } 68973705ce5bSJoe Perches } else { 68983705ce5bSJoe Perches print $f $fixed_line . "\n"; 68993705ce5bSJoe Perches } 69003705ce5bSJoe Perches } 69013705ce5bSJoe Perches close($f); 69023705ce5bSJoe Perches 69033705ce5bSJoe Perches if (!$quiet) { 69043705ce5bSJoe Perches print << "EOM"; 6905d8469f16SJoe Perches 69063705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 69073705ce5bSJoe Perches 69083705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 69093705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 69103705ce5bSJoe Perches 69113705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 69123705ce5bSJoe PerchesNo warranties, expressed or implied... 69133705ce5bSJoe PerchesEOM 69143705ce5bSJoe Perches } 69153705ce5bSJoe Perches } 69163705ce5bSJoe Perches 6917d8469f16SJoe Perches if ($quiet == 0) { 6918d8469f16SJoe Perches print "\n"; 6919d8469f16SJoe Perches if ($clean == 1) { 6920d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6921d8469f16SJoe Perches } else { 6922d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 69230a920b5bSAndy Whitcroft } 69240a920b5bSAndy Whitcroft } 69250a920b5bSAndy Whitcroft return $clean; 69260a920b5bSAndy Whitcroft} 6927