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"; 546cd7f386SJoe Perchesmy $max_line_length = 80; 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 65*dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE 66*dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git'; 6777f5b10aSHannes Eder 6877f5b10aSHannes Edersub help { 6977f5b10aSHannes Eder my ($exitcode) = @_; 7077f5b10aSHannes Eder 7177f5b10aSHannes Eder print << "EOM"; 7277f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 7377f5b10aSHannes EderVersion: $V 7477f5b10aSHannes Eder 7577f5b10aSHannes EderOptions: 7677f5b10aSHannes Eder -q, --quiet quiet 7777f5b10aSHannes Eder --no-tree run without a kernel tree 7877f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 7977f5b10aSHannes Eder --patch treat FILE as patchfile (default) 8077f5b10aSHannes Eder --emacs emacs compile window format 8177f5b10aSHannes Eder --terse one line per report 8234d8815fSJoe Perches --showfile emit diffed file position, not input file position 834a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 844a593c34SDu, Changbin single git commit with: 854a593c34SDu, Changbin <rev> 864a593c34SDu, Changbin <rev>^ 874a593c34SDu, Changbin <rev>~n 884a593c34SDu, Changbin multiple git commits with: 894a593c34SDu, Changbin <rev1>..<rev2> 904a593c34SDu, Changbin <rev1>...<rev2> 914a593c34SDu, Changbin <rev>-<count> 924a593c34SDu, Changbin git merges are ignored 9377f5b10aSHannes Eder -f, --file treat FILE as regular source file 9477f5b10aSHannes Eder --subjective, --strict enable more subjective tests 953beb42ecSJoe Perches --list-types list the possible message types 9691bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 97000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 983beb42ecSJoe Perches --show-types show the specific message type in the output 996cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 10056193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 10177f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 10277f5b10aSHannes Eder --no-summary suppress the per-file summary 10377f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 10477f5b10aSHannes Eder --summary-file include the filename in summary 10577f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 10677f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 10777f5b10aSHannes Eder is all off) 10877f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 10977f5b10aSHannes Eder literally 1103705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1113705ce5bSJoe Perches If correctable single-line errors exist, create 1123705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1133705ce5bSJoe Perches with potential errors corrected to the preferred 1143705ce5bSJoe Perches checkpatch style 1159624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1169624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1179624b8d6SJoe Perches file. It's your fault if there's no backup or git 118d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 119d62a201fSDave Hansen runtime errors. 120ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 121f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 122ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 12375ad8c57SJerome Forissier --typedefsfile Read additional types from this file 124737c0767SJohn Brooks --color[=WHEN] Use colors 'always', 'never', or only when output 125737c0767SJohn Brooks is a terminal ('auto'). Default is 'auto'. 12677f5b10aSHannes Eder -h, --help, --version display this help and exit 12777f5b10aSHannes Eder 12877f5b10aSHannes EderWhen FILE is - read standard input. 12977f5b10aSHannes EderEOM 13077f5b10aSHannes Eder 13177f5b10aSHannes Eder exit($exitcode); 13277f5b10aSHannes Eder} 13377f5b10aSHannes Eder 1343beb42ecSJoe Perchessub uniq { 1353beb42ecSJoe Perches my %seen; 1363beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1373beb42ecSJoe Perches} 1383beb42ecSJoe Perches 1393beb42ecSJoe Perchessub list_types { 1403beb42ecSJoe Perches my ($exitcode) = @_; 1413beb42ecSJoe Perches 1423beb42ecSJoe Perches my $count = 0; 1433beb42ecSJoe Perches 1443beb42ecSJoe Perches local $/ = undef; 1453beb42ecSJoe Perches 1463beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1473beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1483beb42ecSJoe Perches 1493beb42ecSJoe Perches my $text = <$script>; 1503beb42ecSJoe Perches close($script); 1513beb42ecSJoe Perches 1523beb42ecSJoe Perches my @types = (); 1530547fa58SJean Delvare # Also catch when type or level is passed through a variable 1540547fa58SJean Delvare for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { 1553beb42ecSJoe Perches push (@types, $_); 1563beb42ecSJoe Perches } 1573beb42ecSJoe Perches @types = sort(uniq(@types)); 1583beb42ecSJoe Perches print("#\tMessage type\n\n"); 1593beb42ecSJoe Perches foreach my $type (@types) { 1603beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1613beb42ecSJoe Perches } 1623beb42ecSJoe Perches 1633beb42ecSJoe Perches exit($exitcode); 1643beb42ecSJoe Perches} 1653beb42ecSJoe Perches 166000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 167000d1cc1SJoe Perchesif (-f $conf) { 168000d1cc1SJoe Perches my @conf_args; 169000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 170000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 171000d1cc1SJoe Perches 172000d1cc1SJoe Perches while (<$conffile>) { 173000d1cc1SJoe Perches my $line = $_; 174000d1cc1SJoe Perches 175000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 176000d1cc1SJoe Perches $line =~ s/^\s*//g; 177000d1cc1SJoe Perches $line =~ s/\s+/ /g; 178000d1cc1SJoe Perches 179000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 180000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 181000d1cc1SJoe Perches 182000d1cc1SJoe Perches my @words = split(" ", $line); 183000d1cc1SJoe Perches foreach my $word (@words) { 184000d1cc1SJoe Perches last if ($word =~ m/^#/); 185000d1cc1SJoe Perches push (@conf_args, $word); 186000d1cc1SJoe Perches } 187000d1cc1SJoe Perches } 188000d1cc1SJoe Perches close($conffile); 189000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 190000d1cc1SJoe Perches} 191000d1cc1SJoe Perches 192737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space. 193737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments 194737c0767SJohn Brooksforeach (@ARGV) { 195737c0767SJohn Brooks if ($_ eq "--color" || $_ eq "-color") { 196737c0767SJohn Brooks $_ = "--color=$color"; 197737c0767SJohn Brooks } 198737c0767SJohn Brooks} 199737c0767SJohn Brooks 2000a920b5bSAndy WhitcroftGetOptions( 2016c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 2020a920b5bSAndy Whitcroft 'tree!' => \$tree, 2030a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 2040a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 2056c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 2068905a67cSAndy Whitcroft 'terse!' => \$terse, 20734d8815fSJoe Perches 'showfile!' => \$showfile, 20877f5b10aSHannes Eder 'f|file!' => \$file, 2094a593c34SDu, Changbin 'g|git!' => \$git, 2106c72ffaaSAndy Whitcroft 'subjective!' => \$check, 2116c72ffaaSAndy Whitcroft 'strict!' => \$check, 212000d1cc1SJoe Perches 'ignore=s' => \@ignore, 21391bfe484SJoe Perches 'types=s' => \@use, 214000d1cc1SJoe Perches 'show-types!' => \$show_types, 2153beb42ecSJoe Perches 'list-types!' => \$list_types, 2166cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 21756193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 2186c72ffaaSAndy Whitcroft 'root=s' => \$root, 2198905a67cSAndy Whitcroft 'summary!' => \$summary, 2208905a67cSAndy Whitcroft 'mailback!' => \$mailback, 22113214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2223705ce5bSJoe Perches 'fix!' => \$fix, 2239624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 224d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 225c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 226773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 227ebfd7d62SJoe Perches 'codespell!' => \$codespell, 228ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 22975ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 230737c0767SJohn Brooks 'color=s' => \$color, 231737c0767SJohn Brooks 'no-color' => \$color, #keep old behaviors of -nocolor 232737c0767SJohn Brooks 'nocolor' => \$color, #keep old behaviors of -nocolor 23377f5b10aSHannes Eder 'h|help' => \$help, 23477f5b10aSHannes Eder 'version' => \$help 23577f5b10aSHannes Eder) or help(1); 23677f5b10aSHannes Eder 23777f5b10aSHannes Ederhelp(0) if ($help); 2380a920b5bSAndy Whitcroft 2393beb42ecSJoe Percheslist_types(0) if ($list_types); 2403beb42ecSJoe Perches 2419624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2422ac73b4fSJoe Perches$check_orig = $check; 2439624b8d6SJoe Perches 2440a920b5bSAndy Whitcroftmy $exit = 0; 2450a920b5bSAndy Whitcroft 2465b57980dSJoe Perchesmy $perl_version_ok = 1; 247d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 2485b57980dSJoe Perches $perl_version_ok = 0; 249d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 2505b57980dSJoe Perches exit(1) if (!$ignore_perl_version); 251d62a201fSDave Hansen} 252d62a201fSDave Hansen 25345107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2540a920b5bSAndy Whitcroftif ($#ARGV < 0) { 25545107ff6SAllen Hubbe push(@ARGV, '-'); 2560a920b5bSAndy Whitcroft} 2570a920b5bSAndy Whitcroft 258737c0767SJohn Brooksif ($color =~ /^[01]$/) { 259737c0767SJohn Brooks $color = !$color; 260737c0767SJohn Brooks} elsif ($color =~ /^always$/i) { 261737c0767SJohn Brooks $color = 1; 262737c0767SJohn Brooks} elsif ($color =~ /^never$/i) { 263737c0767SJohn Brooks $color = 0; 264737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) { 265737c0767SJohn Brooks $color = (-t STDOUT); 266737c0767SJohn Brooks} else { 267737c0767SJohn Brooks die "Invalid color mode: $color\n"; 268737c0767SJohn Brooks} 269737c0767SJohn Brooks 27091bfe484SJoe Perchessub hash_save_array_words { 27191bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 27291bfe484SJoe Perches 27391bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 27491bfe484SJoe Perches foreach my $word (@array) { 275000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 276000d1cc1SJoe Perches $word =~ s/^\s*//g; 277000d1cc1SJoe Perches $word =~ s/\s+/ /g; 278000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 279000d1cc1SJoe Perches 280000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 281000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 282000d1cc1SJoe Perches 28391bfe484SJoe Perches $hashRef->{$word}++; 284000d1cc1SJoe Perches } 28591bfe484SJoe Perches} 28691bfe484SJoe Perches 28791bfe484SJoe Perchessub hash_show_words { 28891bfe484SJoe Perches my ($hashRef, $prefix) = @_; 28991bfe484SJoe Perches 2903c816e49SJoe Perches if (keys %$hashRef) { 291d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 29258cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 29391bfe484SJoe Perches print " $word"; 29491bfe484SJoe Perches } 295d8469f16SJoe Perches print "\n"; 29691bfe484SJoe Perches } 29791bfe484SJoe Perches} 29891bfe484SJoe Perches 29991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 30091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 301000d1cc1SJoe Perches 302c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 303c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 3047429c690SAndy Whitcroftmy $dbg_type = 0; 305a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 306c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 30721caa13cSAndy Whitcroft ## no critic 30821caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 30921caa13cSAndy Whitcroft die "$@" if ($@); 310c2fdda0dSAndy Whitcroft} 311c2fdda0dSAndy Whitcroft 312d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 313d2c0a235SAndy Whitcroft 3148905a67cSAndy Whitcroftif ($terse) { 3158905a67cSAndy Whitcroft $emacs = 1; 3168905a67cSAndy Whitcroft $quiet++; 3178905a67cSAndy Whitcroft} 3188905a67cSAndy Whitcroft 3196c72ffaaSAndy Whitcroftif ($tree) { 3206c72ffaaSAndy Whitcroft if (defined $root) { 3216c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 3226c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 3236c72ffaaSAndy Whitcroft } 3246c72ffaaSAndy Whitcroft } else { 3256c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 3266c72ffaaSAndy Whitcroft $root = '.'; 3276c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 3286c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 3296c72ffaaSAndy Whitcroft $root = $1; 3306c72ffaaSAndy Whitcroft } 3316c72ffaaSAndy Whitcroft } 3326c72ffaaSAndy Whitcroft 3336c72ffaaSAndy Whitcroft if (!defined $root) { 3340a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3350a920b5bSAndy Whitcroft exit(2); 3360a920b5bSAndy Whitcroft } 3376c72ffaaSAndy Whitcroft} 3386c72ffaaSAndy Whitcroft 3396c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3406c72ffaaSAndy Whitcroft 3412ceb532bSAndy Whitcroftour $Ident = qr{ 3422ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3432ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3442ceb532bSAndy Whitcroft }x; 3456c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3466c72ffaaSAndy Whitcroftour $Sparse = qr{ 3476c72ffaaSAndy Whitcroft __user| 3486c72ffaaSAndy Whitcroft __kernel| 3496c72ffaaSAndy Whitcroft __force| 3506c72ffaaSAndy Whitcroft __iomem| 3516c72ffaaSAndy Whitcroft __must_check| 352417495edSAndy Whitcroft __kprobes| 353165e72a6SSven Eckelmann __ref| 35433aa4597SGeert Uytterhoeven __refconst| 35533aa4597SGeert Uytterhoeven __refdata| 356ad315455SBoqun Feng __rcu| 357ad315455SBoqun Feng __private 3586c72ffaaSAndy Whitcroft }x; 359e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 360e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 361e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 362e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 363e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3648716de38SJoe Perches 36552131292SWolfram Sang# Notes to $Attribute: 36652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3676c72ffaaSAndy Whitcroftour $Attribute = qr{ 3686c72ffaaSAndy Whitcroft const| 36903f1df7dSJoe Perches __percpu| 37003f1df7dSJoe Perches __nocast| 37103f1df7dSJoe Perches __safe| 37246d832f5SMichael S. Tsirkin __bitwise| 37303f1df7dSJoe Perches __packed__| 37403f1df7dSJoe Perches __packed2__| 37503f1df7dSJoe Perches __naked| 37603f1df7dSJoe Perches __maybe_unused| 37703f1df7dSJoe Perches __always_unused| 37803f1df7dSJoe Perches __noreturn| 37903f1df7dSJoe Perches __used| 38003f1df7dSJoe Perches __cold| 381e23ef1f3SJoe Perches __pure| 38203f1df7dSJoe Perches __noclone| 38303f1df7dSJoe Perches __deprecated| 3846c72ffaaSAndy Whitcroft __read_mostly| 385c5967e98SJoe Perches __ro_after_init| 3866c72ffaaSAndy Whitcroft __kprobes| 3878716de38SJoe Perches $InitAttribute| 38824e1d81aSAndy Whitcroft ____cacheline_aligned| 38924e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 3905fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 3915fe3af11SAndy Whitcroft __weak 3926c72ffaaSAndy Whitcroft }x; 393c45dcabdSAndy Whitcroftour $Modifier; 39491cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 3956c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 3966c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 3976c72ffaaSAndy Whitcroft 39895e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 39995e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 40095e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 40195e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 4022435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 403c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 404326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 405326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 406326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 40774349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 4082435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 409326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 410447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 41123f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 4126c72ffaaSAndy Whitcroftour $Operators = qr{ 4136c72ffaaSAndy Whitcroft <=|>=|==|!=| 4146c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 41523f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 4166c72ffaaSAndy Whitcroft }x; 4176c72ffaaSAndy Whitcroft 41891cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 41991cb5195SJoe Perches 420ab7e23f3SJoe Perchesour $BasicType; 4218905a67cSAndy Whitcroftour $NonptrType; 4221813087dSJoe Perchesour $NonptrTypeMisordered; 4238716de38SJoe Perchesour $NonptrTypeWithAttr; 4248905a67cSAndy Whitcroftour $Type; 4251813087dSJoe Perchesour $TypeMisordered; 4268905a67cSAndy Whitcroftour $Declare; 4271813087dSJoe Perchesour $DeclareMisordered; 4288905a67cSAndy Whitcroft 42915662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 43015662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 431171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 432171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 433171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 434171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 435171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 436171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 437171ae1a4SAndy Whitcroft}x; 438171ae1a4SAndy Whitcroft 43915662b3eSJoe Perchesour $UTF8 = qr{ 44015662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 44115662b3eSJoe Perches | $NON_ASCII_UTF8 44215662b3eSJoe Perches}x; 44315662b3eSJoe Perches 444e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 445021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 446021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 447021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 448021158b4SJoe Perches)}; 449e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 450fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4518ed22cadSAndy Whitcroft atomic_t 4528ed22cadSAndy Whitcroft)}; 453e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 454e6176fa4SJoe Perches $typeC99Typedefs\b| 455e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 456e6176fa4SJoe Perches $typeKernelTypedefs\b 457e6176fa4SJoe Perches)}; 4588ed22cadSAndy Whitcroft 4596d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4606d32f7a3SJoe Perches 461691e669bSJoe Perchesour $logFunctions = qr{(?x: 462758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4637d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 46487bd499aSJoe Perches TP_printk| 4656e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 466b0531722SJoe Perches panic| 46706668727SJoe Perches MODULE_[A-Z_]+| 46806668727SJoe Perches seq_vprintf|seq_printf|seq_puts 469691e669bSJoe Perches)}; 470691e669bSJoe Perches 471e29a70f1SJoe Perchesour $allocFunctions = qr{(?x: 472e29a70f1SJoe Perches (?:(?:devm_)? 473e29a70f1SJoe Perches (?:kv|k|v)[czm]alloc(?:_node|_array)? | 474e29a70f1SJoe Perches kstrdup(?:_const)? | 475e29a70f1SJoe Perches kmemdup(?:_nul)?) | 476e29a70f1SJoe Perches (?:\w+)?alloc_skb(?:ip_align)? | 477e29a70f1SJoe Perches # dev_alloc_skb/netdev_alloc_skb, et al 478e29a70f1SJoe Perches dma_alloc_coherent 479e29a70f1SJoe Perches)}; 480e29a70f1SJoe Perches 48120112475SJoe Perchesour $signature_tags = qr{(?xi: 48220112475SJoe Perches Signed-off-by:| 483d499480cSJorge Ramirez-Ortiz Co-developed-by:| 48420112475SJoe Perches Acked-by:| 48520112475SJoe Perches Tested-by:| 48620112475SJoe Perches Reviewed-by:| 48720112475SJoe Perches Reported-by:| 4888543ae12SMugunthan V N Suggested-by:| 48920112475SJoe Perches To:| 49020112475SJoe Perches Cc: 49120112475SJoe Perches)}; 49220112475SJoe Perches 4931813087dSJoe Perchesour @typeListMisordered = ( 4941813087dSJoe Perches qr{char\s+(?:un)?signed}, 4951813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 4961813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 4971813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 4981813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 4991813087dSJoe Perches qr{short\s+(?:un)?signed}, 5001813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 5011813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 5021813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 5031813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 5041813087dSJoe Perches qr{int\s+(?:un)?signed}, 5051813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 5061813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 5071813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 5081813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 5091813087dSJoe Perches qr{long\s+(?:un)?signed}, 5101813087dSJoe Perches); 5111813087dSJoe Perches 5128905a67cSAndy Whitcroftour @typeList = ( 5138905a67cSAndy Whitcroft qr{void}, 5140c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 5150c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 5160c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 5170c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 5180c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 5190c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 5200c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 5210c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 5220c773d9dSJoe Perches qr{(?:un)?signed}, 5238905a67cSAndy Whitcroft qr{float}, 5248905a67cSAndy Whitcroft qr{double}, 5258905a67cSAndy Whitcroft qr{bool}, 5268905a67cSAndy Whitcroft qr{struct\s+$Ident}, 5278905a67cSAndy Whitcroft qr{union\s+$Ident}, 5288905a67cSAndy Whitcroft qr{enum\s+$Ident}, 5298905a67cSAndy Whitcroft qr{${Ident}_t}, 5308905a67cSAndy Whitcroft qr{${Ident}_handler}, 5318905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 5321813087dSJoe Perches @typeListMisordered, 5338905a67cSAndy Whitcroft); 534938224b5SJoe Perches 535938224b5SJoe Perchesour $C90_int_types = qr{(?x: 536938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 537938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 538938224b5SJoe Perches long\s+long\s+(?:un)?signed| 539938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 540938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 541938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 542938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 543938224b5SJoe Perches 544938224b5SJoe Perches long\s+int\s+(?:un)?signed| 545938224b5SJoe Perches long\s+(?:un)?signed\s+int| 546938224b5SJoe Perches long\s+(?:un)?signed| 547938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 548938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 549938224b5SJoe Perches int\s+long\s+(?:un)?signed| 550938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 551938224b5SJoe Perches 552938224b5SJoe Perches int\s+(?:un)?signed| 553938224b5SJoe Perches (?:(?:un)?signed\s+)?int 554938224b5SJoe Perches)}; 555938224b5SJoe Perches 556485ff23eSAlex Dowadour @typeListFile = (); 5578716de38SJoe Perchesour @typeListWithAttr = ( 5588716de38SJoe Perches @typeList, 5598716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 5608716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 5618716de38SJoe Perches); 5628716de38SJoe Perches 563c45dcabdSAndy Whitcroftour @modifierList = ( 564c45dcabdSAndy Whitcroft qr{fastcall}, 565c45dcabdSAndy Whitcroft); 566485ff23eSAlex Dowadour @modifierListFile = (); 5678905a67cSAndy Whitcroft 5682435880fSJoe Perchesour @mode_permission_funcs = ( 5692435880fSJoe Perches ["module_param", 3], 5702435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 5712435880fSJoe Perches ["module_param_array_named", 5], 5722435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 5732435880fSJoe Perches ["proc_create(?:_data|)", 2], 574459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 575459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 576459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 577459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 578459cf0aeSJoe Perches ["__ATTR", 2], 5792435880fSJoe Perches); 5802435880fSJoe Perches 581515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 582515a235eSJoe Perchesour $mode_perms_search = ""; 583515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 584515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 585515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 586515a235eSJoe Perches} 58700180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})"; 588515a235eSJoe Perches 5899189c7e7SJoe Perchesour %deprecated_apis = ( 5909189c7e7SJoe Perches "synchronize_rcu_bh" => "synchronize_rcu", 5919189c7e7SJoe Perches "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 5929189c7e7SJoe Perches "call_rcu_bh" => "call_rcu", 5939189c7e7SJoe Perches "rcu_barrier_bh" => "rcu_barrier", 5949189c7e7SJoe Perches "synchronize_sched" => "synchronize_rcu", 5959189c7e7SJoe Perches "synchronize_sched_expedited" => "synchronize_rcu_expedited", 5969189c7e7SJoe Perches "call_rcu_sched" => "call_rcu", 5979189c7e7SJoe Perches "rcu_barrier_sched" => "rcu_barrier", 5989189c7e7SJoe Perches "get_state_synchronize_sched" => "get_state_synchronize_rcu", 5999189c7e7SJoe Perches "cond_synchronize_sched" => "cond_synchronize_rcu", 6009189c7e7SJoe Perches); 6019189c7e7SJoe Perches 6029189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below 6039189c7e7SJoe Perchesour $deprecated_apis_search = ""; 6049189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) { 6059189c7e7SJoe Perches $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 6069189c7e7SJoe Perches $deprecated_apis_search .= $entry; 6079189c7e7SJoe Perches} 6089189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})"; 6099189c7e7SJoe Perches 610b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 611b392c64fSJoe Perches S_IWUGO | 612b392c64fSJoe Perches S_IWOTH | 613b392c64fSJoe Perches S_IRWXUGO | 614b392c64fSJoe Perches S_IALLUGO | 615b392c64fSJoe Perches 0[0-7][0-7][2367] 616b392c64fSJoe Perches}x; 617b392c64fSJoe Perches 618f90774e1SJoe Perchesour %mode_permission_string_types = ( 619f90774e1SJoe Perches "S_IRWXU" => 0700, 620f90774e1SJoe Perches "S_IRUSR" => 0400, 621f90774e1SJoe Perches "S_IWUSR" => 0200, 622f90774e1SJoe Perches "S_IXUSR" => 0100, 623f90774e1SJoe Perches "S_IRWXG" => 0070, 624f90774e1SJoe Perches "S_IRGRP" => 0040, 625f90774e1SJoe Perches "S_IWGRP" => 0020, 626f90774e1SJoe Perches "S_IXGRP" => 0010, 627f90774e1SJoe Perches "S_IRWXO" => 0007, 628f90774e1SJoe Perches "S_IROTH" => 0004, 629f90774e1SJoe Perches "S_IWOTH" => 0002, 630f90774e1SJoe Perches "S_IXOTH" => 0001, 631f90774e1SJoe Perches "S_IRWXUGO" => 0777, 632f90774e1SJoe Perches "S_IRUGO" => 0444, 633f90774e1SJoe Perches "S_IWUGO" => 0222, 634f90774e1SJoe Perches "S_IXUGO" => 0111, 635f90774e1SJoe Perches); 636f90774e1SJoe Perches 637f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 638f90774e1SJoe Perchesour $mode_perms_string_search = ""; 639f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 640f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 641f90774e1SJoe Perches $mode_perms_string_search .= $entry; 642f90774e1SJoe Perches} 64300180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; 64400180468SJoe Perchesour $multi_mode_perms_string_search = qr{ 64500180468SJoe Perches ${single_mode_perms_string_search} 64600180468SJoe Perches (?:\s*\|\s*${single_mode_perms_string_search})* 64700180468SJoe Perches}x; 64800180468SJoe Perches 64900180468SJoe Perchessub perms_to_octal { 65000180468SJoe Perches my ($string) = @_; 65100180468SJoe Perches 65200180468SJoe Perches return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); 65300180468SJoe Perches 65400180468SJoe Perches my $val = ""; 65500180468SJoe Perches my $oval = ""; 65600180468SJoe Perches my $to = 0; 65700180468SJoe Perches my $curpos = 0; 65800180468SJoe Perches my $lastpos = 0; 65900180468SJoe Perches while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 66000180468SJoe Perches $curpos = pos($string); 66100180468SJoe Perches my $match = $2; 66200180468SJoe Perches my $omatch = $1; 66300180468SJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 66400180468SJoe Perches $lastpos = $curpos; 66500180468SJoe Perches $to |= $mode_permission_string_types{$match}; 66600180468SJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 66700180468SJoe Perches $val .= $match; 66800180468SJoe Perches $oval .= $omatch; 66900180468SJoe Perches } 67000180468SJoe Perches $oval =~ s/^\s*\|\s*//; 67100180468SJoe Perches $oval =~ s/\s*\|\s*$//; 67200180468SJoe Perches return sprintf("%04o", $to); 67300180468SJoe Perches} 674f90774e1SJoe Perches 6757840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 6767840a94cSWolfram Sang irq| 677cdcee686SSergey Ryazanov memory| 678cdcee686SSergey Ryazanov time| 679cdcee686SSergey Ryazanov reboot 6807840a94cSWolfram Sang)}; 6817840a94cSWolfram Sang# memory.h: ARM has a custom one 6827840a94cSWolfram Sang 68366b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 68466b47b4aSKees Cookmy $misspellings; 68566b47b4aSKees Cookmy %spelling_fix; 68636061e38SJoe Perches 68736061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 68866b47b4aSKees Cook while (<$spelling>) { 68966b47b4aSKees Cook my $line = $_; 69066b47b4aSKees Cook 69166b47b4aSKees Cook $line =~ s/\s*\n?$//g; 69266b47b4aSKees Cook $line =~ s/^\s*//g; 69366b47b4aSKees Cook 69466b47b4aSKees Cook next if ($line =~ m/^\s*#/); 69566b47b4aSKees Cook next if ($line =~ m/^\s*$/); 69666b47b4aSKees Cook 69766b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 69866b47b4aSKees Cook 69966b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 70066b47b4aSKees Cook } 70166b47b4aSKees Cook close($spelling); 70236061e38SJoe Perches} else { 70336061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 70436061e38SJoe Perches} 70566b47b4aSKees Cook 706ebfd7d62SJoe Perchesif ($codespell) { 707ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 708ebfd7d62SJoe Perches while (<$spelling>) { 709ebfd7d62SJoe Perches my $line = $_; 710ebfd7d62SJoe Perches 711ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 712ebfd7d62SJoe Perches $line =~ s/^\s*//g; 713ebfd7d62SJoe Perches 714ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 715ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 716ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 717ebfd7d62SJoe Perches 718ebfd7d62SJoe Perches $line =~ s/,.*$//; 719ebfd7d62SJoe Perches 720ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 721ebfd7d62SJoe Perches 722ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 723ebfd7d62SJoe Perches } 724ebfd7d62SJoe Perches close($spelling); 725ebfd7d62SJoe Perches } else { 726ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 727ebfd7d62SJoe Perches } 728ebfd7d62SJoe Perches} 729ebfd7d62SJoe Perches 730ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 731ebfd7d62SJoe Perches 73275ad8c57SJerome Forissiersub read_words { 73375ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 73475ad8c57SJerome Forissier 73575ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 73675ad8c57SJerome Forissier while (<$words>) { 737bf1fa1daSJoe Perches my $line = $_; 738bf1fa1daSJoe Perches 739bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 740bf1fa1daSJoe Perches $line =~ s/^\s*//g; 741bf1fa1daSJoe Perches 742bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 743bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 744bf1fa1daSJoe Perches if ($line =~ /\s/) { 74575ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 746bf1fa1daSJoe Perches next; 747bf1fa1daSJoe Perches } 748bf1fa1daSJoe Perches 74975ad8c57SJerome Forissier $$wordsRef .= '|' if ($$wordsRef ne ""); 75075ad8c57SJerome Forissier $$wordsRef .= $line; 751bf1fa1daSJoe Perches } 75275ad8c57SJerome Forissier close($file); 75375ad8c57SJerome Forissier return 1; 754bf1fa1daSJoe Perches } 755bf1fa1daSJoe Perches 75675ad8c57SJerome Forissier return 0; 75775ad8c57SJerome Forissier} 75875ad8c57SJerome Forissier 75975ad8c57SJerome Forissiermy $const_structs = ""; 76075ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile) 76175ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 76275ad8c57SJerome Forissier 76375ad8c57SJerome Forissiermy $typeOtherTypedefs = ""; 76475ad8c57SJerome Forissierif (length($typedefsfile)) { 76575ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 76675ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 76775ad8c57SJerome Forissier} 76875ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); 76975ad8c57SJerome Forissier 7708905a67cSAndy Whitcroftsub build_types { 771485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 772485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 7731813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 7748716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 775c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 776ab7e23f3SJoe Perches $BasicType = qr{ 777ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 778ab7e23f3SJoe Perches (?:${all}\b) 779ab7e23f3SJoe Perches }x; 7808905a67cSAndy Whitcroft $NonptrType = qr{ 781d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 782cf655043SAndy Whitcroft (?: 7836b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 7848ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 785c45dcabdSAndy Whitcroft (?:${all}\b) 786cf655043SAndy Whitcroft ) 787c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 7888905a67cSAndy Whitcroft }x; 7891813087dSJoe Perches $NonptrTypeMisordered = qr{ 7901813087dSJoe Perches (?:$Modifier\s+|const\s+)* 7911813087dSJoe Perches (?: 7921813087dSJoe Perches (?:${Misordered}\b) 7931813087dSJoe Perches ) 7941813087dSJoe Perches (?:\s+$Modifier|\s+const)* 7951813087dSJoe Perches }x; 7968716de38SJoe Perches $NonptrTypeWithAttr = qr{ 7978716de38SJoe Perches (?:$Modifier\s+|const\s+)* 7988716de38SJoe Perches (?: 7998716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 8008716de38SJoe Perches (?:$typeTypedefs\b)| 8018716de38SJoe Perches (?:${allWithAttr}\b) 8028716de38SJoe Perches ) 8038716de38SJoe Perches (?:\s+$Modifier|\s+const)* 8048716de38SJoe Perches }x; 8058905a67cSAndy Whitcroft $Type = qr{ 806c45dcabdSAndy Whitcroft $NonptrType 8071574a29fSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 808c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 8098905a67cSAndy Whitcroft }x; 8101813087dSJoe Perches $TypeMisordered = qr{ 8111813087dSJoe Perches $NonptrTypeMisordered 8121813087dSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 8131813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 8141813087dSJoe Perches }x; 81591cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 8161813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 8178905a67cSAndy Whitcroft} 8188905a67cSAndy Whitcroftbuild_types(); 8196c72ffaaSAndy Whitcroft 8207d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 821d1fe9c09SJoe Perches 822d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 823d1fe9c09SJoe Perches# requires at least perl version v5.10.0 824d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 825d1fe9c09SJoe Perches 826d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 8272435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 828c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 8297d2367afSJoe Perches 830f8422308SJoe Perchesour $declaration_macros = qr{(?x: 8313e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 832fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| 8333d102fc0SGilad Ben-Yossef (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(| 8343d102fc0SGilad Ben-Yossef (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( 835f8422308SJoe Perches)}; 836f8422308SJoe Perches 8377d2367afSJoe Perchessub deparenthesize { 8387d2367afSJoe Perches my ($string) = @_; 8397d2367afSJoe Perches return "" if (!defined($string)); 8405b9553abSJoe Perches 8415b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 8425b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 8435b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 8445b9553abSJoe Perches } 8455b9553abSJoe Perches 8467d2367afSJoe Perches $string =~ s@\s+@ @g; 8475b9553abSJoe Perches 8487d2367afSJoe Perches return $string; 8497d2367afSJoe Perches} 8507d2367afSJoe Perches 8513445686aSJoe Perchessub seed_camelcase_file { 8523445686aSJoe Perches my ($file) = @_; 8533445686aSJoe Perches 8543445686aSJoe Perches return if (!(-f $file)); 8553445686aSJoe Perches 8563445686aSJoe Perches local $/; 8573445686aSJoe Perches 8583445686aSJoe Perches open(my $include_file, '<', "$file") 8593445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 8603445686aSJoe Perches my $text = <$include_file>; 8613445686aSJoe Perches close($include_file); 8623445686aSJoe Perches 8633445686aSJoe Perches my @lines = split('\n', $text); 8643445686aSJoe Perches 8653445686aSJoe Perches foreach my $line (@lines) { 8663445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 8673445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 8683445686aSJoe Perches $camelcase{$1} = 1; 86911ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 87011ea516aSJoe Perches $camelcase{$1} = 1; 87111ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 8723445686aSJoe Perches $camelcase{$1} = 1; 8733445686aSJoe Perches } 8743445686aSJoe Perches } 8753445686aSJoe Perches} 8763445686aSJoe Perches 87785b0ee18SJoe Perchessub is_maintained_obsolete { 87885b0ee18SJoe Perches my ($filename) = @_; 87985b0ee18SJoe Perches 880f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 88185b0ee18SJoe Perches 8820616efa4SJoe Perches my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 88385b0ee18SJoe Perches 88485b0ee18SJoe Perches return $status =~ /obsolete/i; 88585b0ee18SJoe Perches} 88685b0ee18SJoe Perches 8873b6e8ac9SJoe Perchessub is_SPDX_License_valid { 8883b6e8ac9SJoe Perches my ($license) = @_; 8893b6e8ac9SJoe Perches 89056294112SJoe Perches return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git")); 8913b6e8ac9SJoe Perches 89256294112SJoe Perches my $root_path = abs_path($root); 89356294112SJoe Perches my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; 8943b6e8ac9SJoe Perches return 0 if ($status ne ""); 8953b6e8ac9SJoe Perches return 1; 8963b6e8ac9SJoe Perches} 8973b6e8ac9SJoe Perches 8983445686aSJoe Perchesmy $camelcase_seeded = 0; 8993445686aSJoe Perchessub seed_camelcase_includes { 9003445686aSJoe Perches return if ($camelcase_seeded); 9013445686aSJoe Perches 9023445686aSJoe Perches my $files; 903c707a81dSJoe Perches my $camelcase_cache = ""; 904c707a81dSJoe Perches my @include_files = (); 905c707a81dSJoe Perches 906c707a81dSJoe Perches $camelcase_seeded = 1; 907351b2a1fSJoe Perches 9083645e328SRichard Genoud if (-e ".git") { 909*dbbf869dSJoe Perches my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; 910351b2a1fSJoe Perches chomp $git_last_include_commit; 911c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 912c707a81dSJoe Perches } else { 913c707a81dSJoe Perches my $last_mod_date = 0; 914c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 915c707a81dSJoe Perches @include_files = split('\n', $files); 916c707a81dSJoe Perches foreach my $file (@include_files) { 917c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 918c707a81dSJoe Perches localtime((stat $file)[9])); 919c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 920c707a81dSJoe Perches } 921c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 922c707a81dSJoe Perches } 923c707a81dSJoe Perches 924c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 925c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 926c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 927351b2a1fSJoe Perches while (<$camelcase_file>) { 928351b2a1fSJoe Perches chomp; 929351b2a1fSJoe Perches $camelcase{$_} = 1; 930351b2a1fSJoe Perches } 931351b2a1fSJoe Perches close($camelcase_file); 932351b2a1fSJoe Perches 933351b2a1fSJoe Perches return; 934351b2a1fSJoe Perches } 935c707a81dSJoe Perches 9363645e328SRichard Genoud if (-e ".git") { 937*dbbf869dSJoe Perches $files = `${git_command} ls-files "include/*.h"`; 938c707a81dSJoe Perches @include_files = split('\n', $files); 9393445686aSJoe Perches } 940c707a81dSJoe Perches 9413445686aSJoe Perches foreach my $file (@include_files) { 9423445686aSJoe Perches seed_camelcase_file($file); 9433445686aSJoe Perches } 944351b2a1fSJoe Perches 945c707a81dSJoe Perches if ($camelcase_cache ne "") { 946351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 947c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 948c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 949351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 950351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 951351b2a1fSJoe Perches } 952351b2a1fSJoe Perches close($camelcase_file); 953351b2a1fSJoe Perches } 9543445686aSJoe Perches} 9553445686aSJoe Perches 956d311cd44SJoe Perchessub git_commit_info { 957d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 958d311cd44SJoe Perches 959d311cd44SJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 960d311cd44SJoe Perches 961*dbbf869dSJoe Perches my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; 962d311cd44SJoe Perches $output =~ s/^\s*//gm; 963d311cd44SJoe Perches my @lines = split("\n", $output); 964d311cd44SJoe Perches 9650d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 9660d7835fcSJoe Perches 9675a7f4455SSean Christopherson if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { 968d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 969d311cd44SJoe Perches# all matching commit ids, but it's very slow... 970d311cd44SJoe Perches# 971d311cd44SJoe Perches# echo "checking commits $1..." 972d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 973d311cd44SJoe Perches# while read line ; do 974d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 975d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 976d311cd44SJoe Perches# done 977d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 978948b133aSHeinrich Schuchardt $id = undef; 979d311cd44SJoe Perches } else { 980d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 981d311cd44SJoe Perches $desc = substr($lines[0], 41); 982d311cd44SJoe Perches } 983d311cd44SJoe Perches 984d311cd44SJoe Perches return ($id, $desc); 985d311cd44SJoe Perches} 986d311cd44SJoe Perches 9876c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 9880a920b5bSAndy Whitcroft 98900df344fSAndy Whitcroftmy @rawlines = (); 990c2fdda0dSAndy Whitcroftmy @lines = (); 9913705ce5bSJoe Perchesmy @fixed = (); 992d752fcc8SJoe Perchesmy @fixed_inserted = (); 993d752fcc8SJoe Perchesmy @fixed_deleted = (); 994194f66fcSJoe Perchesmy $fixlinenr = -1; 995194f66fcSJoe Perches 9964a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 9974a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 9984a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git"); 9994a593c34SDu, Changbin 10004a593c34SDu, Changbinif ($git) { 10014a593c34SDu, Changbin my @commits = (); 10020dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 10034a593c34SDu, Changbin my $git_range; 100428898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 100528898fd1SJoe Perches $git_range = "-$2 $1"; 10064a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 10074a593c34SDu, Changbin $git_range = "$commit_expr"; 10084a593c34SDu, Changbin } else { 10090dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 10100dea9f1eSJoe Perches } 1011*dbbf869dSJoe Perches my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 10120dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 101328898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 101428898fd1SJoe Perches next if (!defined($1) || !defined($2)); 10150dea9f1eSJoe Perches my $sha1 = $1; 10160dea9f1eSJoe Perches my $subject = $2; 10170dea9f1eSJoe Perches unshift(@commits, $sha1); 10180dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 10194a593c34SDu, Changbin } 10204a593c34SDu, Changbin } 10214a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 10224a593c34SDu, Changbin @ARGV = @commits; 10234a593c34SDu, Changbin} 10244a593c34SDu, Changbin 1025c2fdda0dSAndy Whitcroftmy $vname; 102698005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; 10276c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 102821caa13cSAndy Whitcroft my $FILE; 10294a593c34SDu, Changbin if ($git) { 10304a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 10314a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 10324a593c34SDu, Changbin } elsif ($file) { 103321caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 10346c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 103521caa13cSAndy Whitcroft } elsif ($filename eq '-') { 103621caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 10376c72ffaaSAndy Whitcroft } else { 103821caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 10396c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 10406c72ffaaSAndy Whitcroft } 1041c2fdda0dSAndy Whitcroft if ($filename eq '-') { 1042c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 10434a593c34SDu, Changbin } elsif ($git) { 10440dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 1045c2fdda0dSAndy Whitcroft } else { 1046c2fdda0dSAndy Whitcroft $vname = $filename; 1047c2fdda0dSAndy Whitcroft } 104821caa13cSAndy Whitcroft while (<$FILE>) { 10490a920b5bSAndy Whitcroft chomp; 105000df344fSAndy Whitcroft push(@rawlines, $_); 10516c72ffaaSAndy Whitcroft } 105221caa13cSAndy Whitcroft close($FILE); 1053d8469f16SJoe Perches 1054d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 1055d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1056d8469f16SJoe Perches print "$vname\n"; 1057d8469f16SJoe Perches print '-' x length($vname) . "\n"; 1058d8469f16SJoe Perches } 1059d8469f16SJoe Perches 1060c2fdda0dSAndy Whitcroft if (!process($filename)) { 10610a920b5bSAndy Whitcroft $exit = 1; 10620a920b5bSAndy Whitcroft } 106300df344fSAndy Whitcroft @rawlines = (); 106413214adfSAndy Whitcroft @lines = (); 10653705ce5bSJoe Perches @fixed = (); 1066d752fcc8SJoe Perches @fixed_inserted = (); 1067d752fcc8SJoe Perches @fixed_deleted = (); 1068194f66fcSJoe Perches $fixlinenr = -1; 1069485ff23eSAlex Dowad @modifierListFile = (); 1070485ff23eSAlex Dowad @typeListFile = (); 1071485ff23eSAlex Dowad build_types(); 10720a920b5bSAndy Whitcroft} 10730a920b5bSAndy Whitcroft 1074d8469f16SJoe Perchesif (!$quiet) { 10753c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 10763c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 10773c816e49SJoe Perches 10785b57980dSJoe Perches if (!$perl_version_ok) { 1079d8469f16SJoe Perches print << "EOM" 1080d8469f16SJoe Perches 1081d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 10825b57980dSJoe Perches An upgrade to at least perl $minimum_perl_version is suggested. 1083d8469f16SJoe PerchesEOM 1084d8469f16SJoe Perches } 1085d8469f16SJoe Perches if ($exit) { 1086d8469f16SJoe Perches print << "EOM" 1087d8469f16SJoe Perches 1088d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 1089d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 1090d8469f16SJoe PerchesEOM 1091d8469f16SJoe Perches } 1092d8469f16SJoe Perches} 1093d8469f16SJoe Perches 10940a920b5bSAndy Whitcroftexit($exit); 10950a920b5bSAndy Whitcroft 10960a920b5bSAndy Whitcroftsub top_of_kernel_tree { 10976c72ffaaSAndy Whitcroft my ($root) = @_; 10986c72ffaaSAndy Whitcroft 10996c72ffaaSAndy Whitcroft my @tree_check = ( 11006c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 11016c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 11026c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 11036c72ffaaSAndy Whitcroft ); 11046c72ffaaSAndy Whitcroft 11056c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 11066c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 11070a920b5bSAndy Whitcroft return 0; 11080a920b5bSAndy Whitcroft } 11096c72ffaaSAndy Whitcroft } 11106c72ffaaSAndy Whitcroft return 1; 11116c72ffaaSAndy Whitcroft} 11120a920b5bSAndy Whitcroft 111320112475SJoe Perchessub parse_email { 111420112475SJoe Perches my ($formatted_email) = @_; 111520112475SJoe Perches 111620112475SJoe Perches my $name = ""; 111720112475SJoe Perches my $address = ""; 111820112475SJoe Perches my $comment = ""; 111920112475SJoe Perches 112020112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 112120112475SJoe Perches $name = $1; 112220112475SJoe Perches $address = $2; 112320112475SJoe Perches $comment = $3 if defined $3; 112420112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 112520112475SJoe Perches $address = $1; 112620112475SJoe Perches $comment = $2 if defined $2; 112720112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 112820112475SJoe Perches $address = $1; 112920112475SJoe Perches $comment = $2 if defined $2; 113085e12066SJoe Perches $formatted_email =~ s/\Q$address\E.*$//; 113120112475SJoe Perches $name = $formatted_email; 11323705ce5bSJoe Perches $name = trim($name); 113320112475SJoe Perches $name =~ s/^\"|\"$//g; 113420112475SJoe Perches # If there's a name left after stripping spaces and 113520112475SJoe Perches # leading quotes, and the address doesn't have both 113620112475SJoe Perches # leading and trailing angle brackets, the address 113720112475SJoe Perches # is invalid. ie: 113820112475SJoe Perches # "joe smith [email protected]" bad 113920112475SJoe Perches # "joe smith <[email protected]" bad 114020112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 114120112475SJoe Perches $name = ""; 114220112475SJoe Perches $address = ""; 114320112475SJoe Perches $comment = ""; 114420112475SJoe Perches } 114520112475SJoe Perches } 114620112475SJoe Perches 11473705ce5bSJoe Perches $name = trim($name); 114820112475SJoe Perches $name =~ s/^\"|\"$//g; 11493705ce5bSJoe Perches $address = trim($address); 115020112475SJoe Perches $address =~ s/^\<|\>$//g; 115120112475SJoe Perches 115220112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 115320112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 115420112475SJoe Perches $name = "\"$name\""; 115520112475SJoe Perches } 115620112475SJoe Perches 115720112475SJoe Perches return ($name, $address, $comment); 115820112475SJoe Perches} 115920112475SJoe Perches 116020112475SJoe Perchessub format_email { 116120112475SJoe Perches my ($name, $address) = @_; 116220112475SJoe Perches 116320112475SJoe Perches my $formatted_email; 116420112475SJoe Perches 11653705ce5bSJoe Perches $name = trim($name); 116620112475SJoe Perches $name =~ s/^\"|\"$//g; 11673705ce5bSJoe Perches $address = trim($address); 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 117420112475SJoe Perches if ("$name" eq "") { 117520112475SJoe Perches $formatted_email = "$address"; 117620112475SJoe Perches } else { 117720112475SJoe Perches $formatted_email = "$name <$address>"; 117820112475SJoe Perches } 117920112475SJoe Perches 118020112475SJoe Perches return $formatted_email; 118120112475SJoe Perches} 118220112475SJoe Perches 1183d311cd44SJoe Perchessub which { 1184d311cd44SJoe Perches my ($bin) = @_; 1185d311cd44SJoe Perches 1186d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1187d311cd44SJoe Perches if (-e "$path/$bin") { 1188d311cd44SJoe Perches return "$path/$bin"; 1189d311cd44SJoe Perches } 1190d311cd44SJoe Perches } 1191d311cd44SJoe Perches 1192d311cd44SJoe Perches return ""; 1193d311cd44SJoe Perches} 1194d311cd44SJoe Perches 1195000d1cc1SJoe Perchessub which_conf { 1196000d1cc1SJoe Perches my ($conf) = @_; 1197000d1cc1SJoe Perches 1198000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1199000d1cc1SJoe Perches if (-e "$path/$conf") { 1200000d1cc1SJoe Perches return "$path/$conf"; 1201000d1cc1SJoe Perches } 1202000d1cc1SJoe Perches } 1203000d1cc1SJoe Perches 1204000d1cc1SJoe Perches return ""; 1205000d1cc1SJoe Perches} 1206000d1cc1SJoe Perches 12070a920b5bSAndy Whitcroftsub expand_tabs { 12080a920b5bSAndy Whitcroft my ($str) = @_; 12090a920b5bSAndy Whitcroft 12100a920b5bSAndy Whitcroft my $res = ''; 12110a920b5bSAndy Whitcroft my $n = 0; 12120a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 12130a920b5bSAndy Whitcroft if ($c eq "\t") { 12140a920b5bSAndy Whitcroft $res .= ' '; 12150a920b5bSAndy Whitcroft $n++; 12160a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 12170a920b5bSAndy Whitcroft $res .= ' '; 12180a920b5bSAndy Whitcroft } 12190a920b5bSAndy Whitcroft next; 12200a920b5bSAndy Whitcroft } 12210a920b5bSAndy Whitcroft $res .= $c; 12220a920b5bSAndy Whitcroft $n++; 12230a920b5bSAndy Whitcroft } 12240a920b5bSAndy Whitcroft 12250a920b5bSAndy Whitcroft return $res; 12260a920b5bSAndy Whitcroft} 12276c72ffaaSAndy Whitcroftsub copy_spacing { 1228773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 12296c72ffaaSAndy Whitcroft return $res; 12306c72ffaaSAndy Whitcroft} 12310a920b5bSAndy Whitcroft 12324a0df2efSAndy Whitcroftsub line_stats { 12334a0df2efSAndy Whitcroft my ($line) = @_; 12344a0df2efSAndy Whitcroft 12354a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 12364a0df2efSAndy Whitcroft $line =~ s/^.//; 12374a0df2efSAndy Whitcroft $line = expand_tabs($line); 12384a0df2efSAndy Whitcroft 12394a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 12404a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 12414a0df2efSAndy Whitcroft 12424a0df2efSAndy Whitcroft return (length($line), length($white)); 12434a0df2efSAndy Whitcroft} 12444a0df2efSAndy Whitcroft 1245773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1246773647a0SAndy Whitcroft 1247773647a0SAndy Whitcroftsub sanitise_line_reset { 1248773647a0SAndy Whitcroft my ($in_comment) = @_; 1249773647a0SAndy Whitcroft 1250773647a0SAndy Whitcroft if ($in_comment) { 1251773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1252773647a0SAndy Whitcroft } else { 1253773647a0SAndy Whitcroft $sanitise_quote = ''; 1254773647a0SAndy Whitcroft } 1255773647a0SAndy Whitcroft} 125600df344fSAndy Whitcroftsub sanitise_line { 125700df344fSAndy Whitcroft my ($line) = @_; 125800df344fSAndy Whitcroft 125900df344fSAndy Whitcroft my $res = ''; 126000df344fSAndy Whitcroft my $l = ''; 126100df344fSAndy Whitcroft 1262c2fdda0dSAndy Whitcroft my $qlen = 0; 1263773647a0SAndy Whitcroft my $off = 0; 1264773647a0SAndy Whitcroft my $c; 126500df344fSAndy Whitcroft 1266773647a0SAndy Whitcroft # Always copy over the diff marker. 1267773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1268773647a0SAndy Whitcroft 1269773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1270773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1271773647a0SAndy Whitcroft 12728d2e11b2SClaudio Fontana # Comments we are whacking completely including the begin 1273773647a0SAndy Whitcroft # and end, all to $;. 1274773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1275773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1276773647a0SAndy Whitcroft 1277773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1278773647a0SAndy Whitcroft $off++; 127900df344fSAndy Whitcroft next; 1280773647a0SAndy Whitcroft } 128181bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1282773647a0SAndy Whitcroft $sanitise_quote = ''; 1283773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1284773647a0SAndy Whitcroft $off++; 1285773647a0SAndy Whitcroft next; 1286773647a0SAndy Whitcroft } 1287113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1288113f04a8SDaniel Walker $sanitise_quote = '//'; 1289113f04a8SDaniel Walker 1290113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1291113f04a8SDaniel Walker $off++; 1292113f04a8SDaniel Walker next; 1293113f04a8SDaniel Walker } 1294773647a0SAndy Whitcroft 1295773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1296773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1297773647a0SAndy Whitcroft $c eq "\\") { 1298773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1299773647a0SAndy Whitcroft $off++; 1300773647a0SAndy Whitcroft next; 1301773647a0SAndy Whitcroft } 1302773647a0SAndy Whitcroft # Regular quotes. 1303773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1304773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1305773647a0SAndy Whitcroft $sanitise_quote = $c; 1306773647a0SAndy Whitcroft 1307773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1308773647a0SAndy Whitcroft next; 1309773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1310773647a0SAndy Whitcroft $sanitise_quote = ''; 131100df344fSAndy Whitcroft } 131200df344fSAndy Whitcroft } 1313773647a0SAndy Whitcroft 1314fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1315773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1316773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1317113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1318113f04a8SDaniel Walker substr($res, $off, 1, $;); 1319773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1320773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 132100df344fSAndy Whitcroft } else { 1322773647a0SAndy Whitcroft substr($res, $off, 1, $c); 132300df344fSAndy Whitcroft } 1324c2fdda0dSAndy Whitcroft } 1325c2fdda0dSAndy Whitcroft 1326113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1327113f04a8SDaniel Walker $sanitise_quote = ''; 1328113f04a8SDaniel Walker } 1329113f04a8SDaniel Walker 1330c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1331c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1332c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1333c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1334c2fdda0dSAndy Whitcroft 1335c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1336c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1337c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1338c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1339c2fdda0dSAndy Whitcroft } 1340c2fdda0dSAndy Whitcroft 1341dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1342dadf680dSJoe Perches my $match = $1; 1343dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1344dadf680dSJoe Perches } 1345dadf680dSJoe Perches 134600df344fSAndy Whitcroft return $res; 134700df344fSAndy Whitcroft} 134800df344fSAndy Whitcroft 1349a6962d72SJoe Perchessub get_quoted_string { 1350a6962d72SJoe Perches my ($line, $rawline) = @_; 1351a6962d72SJoe Perches 1352478b1799SJoe Perches return "" if (!defined($line) || !defined($rawline)); 135333acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1354a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1355a6962d72SJoe Perches} 1356a6962d72SJoe Perches 13578905a67cSAndy Whitcroftsub ctx_statement_block { 13588905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 13598905a67cSAndy Whitcroft my $line = $linenr - 1; 13608905a67cSAndy Whitcroft my $blk = ''; 13618905a67cSAndy Whitcroft my $soff = $off; 13628905a67cSAndy Whitcroft my $coff = $off - 1; 1363773647a0SAndy Whitcroft my $coff_set = 0; 13648905a67cSAndy Whitcroft 136513214adfSAndy Whitcroft my $loff = 0; 136613214adfSAndy Whitcroft 13678905a67cSAndy Whitcroft my $type = ''; 13688905a67cSAndy Whitcroft my $level = 0; 1369a2750645SAndy Whitcroft my @stack = (); 1370cf655043SAndy Whitcroft my $p; 13718905a67cSAndy Whitcroft my $c; 13728905a67cSAndy Whitcroft my $len = 0; 137313214adfSAndy Whitcroft 137413214adfSAndy Whitcroft my $remainder; 13758905a67cSAndy Whitcroft while (1) { 1376a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1377a2750645SAndy Whitcroft 1378773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 13798905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 13808905a67cSAndy Whitcroft # context. 13818905a67cSAndy Whitcroft if ($off >= $len) { 13828905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1383dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1384c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 13858905a67cSAndy Whitcroft $remain--; 138613214adfSAndy Whitcroft $loff = $len; 1387c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 13888905a67cSAndy Whitcroft $len = length($blk); 13898905a67cSAndy Whitcroft $line++; 13908905a67cSAndy Whitcroft last; 13918905a67cSAndy Whitcroft } 13928905a67cSAndy Whitcroft # Bail if there is no further context. 13938905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 139413214adfSAndy Whitcroft if ($off >= $len) { 13958905a67cSAndy Whitcroft last; 13968905a67cSAndy Whitcroft } 1397f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1398f74bd194SAndy Whitcroft $level++; 1399f74bd194SAndy Whitcroft $type = '#'; 1400f74bd194SAndy Whitcroft } 14018905a67cSAndy Whitcroft } 1402cf655043SAndy Whitcroft $p = $c; 14038905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 140413214adfSAndy Whitcroft $remainder = substr($blk, $off); 14058905a67cSAndy Whitcroft 1406773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 14074635f4fbSAndy Whitcroft 14084635f4fbSAndy Whitcroft # Handle nested #if/#else. 14094635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 14104635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 14114635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 14124635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 14134635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 14144635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 14154635f4fbSAndy Whitcroft } 14164635f4fbSAndy Whitcroft 14178905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 14188905a67cSAndy Whitcroft # outermost level. 14198905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 14208905a67cSAndy Whitcroft last; 14218905a67cSAndy Whitcroft } 14228905a67cSAndy Whitcroft 142313214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1424773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1425773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1426773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1427773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1428773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1429773647a0SAndy Whitcroft $coff_set = 1; 1430773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1431773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 143213214adfSAndy Whitcroft } 143313214adfSAndy Whitcroft 14348905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 14358905a67cSAndy Whitcroft $level++; 14368905a67cSAndy Whitcroft $type = '('; 14378905a67cSAndy Whitcroft } 14388905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 14398905a67cSAndy Whitcroft $level--; 14408905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 14418905a67cSAndy Whitcroft 14428905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 14438905a67cSAndy Whitcroft $coff = $off; 1444773647a0SAndy Whitcroft $coff_set = 1; 1445773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 14468905a67cSAndy Whitcroft } 14478905a67cSAndy Whitcroft } 14488905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 14498905a67cSAndy Whitcroft $level++; 14508905a67cSAndy Whitcroft $type = '{'; 14518905a67cSAndy Whitcroft } 14528905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 14538905a67cSAndy Whitcroft $level--; 14548905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 14558905a67cSAndy Whitcroft 14568905a67cSAndy Whitcroft if ($level == 0) { 1457b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1458b998e001SPatrick Pannuto $off++; 1459b998e001SPatrick Pannuto } 14608905a67cSAndy Whitcroft last; 14618905a67cSAndy Whitcroft } 14628905a67cSAndy Whitcroft } 1463f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1464f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1465f74bd194SAndy Whitcroft $level--; 1466f74bd194SAndy Whitcroft $type = ''; 1467f74bd194SAndy Whitcroft $off++; 1468f74bd194SAndy Whitcroft last; 1469f74bd194SAndy Whitcroft } 14708905a67cSAndy Whitcroft $off++; 14718905a67cSAndy Whitcroft } 1472a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 147313214adfSAndy Whitcroft if ($off == $len) { 1474a3bb97a7SAndy Whitcroft $loff = $len + 1; 147513214adfSAndy Whitcroft $line++; 147613214adfSAndy Whitcroft $remain--; 147713214adfSAndy Whitcroft } 14788905a67cSAndy Whitcroft 14798905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 14808905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 14818905a67cSAndy Whitcroft 14828905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 14838905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 14848905a67cSAndy Whitcroft 1485773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 148613214adfSAndy Whitcroft 148713214adfSAndy Whitcroft return ($statement, $condition, 148813214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 148913214adfSAndy Whitcroft} 149013214adfSAndy Whitcroft 1491cf655043SAndy Whitcroftsub statement_lines { 1492cf655043SAndy Whitcroft my ($stmt) = @_; 1493cf655043SAndy Whitcroft 1494cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1495cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1496cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1497cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1498cf655043SAndy Whitcroft 1499cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1500cf655043SAndy Whitcroft 1501cf655043SAndy Whitcroft return $#stmt_lines + 2; 1502cf655043SAndy Whitcroft} 1503cf655043SAndy Whitcroft 1504cf655043SAndy Whitcroftsub statement_rawlines { 1505cf655043SAndy Whitcroft my ($stmt) = @_; 1506cf655043SAndy Whitcroft 1507cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1508cf655043SAndy Whitcroft 1509cf655043SAndy Whitcroft return $#stmt_lines + 2; 1510cf655043SAndy Whitcroft} 1511cf655043SAndy Whitcroft 1512cf655043SAndy Whitcroftsub statement_block_size { 1513cf655043SAndy Whitcroft my ($stmt) = @_; 1514cf655043SAndy Whitcroft 1515cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1516cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1517cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1518cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1519cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1520cf655043SAndy Whitcroft 1521cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1522cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1523cf655043SAndy Whitcroft 1524cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1525cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1526cf655043SAndy Whitcroft 1527cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1528cf655043SAndy Whitcroft return $stmt_lines; 1529cf655043SAndy Whitcroft } else { 1530cf655043SAndy Whitcroft return $stmt_statements; 1531cf655043SAndy Whitcroft } 1532cf655043SAndy Whitcroft} 1533cf655043SAndy Whitcroft 153413214adfSAndy Whitcroftsub ctx_statement_full { 153513214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 153613214adfSAndy Whitcroft my ($statement, $condition, $level); 153713214adfSAndy Whitcroft 153813214adfSAndy Whitcroft my (@chunks); 153913214adfSAndy Whitcroft 1540cf655043SAndy Whitcroft # Grab the first conditional/block pair. 154113214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 154213214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1543773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 154413214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1545cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1546cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1547cf655043SAndy Whitcroft } 1548cf655043SAndy Whitcroft 1549cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1550cf655043SAndy Whitcroft # could continue the statement. 1551cf655043SAndy Whitcroft for (;;) { 155213214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 155313214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1554cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1555773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1556cf655043SAndy Whitcroft #print "C: push\n"; 1557cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 155813214adfSAndy Whitcroft } 155913214adfSAndy Whitcroft 156013214adfSAndy Whitcroft return ($level, $linenr, @chunks); 15618905a67cSAndy Whitcroft} 15628905a67cSAndy Whitcroft 15634a0df2efSAndy Whitcroftsub ctx_block_get { 1564f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 15654a0df2efSAndy Whitcroft my $line; 15664a0df2efSAndy Whitcroft my $start = $linenr - 1; 15674a0df2efSAndy Whitcroft my $blk = ''; 15684a0df2efSAndy Whitcroft my @o; 15694a0df2efSAndy Whitcroft my @c; 15704a0df2efSAndy Whitcroft my @res = (); 15714a0df2efSAndy Whitcroft 1572f0a594c1SAndy Whitcroft my $level = 0; 15734635f4fbSAndy Whitcroft my @stack = ($level); 157400df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 157500df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 157600df344fSAndy Whitcroft $remain--; 157700df344fSAndy Whitcroft 157800df344fSAndy Whitcroft $blk .= $rawlines[$line]; 15794635f4fbSAndy Whitcroft 15804635f4fbSAndy Whitcroft # Handle nested #if/#else. 158101464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 15824635f4fbSAndy Whitcroft push(@stack, $level); 158301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 15844635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 158501464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 15864635f4fbSAndy Whitcroft $level = pop(@stack); 15874635f4fbSAndy Whitcroft } 15884635f4fbSAndy Whitcroft 158901464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1590f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1591f0a594c1SAndy Whitcroft if ($off > 0) { 1592f0a594c1SAndy Whitcroft $off--; 1593f0a594c1SAndy Whitcroft next; 1594f0a594c1SAndy Whitcroft } 15954a0df2efSAndy Whitcroft 1596f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1597f0a594c1SAndy Whitcroft $level--; 1598f0a594c1SAndy Whitcroft last if ($level == 0); 1599f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1600f0a594c1SAndy Whitcroft $level++; 1601f0a594c1SAndy Whitcroft } 1602f0a594c1SAndy Whitcroft } 16034a0df2efSAndy Whitcroft 1604f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 160500df344fSAndy Whitcroft push(@res, $rawlines[$line]); 16064a0df2efSAndy Whitcroft } 16074a0df2efSAndy Whitcroft 1608f0a594c1SAndy Whitcroft last if ($level == 0); 16094a0df2efSAndy Whitcroft } 16104a0df2efSAndy Whitcroft 1611f0a594c1SAndy Whitcroft return ($level, @res); 16124a0df2efSAndy Whitcroft} 16134a0df2efSAndy Whitcroftsub ctx_block_outer { 16144a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 16154a0df2efSAndy Whitcroft 1616f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1617f0a594c1SAndy Whitcroft return @r; 16184a0df2efSAndy Whitcroft} 16194a0df2efSAndy Whitcroftsub ctx_block { 16204a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 16214a0df2efSAndy Whitcroft 1622f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1623f0a594c1SAndy Whitcroft return @r; 1624653d4876SAndy Whitcroft} 1625653d4876SAndy Whitcroftsub ctx_statement { 1626f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1627f0a594c1SAndy Whitcroft 1628f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1629f0a594c1SAndy Whitcroft return @r; 1630f0a594c1SAndy Whitcroft} 1631f0a594c1SAndy Whitcroftsub ctx_block_level { 1632653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1633653d4876SAndy Whitcroft 1634f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 16354a0df2efSAndy Whitcroft} 16369c0ca6f9SAndy Whitcroftsub ctx_statement_level { 16379c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 16389c0ca6f9SAndy Whitcroft 16399c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 16409c0ca6f9SAndy Whitcroft} 16414a0df2efSAndy Whitcroft 16424a0df2efSAndy Whitcroftsub ctx_locate_comment { 16434a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 16444a0df2efSAndy Whitcroft 16454a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1646beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 16474a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 16484a0df2efSAndy Whitcroft 16494a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 16504a0df2efSAndy Whitcroft # comment. 16514a0df2efSAndy Whitcroft my $in_comment = 0; 16524a0df2efSAndy Whitcroft $current_comment = ''; 16534a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 165400df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 165500df344fSAndy Whitcroft #warn " $line\n"; 16564a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 16574a0df2efSAndy Whitcroft $in_comment = 1; 16584a0df2efSAndy Whitcroft } 16594a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 16604a0df2efSAndy Whitcroft $in_comment = 1; 16614a0df2efSAndy Whitcroft } 16624a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 16634a0df2efSAndy Whitcroft $current_comment = ''; 16644a0df2efSAndy Whitcroft } 16654a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 16664a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 16674a0df2efSAndy Whitcroft $in_comment = 0; 16684a0df2efSAndy Whitcroft } 16694a0df2efSAndy Whitcroft } 16704a0df2efSAndy Whitcroft 16714a0df2efSAndy Whitcroft chomp($current_comment); 16724a0df2efSAndy Whitcroft return($current_comment); 16734a0df2efSAndy Whitcroft} 16744a0df2efSAndy Whitcroftsub ctx_has_comment { 16754a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 16764a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 16774a0df2efSAndy Whitcroft 167800df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 16794a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 16804a0df2efSAndy Whitcroft 16814a0df2efSAndy Whitcroft return ($cmt ne ''); 16824a0df2efSAndy Whitcroft} 16834a0df2efSAndy Whitcroft 16844d001e4dSAndy Whitcroftsub raw_line { 16854d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 16864d001e4dSAndy Whitcroft 16874d001e4dSAndy Whitcroft my $offset = $linenr - 1; 16884d001e4dSAndy Whitcroft $cnt++; 16894d001e4dSAndy Whitcroft 16904d001e4dSAndy Whitcroft my $line; 16914d001e4dSAndy Whitcroft while ($cnt) { 16924d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 16934d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 16944d001e4dSAndy Whitcroft $cnt--; 16954d001e4dSAndy Whitcroft } 16964d001e4dSAndy Whitcroft 16974d001e4dSAndy Whitcroft return $line; 16984d001e4dSAndy Whitcroft} 16994d001e4dSAndy Whitcroft 17002a9f9d85STobin C. Hardingsub get_stat_real { 17012a9f9d85STobin C. Harding my ($linenr, $lc) = @_; 17022a9f9d85STobin C. Harding 17032a9f9d85STobin C. Harding my $stat_real = raw_line($linenr, 0); 17042a9f9d85STobin C. Harding for (my $count = $linenr + 1; $count <= $lc; $count++) { 17052a9f9d85STobin C. Harding $stat_real = $stat_real . "\n" . raw_line($count, 0); 17062a9f9d85STobin C. Harding } 17072a9f9d85STobin C. Harding 17082a9f9d85STobin C. Harding return $stat_real; 17092a9f9d85STobin C. Harding} 17102a9f9d85STobin C. Harding 1711e3d95a2aSTobin C. Hardingsub get_stat_here { 1712e3d95a2aSTobin C. Harding my ($linenr, $cnt, $here) = @_; 1713e3d95a2aSTobin C. Harding 1714e3d95a2aSTobin C. Harding my $herectx = $here . "\n"; 1715e3d95a2aSTobin C. Harding for (my $n = 0; $n < $cnt; $n++) { 1716e3d95a2aSTobin C. Harding $herectx .= raw_line($linenr, $n) . "\n"; 1717e3d95a2aSTobin C. Harding } 1718e3d95a2aSTobin C. Harding 1719e3d95a2aSTobin C. Harding return $herectx; 1720e3d95a2aSTobin C. Harding} 1721e3d95a2aSTobin C. Harding 17220a920b5bSAndy Whitcroftsub cat_vet { 17230a920b5bSAndy Whitcroft my ($vet) = @_; 17249c0ca6f9SAndy Whitcroft my ($res, $coded); 17250a920b5bSAndy Whitcroft 17269c0ca6f9SAndy Whitcroft $res = ''; 17276c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 17286c72ffaaSAndy Whitcroft $res .= $1; 17296c72ffaaSAndy Whitcroft if ($2 ne '') { 17309c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 17316c72ffaaSAndy Whitcroft $res .= $coded; 17326c72ffaaSAndy Whitcroft } 17339c0ca6f9SAndy Whitcroft } 17349c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 17350a920b5bSAndy Whitcroft 17369c0ca6f9SAndy Whitcroft return $res; 17370a920b5bSAndy Whitcroft} 17380a920b5bSAndy Whitcroft 1739c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1740cf655043SAndy Whitcroftmy $av_pending; 1741c2fdda0dSAndy Whitcroftmy @av_paren_type; 17421f65f947SAndy Whitcroftmy $av_pend_colon; 1743c2fdda0dSAndy Whitcroft 1744c2fdda0dSAndy Whitcroftsub annotate_reset { 1745c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1746cf655043SAndy Whitcroft $av_pending = '_'; 1747cf655043SAndy Whitcroft @av_paren_type = ('E'); 17481f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1749c2fdda0dSAndy Whitcroft} 1750c2fdda0dSAndy Whitcroft 17516c72ffaaSAndy Whitcroftsub annotate_values { 17526c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 17536c72ffaaSAndy Whitcroft 17546c72ffaaSAndy Whitcroft my $res; 17551f65f947SAndy Whitcroft my $var = '_' x length($stream); 17566c72ffaaSAndy Whitcroft my $cur = $stream; 17576c72ffaaSAndy Whitcroft 1758c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 17596c72ffaaSAndy Whitcroft 17606c72ffaaSAndy Whitcroft while (length($cur)) { 1761773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1762cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1763171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 17646c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1765c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1766c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1767cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1768c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 17696c72ffaaSAndy Whitcroft } 17706c72ffaaSAndy Whitcroft 1771c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 17729446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 17739446ef56SAndy Whitcroft push(@av_paren_type, $type); 1774addcdceaSAndy Whitcroft $type = 'c'; 17759446ef56SAndy Whitcroft 1776e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1777c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 17786c72ffaaSAndy Whitcroft $type = 'T'; 17796c72ffaaSAndy Whitcroft 1780389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1781389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1782389a2fe5SAndy Whitcroft $type = 'T'; 1783389a2fe5SAndy Whitcroft 1784c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1785171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1786c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1787171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1788171ae1a4SAndy Whitcroft if ($2 ne '') { 1789cf655043SAndy Whitcroft $av_pending = 'N'; 1790171ae1a4SAndy Whitcroft } 1791171ae1a4SAndy Whitcroft $type = 'E'; 1792171ae1a4SAndy Whitcroft 1793c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1794171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1795171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1796171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 17976c72ffaaSAndy Whitcroft 1798c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1799cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1800c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1801cf655043SAndy Whitcroft 1802cf655043SAndy Whitcroft push(@av_paren_type, $type); 1803cf655043SAndy Whitcroft push(@av_paren_type, $type); 1804171ae1a4SAndy Whitcroft $type = 'E'; 1805cf655043SAndy Whitcroft 1806c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1807cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1808cf655043SAndy Whitcroft $av_preprocessor = 1; 1809cf655043SAndy Whitcroft 1810cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1811cf655043SAndy Whitcroft 1812171ae1a4SAndy Whitcroft $type = 'E'; 1813cf655043SAndy Whitcroft 1814c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1815cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1816cf655043SAndy Whitcroft 1817cf655043SAndy Whitcroft $av_preprocessor = 1; 1818cf655043SAndy Whitcroft 1819cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1820cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1821cf655043SAndy Whitcroft pop(@av_paren_type); 1822cf655043SAndy Whitcroft push(@av_paren_type, $type); 1823171ae1a4SAndy Whitcroft $type = 'E'; 18246c72ffaaSAndy Whitcroft 18256c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1826c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 18276c72ffaaSAndy Whitcroft 1828171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1829171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1830171ae1a4SAndy Whitcroft $av_pending = $type; 1831171ae1a4SAndy Whitcroft $type = 'N'; 1832171ae1a4SAndy Whitcroft 18336c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1834c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 18356c72ffaaSAndy Whitcroft if (defined $2) { 1836cf655043SAndy Whitcroft $av_pending = 'V'; 18376c72ffaaSAndy Whitcroft } 18386c72ffaaSAndy Whitcroft $type = 'N'; 18396c72ffaaSAndy Whitcroft 184014b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1841c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 184214b111c1SAndy Whitcroft $av_pending = 'E'; 18436c72ffaaSAndy Whitcroft $type = 'N'; 18446c72ffaaSAndy Whitcroft 18451f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 18461f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 18471f65f947SAndy Whitcroft $av_pend_colon = 'C'; 18481f65f947SAndy Whitcroft $type = 'N'; 18491f65f947SAndy Whitcroft 185014b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1851c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 18526c72ffaaSAndy Whitcroft $type = 'N'; 18536c72ffaaSAndy Whitcroft 18546c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1855c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1856cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1857cf655043SAndy Whitcroft $av_pending = '_'; 18586c72ffaaSAndy Whitcroft $type = 'N'; 18596c72ffaaSAndy Whitcroft 18606c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1861cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1862cf655043SAndy Whitcroft if ($new_type ne '_') { 1863cf655043SAndy Whitcroft $type = $new_type; 1864c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1865c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 18666c72ffaaSAndy Whitcroft } else { 1867c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 18686c72ffaaSAndy Whitcroft } 18696c72ffaaSAndy Whitcroft 1870c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1871c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1872c8cb2ca3SAndy Whitcroft $type = 'V'; 1873cf655043SAndy Whitcroft $av_pending = 'V'; 18746c72ffaaSAndy Whitcroft 18758e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 18768e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 18771f65f947SAndy Whitcroft $av_pend_colon = 'B'; 18788e761b04SAndy Whitcroft } elsif ($type eq 'E') { 18798e761b04SAndy Whitcroft $av_pend_colon = 'L'; 18801f65f947SAndy Whitcroft } 18811f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 18821f65f947SAndy Whitcroft $type = 'V'; 18831f65f947SAndy Whitcroft 18846c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1885c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 18866c72ffaaSAndy Whitcroft $type = 'V'; 18876c72ffaaSAndy Whitcroft 18886c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1889c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 18906c72ffaaSAndy Whitcroft $type = 'N'; 18916c72ffaaSAndy Whitcroft 1892cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1893c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 189413214adfSAndy Whitcroft $type = 'E'; 18951f65f947SAndy Whitcroft $av_pend_colon = 'O'; 189613214adfSAndy Whitcroft 18978e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 18988e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 18998e761b04SAndy Whitcroft $type = 'C'; 19008e761b04SAndy Whitcroft 19011f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 19021f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 19031f65f947SAndy Whitcroft $type = 'N'; 19041f65f947SAndy Whitcroft 19051f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 19061f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 19071f65f947SAndy Whitcroft 19081f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 19091f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 19101f65f947SAndy Whitcroft $type = 'E'; 19111f65f947SAndy Whitcroft } else { 19121f65f947SAndy Whitcroft $type = 'N'; 19131f65f947SAndy Whitcroft } 19141f65f947SAndy Whitcroft $av_pend_colon = 'O'; 19151f65f947SAndy Whitcroft 19168e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 191713214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 19186c72ffaaSAndy Whitcroft $type = 'N'; 19196c72ffaaSAndy Whitcroft 19200d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 192174048ed8SAndy Whitcroft my $variant; 192274048ed8SAndy Whitcroft 192374048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 192474048ed8SAndy Whitcroft if ($type eq 'V') { 192574048ed8SAndy Whitcroft $variant = 'B'; 192674048ed8SAndy Whitcroft } else { 192774048ed8SAndy Whitcroft $variant = 'U'; 192874048ed8SAndy Whitcroft } 192974048ed8SAndy Whitcroft 193074048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 193174048ed8SAndy Whitcroft $type = 'N'; 193274048ed8SAndy Whitcroft 19336c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1934c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 19356c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 19366c72ffaaSAndy Whitcroft $type = 'N'; 19376c72ffaaSAndy Whitcroft } 19386c72ffaaSAndy Whitcroft 19396c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1940c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 19416c72ffaaSAndy Whitcroft } 19426c72ffaaSAndy Whitcroft if (defined $1) { 19436c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 19446c72ffaaSAndy Whitcroft $res .= $type x length($1); 19456c72ffaaSAndy Whitcroft } 19466c72ffaaSAndy Whitcroft } 19476c72ffaaSAndy Whitcroft 19481f65f947SAndy Whitcroft return ($res, $var); 19496c72ffaaSAndy Whitcroft} 19506c72ffaaSAndy Whitcroft 19518905a67cSAndy Whitcroftsub possible { 195213214adfSAndy Whitcroft my ($possible, $line) = @_; 19539a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 19540776e594SAndy Whitcroft ^(?: 19550776e594SAndy Whitcroft $Modifier| 19560776e594SAndy Whitcroft $Storage| 19570776e594SAndy Whitcroft $Type| 19589a974fdbSAndy Whitcroft DEFINE_\S+ 19599a974fdbSAndy Whitcroft )$| 19609a974fdbSAndy Whitcroft ^(?: 19610776e594SAndy Whitcroft goto| 19620776e594SAndy Whitcroft return| 19630776e594SAndy Whitcroft case| 19640776e594SAndy Whitcroft else| 19650776e594SAndy Whitcroft asm|__asm__| 196689a88353SAndy Whitcroft do| 196789a88353SAndy Whitcroft \#| 196889a88353SAndy Whitcroft \#\#| 19699a974fdbSAndy Whitcroft )(?:\s|$)| 19700776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 19719a974fdbSAndy Whitcroft )}x; 19729a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 19739a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1974c45dcabdSAndy Whitcroft # Check for modifiers. 1975c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1976c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1977c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1978c45dcabdSAndy Whitcroft 1979c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1980c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1981d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 19829a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1983d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1984485ff23eSAlex Dowad push(@modifierListFile, $modifier); 1985d2506586SAndy Whitcroft } 19869a974fdbSAndy Whitcroft } 1987c45dcabdSAndy Whitcroft 1988c45dcabdSAndy Whitcroft } else { 198913214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1990485ff23eSAlex Dowad push(@typeListFile, $possible); 1991c45dcabdSAndy Whitcroft } 19928905a67cSAndy Whitcroft build_types(); 19930776e594SAndy Whitcroft } else { 19940776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 19958905a67cSAndy Whitcroft } 19968905a67cSAndy Whitcroft} 19978905a67cSAndy Whitcroft 19986c72ffaaSAndy Whitcroftmy $prefix = ''; 19996c72ffaaSAndy Whitcroft 2000000d1cc1SJoe Perchessub show_type { 2001cbec18afSJoe Perches my ($type) = @_; 200291bfe484SJoe Perches 2003522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 2004522b837cSAlexey Dobriyan 2005cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 2006cbec18afSJoe Perches 2007cbec18afSJoe Perches return !defined $ignore_type{$type}; 2008000d1cc1SJoe Perches} 2009000d1cc1SJoe Perches 2010f0a594c1SAndy Whitcroftsub report { 2011cbec18afSJoe Perches my ($level, $type, $msg) = @_; 2012cbec18afSJoe Perches 2013cbec18afSJoe Perches if (!show_type($type) || 2014cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 2015773647a0SAndy Whitcroft return 0; 2016773647a0SAndy Whitcroft } 201757230297SJoe Perches my $output = ''; 2018737c0767SJohn Brooks if ($color) { 201957230297SJoe Perches if ($level eq 'ERROR') { 202057230297SJoe Perches $output .= RED; 202157230297SJoe Perches } elsif ($level eq 'WARNING') { 202257230297SJoe Perches $output .= YELLOW; 2023000d1cc1SJoe Perches } else { 202457230297SJoe Perches $output .= GREEN; 2025000d1cc1SJoe Perches } 202657230297SJoe Perches } 202757230297SJoe Perches $output .= $prefix . $level . ':'; 202857230297SJoe Perches if ($show_types) { 2029737c0767SJohn Brooks $output .= BLUE if ($color); 203057230297SJoe Perches $output .= "$type:"; 203157230297SJoe Perches } 2032737c0767SJohn Brooks $output .= RESET if ($color); 203357230297SJoe Perches $output .= ' ' . $msg . "\n"; 203434d8815fSJoe Perches 203534d8815fSJoe Perches if ($showfile) { 203634d8815fSJoe Perches my @lines = split("\n", $output, -1); 203734d8815fSJoe Perches splice(@lines, 1, 1); 203834d8815fSJoe Perches $output = join("\n", @lines); 203934d8815fSJoe Perches } 204057230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 20418905a67cSAndy Whitcroft 204257230297SJoe Perches push(our @report, $output); 2043773647a0SAndy Whitcroft 2044773647a0SAndy Whitcroft return 1; 2045f0a594c1SAndy Whitcroft} 2046cbec18afSJoe Perches 2047f0a594c1SAndy Whitcroftsub report_dump { 204813214adfSAndy Whitcroft our @report; 2049f0a594c1SAndy Whitcroft} 2050000d1cc1SJoe Perches 2051d752fcc8SJoe Perchessub fixup_current_range { 2052d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 2053d752fcc8SJoe Perches 2054d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 2055d752fcc8SJoe Perches my $o = $1; 2056d752fcc8SJoe Perches my $l = $2; 2057d752fcc8SJoe Perches my $no = $o + $offset; 2058d752fcc8SJoe Perches my $nl = $l + $length; 2059d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 2060d752fcc8SJoe Perches } 2061d752fcc8SJoe Perches} 2062d752fcc8SJoe Perches 2063d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 2064d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 2065d752fcc8SJoe Perches 2066d752fcc8SJoe Perches my $range_last_linenr = 0; 2067d752fcc8SJoe Perches my $delta_offset = 0; 2068d752fcc8SJoe Perches 2069d752fcc8SJoe Perches my $old_linenr = 0; 2070d752fcc8SJoe Perches my $new_linenr = 0; 2071d752fcc8SJoe Perches 2072d752fcc8SJoe Perches my $next_insert = 0; 2073d752fcc8SJoe Perches my $next_delete = 0; 2074d752fcc8SJoe Perches 2075d752fcc8SJoe Perches my @lines = (); 2076d752fcc8SJoe Perches 2077d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 2078d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 2079d752fcc8SJoe Perches 2080d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 2081d752fcc8SJoe Perches my $save_line = 1; 2082d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 2083323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 2084d752fcc8SJoe Perches $delta_offset = 0; 2085d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 2086d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 2087d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 2088d752fcc8SJoe Perches } 2089d752fcc8SJoe Perches 2090d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 2091d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 2092d752fcc8SJoe Perches $save_line = 0; 2093d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 2094d752fcc8SJoe Perches } 2095d752fcc8SJoe Perches 2096d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 2097d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 2098d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 2099d752fcc8SJoe Perches $new_linenr++; 2100d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 2101d752fcc8SJoe Perches } 2102d752fcc8SJoe Perches 2103d752fcc8SJoe Perches if ($save_line) { 2104d752fcc8SJoe Perches push(@lines, $line); 2105d752fcc8SJoe Perches $new_linenr++; 2106d752fcc8SJoe Perches } 2107d752fcc8SJoe Perches 2108d752fcc8SJoe Perches $old_linenr++; 2109d752fcc8SJoe Perches } 2110d752fcc8SJoe Perches 2111d752fcc8SJoe Perches return @lines; 2112d752fcc8SJoe Perches} 2113d752fcc8SJoe Perches 2114f2d7e4d4SJoe Perchessub fix_insert_line { 2115f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2116f2d7e4d4SJoe Perches 2117f2d7e4d4SJoe Perches my $inserted = { 2118f2d7e4d4SJoe Perches LINENR => $linenr, 2119f2d7e4d4SJoe Perches LINE => $line, 2120f2d7e4d4SJoe Perches }; 2121f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 2122f2d7e4d4SJoe Perches} 2123f2d7e4d4SJoe Perches 2124f2d7e4d4SJoe Perchessub fix_delete_line { 2125f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 2126f2d7e4d4SJoe Perches 2127f2d7e4d4SJoe Perches my $deleted = { 2128f2d7e4d4SJoe Perches LINENR => $linenr, 2129f2d7e4d4SJoe Perches LINE => $line, 2130f2d7e4d4SJoe Perches }; 2131f2d7e4d4SJoe Perches 2132f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2133f2d7e4d4SJoe Perches} 2134f2d7e4d4SJoe Perches 2135de7d4f0eSAndy Whitcroftsub ERROR { 2136cbec18afSJoe Perches my ($type, $msg) = @_; 2137cbec18afSJoe Perches 2138cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2139de7d4f0eSAndy Whitcroft our $clean = 0; 21406c72ffaaSAndy Whitcroft our $cnt_error++; 21413705ce5bSJoe Perches return 1; 2142de7d4f0eSAndy Whitcroft } 21433705ce5bSJoe Perches return 0; 2144773647a0SAndy Whitcroft} 2145de7d4f0eSAndy Whitcroftsub WARN { 2146cbec18afSJoe Perches my ($type, $msg) = @_; 2147cbec18afSJoe Perches 2148cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2149de7d4f0eSAndy Whitcroft our $clean = 0; 21506c72ffaaSAndy Whitcroft our $cnt_warn++; 21513705ce5bSJoe Perches return 1; 2152de7d4f0eSAndy Whitcroft } 21533705ce5bSJoe Perches return 0; 2154773647a0SAndy Whitcroft} 2155de7d4f0eSAndy Whitcroftsub CHK { 2156cbec18afSJoe Perches my ($type, $msg) = @_; 2157cbec18afSJoe Perches 2158cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2159de7d4f0eSAndy Whitcroft our $clean = 0; 21606c72ffaaSAndy Whitcroft our $cnt_chk++; 21613705ce5bSJoe Perches return 1; 21626c72ffaaSAndy Whitcroft } 21633705ce5bSJoe Perches return 0; 2164de7d4f0eSAndy Whitcroft} 2165de7d4f0eSAndy Whitcroft 21666ecd9674SAndy Whitcroftsub check_absolute_file { 21676ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 21686ecd9674SAndy Whitcroft my $file = $absolute; 21696ecd9674SAndy Whitcroft 21706ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 21716ecd9674SAndy Whitcroft 21726ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 21736ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 21746ecd9674SAndy Whitcroft if (-f "$root/$file") { 21756ecd9674SAndy Whitcroft ##print "file<$file>\n"; 21766ecd9674SAndy Whitcroft last; 21776ecd9674SAndy Whitcroft } 21786ecd9674SAndy Whitcroft } 21796ecd9674SAndy Whitcroft if (! -f _) { 21806ecd9674SAndy Whitcroft return 0; 21816ecd9674SAndy Whitcroft } 21826ecd9674SAndy Whitcroft 21836ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 21846ecd9674SAndy Whitcroft my $prefix = $absolute; 21856ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 21866ecd9674SAndy Whitcroft 21876ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 21886ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2189000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2190000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 21916ecd9674SAndy Whitcroft } 21926ecd9674SAndy Whitcroft} 21936ecd9674SAndy Whitcroft 21943705ce5bSJoe Perchessub trim { 21953705ce5bSJoe Perches my ($string) = @_; 21963705ce5bSJoe Perches 2197b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2198b34c648bSJoe Perches 2199b34c648bSJoe Perches return $string; 2200b34c648bSJoe Perches} 2201b34c648bSJoe Perches 2202b34c648bSJoe Perchessub ltrim { 2203b34c648bSJoe Perches my ($string) = @_; 2204b34c648bSJoe Perches 2205b34c648bSJoe Perches $string =~ s/^\s+//; 2206b34c648bSJoe Perches 2207b34c648bSJoe Perches return $string; 2208b34c648bSJoe Perches} 2209b34c648bSJoe Perches 2210b34c648bSJoe Perchessub rtrim { 2211b34c648bSJoe Perches my ($string) = @_; 2212b34c648bSJoe Perches 2213b34c648bSJoe Perches $string =~ s/\s+$//; 22143705ce5bSJoe Perches 22153705ce5bSJoe Perches return $string; 22163705ce5bSJoe Perches} 22173705ce5bSJoe Perches 221852ea8506SJoe Perchessub string_find_replace { 221952ea8506SJoe Perches my ($string, $find, $replace) = @_; 222052ea8506SJoe Perches 222152ea8506SJoe Perches $string =~ s/$find/$replace/g; 222252ea8506SJoe Perches 222352ea8506SJoe Perches return $string; 222452ea8506SJoe Perches} 222552ea8506SJoe Perches 22263705ce5bSJoe Perchessub tabify { 22273705ce5bSJoe Perches my ($leading) = @_; 22283705ce5bSJoe Perches 22293705ce5bSJoe Perches my $source_indent = 8; 22303705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 22313705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 22323705ce5bSJoe Perches 22333705ce5bSJoe Perches #convert leading spaces to tabs 22343705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 22353705ce5bSJoe Perches #Remove spaces before a tab 22363705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 22373705ce5bSJoe Perches 22383705ce5bSJoe Perches return "$leading"; 22393705ce5bSJoe Perches} 22403705ce5bSJoe Perches 2241d1fe9c09SJoe Perchessub pos_last_openparen { 2242d1fe9c09SJoe Perches my ($line) = @_; 2243d1fe9c09SJoe Perches 2244d1fe9c09SJoe Perches my $pos = 0; 2245d1fe9c09SJoe Perches 2246d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2247d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2248d1fe9c09SJoe Perches 2249d1fe9c09SJoe Perches my $last_openparen = 0; 2250d1fe9c09SJoe Perches 2251d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2252d1fe9c09SJoe Perches return -1; 2253d1fe9c09SJoe Perches } 2254d1fe9c09SJoe Perches 2255d1fe9c09SJoe Perches my $len = length($line); 2256d1fe9c09SJoe Perches 2257d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2258d1fe9c09SJoe Perches my $string = substr($line, $pos); 2259d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2260d1fe9c09SJoe Perches $pos += length($1) - 1; 2261d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2262d1fe9c09SJoe Perches $last_openparen = $pos; 2263d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2264d1fe9c09SJoe Perches last; 2265d1fe9c09SJoe Perches } 2266d1fe9c09SJoe Perches } 2267d1fe9c09SJoe Perches 226891cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2269d1fe9c09SJoe Perches} 2270d1fe9c09SJoe Perches 22710a920b5bSAndy Whitcroftsub process { 22720a920b5bSAndy Whitcroft my $filename = shift; 22730a920b5bSAndy Whitcroft 22740a920b5bSAndy Whitcroft my $linenr=0; 22750a920b5bSAndy Whitcroft my $prevline=""; 2276c2fdda0dSAndy Whitcroft my $prevrawline=""; 22770a920b5bSAndy Whitcroft my $stashline=""; 2278c2fdda0dSAndy Whitcroft my $stashrawline=""; 22790a920b5bSAndy Whitcroft 22804a0df2efSAndy Whitcroft my $length; 22810a920b5bSAndy Whitcroft my $indent; 22820a920b5bSAndy Whitcroft my $previndent=0; 22830a920b5bSAndy Whitcroft my $stashindent=0; 22840a920b5bSAndy Whitcroft 2285de7d4f0eSAndy Whitcroft our $clean = 1; 22860a920b5bSAndy Whitcroft my $signoff = 0; 2287cd261496SGeert Uytterhoeven my $author = ''; 2288cd261496SGeert Uytterhoeven my $authorsignoff = 0; 22890a920b5bSAndy Whitcroft my $is_patch = 0; 2290133712a2SRob Herring my $is_binding_patch = -1; 229129ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 229215662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 2293ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2294490b292cSJoe Perches my $commit_log_lines = 0; #Number of commit log lines 2295bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 22962a076f40SJoe Perches my $commit_log_long_line = 0; 2297e518e9a5SJoe Perches my $commit_log_has_diff = 0; 229813f1937eSJoe Perches my $reported_maintainer_file = 0; 2299fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2300fa64205dSPasi Savanainen 2301365dd4eaSJoe Perches my $last_blank_line = 0; 23025e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2303365dd4eaSJoe Perches 230413214adfSAndy Whitcroft our @report = (); 23056c72ffaaSAndy Whitcroft our $cnt_lines = 0; 23066c72ffaaSAndy Whitcroft our $cnt_error = 0; 23076c72ffaaSAndy Whitcroft our $cnt_warn = 0; 23086c72ffaaSAndy Whitcroft our $cnt_chk = 0; 23096c72ffaaSAndy Whitcroft 23100a920b5bSAndy Whitcroft # Trace the real file/line as we go. 23110a920b5bSAndy Whitcroft my $realfile = ''; 23120a920b5bSAndy Whitcroft my $realline = 0; 23130a920b5bSAndy Whitcroft my $realcnt = 0; 23140a920b5bSAndy Whitcroft my $here = ''; 231577cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 23160a920b5bSAndy Whitcroft my $in_comment = 0; 2317c2fdda0dSAndy Whitcroft my $comment_edge = 0; 23180a920b5bSAndy Whitcroft my $first_line = 0; 23191e855726SWolfram Sang my $p1_prefix = ''; 23200a920b5bSAndy Whitcroft 232113214adfSAndy Whitcroft my $prev_values = 'E'; 232213214adfSAndy Whitcroft 232313214adfSAndy Whitcroft # suppression flags 2324773647a0SAndy Whitcroft my %suppress_ifbraces; 2325170d3a22SAndy Whitcroft my %suppress_whiletrailers; 23262b474a1aSAndy Whitcroft my %suppress_export; 23273e469cdcSAndy Whitcroft my $suppress_statement = 0; 2328653d4876SAndy Whitcroft 23297e51f197SJoe Perches my %signatures = (); 2330323c1260SJoe Perches 2331c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2332de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2333c2fdda0dSAndy Whitcroft # 2334de7d4f0eSAndy Whitcroft my @setup_docs = (); 2335de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2336773647a0SAndy Whitcroft 2337d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2338d8b07710SJoe Perches 23399f3a8992SRob Herring my $checklicenseline = 1; 23409f3a8992SRob Herring 2341773647a0SAndy Whitcroft sanitise_line_reset(); 2342c2fdda0dSAndy Whitcroft my $line; 2343c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2344773647a0SAndy Whitcroft $linenr++; 2345773647a0SAndy Whitcroft $line = $rawline; 2346c2fdda0dSAndy Whitcroft 23473705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 23483705ce5bSJoe Perches 2349773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2350de7d4f0eSAndy Whitcroft $setup_docs = 0; 23518c27ceffSMauro Carvalho Chehab if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2352de7d4f0eSAndy Whitcroft $setup_docs = 1; 2353de7d4f0eSAndy Whitcroft } 2354773647a0SAndy Whitcroft #next; 2355de7d4f0eSAndy Whitcroft } 235674fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2357773647a0SAndy Whitcroft $realline=$1-1; 2358773647a0SAndy Whitcroft if (defined $2) { 2359773647a0SAndy Whitcroft $realcnt=$3+1; 2360773647a0SAndy Whitcroft } else { 2361773647a0SAndy Whitcroft $realcnt=1+1; 2362773647a0SAndy Whitcroft } 2363c45dcabdSAndy Whitcroft $in_comment = 0; 2364773647a0SAndy Whitcroft 2365773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2366773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2367773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2368773647a0SAndy Whitcroft # at context start. 2369773647a0SAndy Whitcroft my $edge; 237001fa9147SAndy Whitcroft my $cnt = $realcnt; 237101fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 237201fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 237301fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 237401fa9147SAndy Whitcroft $cnt--; 237501fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2376721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2377fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2378fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2379fae17daeSAndy Whitcroft ($edge) = $1; 2380fae17daeSAndy Whitcroft last; 2381fae17daeSAndy Whitcroft } 2382773647a0SAndy Whitcroft } 2383773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2384773647a0SAndy Whitcroft $in_comment = 1; 2385773647a0SAndy Whitcroft } 2386773647a0SAndy Whitcroft 2387773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2388773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2389773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2390773647a0SAndy Whitcroft if (!defined $edge && 239183242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2392773647a0SAndy Whitcroft { 2393773647a0SAndy Whitcroft $in_comment = 1; 2394773647a0SAndy Whitcroft } 2395773647a0SAndy Whitcroft 2396773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2397773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2398773647a0SAndy Whitcroft 2399171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2400773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2401171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2402773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2403773647a0SAndy Whitcroft } 2404773647a0SAndy Whitcroft push(@lines, $line); 2405773647a0SAndy Whitcroft 2406773647a0SAndy Whitcroft if ($realcnt > 1) { 2407773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2408773647a0SAndy Whitcroft } else { 2409773647a0SAndy Whitcroft $realcnt = 0; 2410773647a0SAndy Whitcroft } 2411773647a0SAndy Whitcroft 2412773647a0SAndy Whitcroft #print "==>$rawline\n"; 2413773647a0SAndy Whitcroft #print "-->$line\n"; 2414de7d4f0eSAndy Whitcroft 2415de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2416de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2417de7d4f0eSAndy Whitcroft } 2418de7d4f0eSAndy Whitcroft } 2419de7d4f0eSAndy Whitcroft 24206c72ffaaSAndy Whitcroft $prefix = ''; 24216c72ffaaSAndy Whitcroft 2422773647a0SAndy Whitcroft $realcnt = 0; 2423773647a0SAndy Whitcroft $linenr = 0; 2424194f66fcSJoe Perches $fixlinenr = -1; 24250a920b5bSAndy Whitcroft foreach my $line (@lines) { 24260a920b5bSAndy Whitcroft $linenr++; 2427194f66fcSJoe Perches $fixlinenr++; 24281b5539b1SJoe Perches my $sline = $line; #copy of $line 24291b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 24300a920b5bSAndy Whitcroft 2431c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 24326c72ffaaSAndy Whitcroft 243312c253abSJoe Perches# check if it's a mode change, rename or start of a patch 243412c253abSJoe Perches if (!$in_commit_log && 243512c253abSJoe Perches ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || 243612c253abSJoe Perches ($line =~ /^rename (?:from|to) \S+\s*$/ || 243712c253abSJoe Perches $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { 243812c253abSJoe Perches $is_patch = 1; 243912c253abSJoe Perches } 244012c253abSJoe Perches 24410a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2442e518e9a5SJoe Perches if (!$in_commit_log && 244374fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 244474fd4f34SJoe Perches my $context = $4; 24450a920b5bSAndy Whitcroft $is_patch = 1; 24464a0df2efSAndy Whitcroft $first_line = $linenr + 1; 24470a920b5bSAndy Whitcroft $realline=$1-1; 24480a920b5bSAndy Whitcroft if (defined $2) { 24490a920b5bSAndy Whitcroft $realcnt=$3+1; 24500a920b5bSAndy Whitcroft } else { 24510a920b5bSAndy Whitcroft $realcnt=1+1; 24520a920b5bSAndy Whitcroft } 2453c2fdda0dSAndy Whitcroft annotate_reset(); 245413214adfSAndy Whitcroft $prev_values = 'E'; 245513214adfSAndy Whitcroft 2456773647a0SAndy Whitcroft %suppress_ifbraces = (); 2457170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 24582b474a1aSAndy Whitcroft %suppress_export = (); 24593e469cdcSAndy Whitcroft $suppress_statement = 0; 246074fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 246174fd4f34SJoe Perches $context_function = $1; 246274fd4f34SJoe Perches } else { 246374fd4f34SJoe Perches undef $context_function; 246474fd4f34SJoe Perches } 24650a920b5bSAndy Whitcroft next; 24660a920b5bSAndy Whitcroft 24674a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 24684a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 24694a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2470773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 24710a920b5bSAndy Whitcroft $realline++; 2472d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 24730a920b5bSAndy Whitcroft 24744a0df2efSAndy Whitcroft # Measure the line length and indent. 2475c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 24760a920b5bSAndy Whitcroft 24770a920b5bSAndy Whitcroft # Track the previous line. 24780a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 24790a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2480c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2481c2fdda0dSAndy Whitcroft 2482773647a0SAndy Whitcroft #warn "line<$line>\n"; 24836c72ffaaSAndy Whitcroft 2484d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2485d8aaf121SAndy Whitcroft $realcnt--; 24860a920b5bSAndy Whitcroft } 24870a920b5bSAndy Whitcroft 2488cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2489cc77cdcaSAndy Whitcroft 24906c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 24916c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2492773647a0SAndy Whitcroft 24932ac73b4fSJoe Perches my $found_file = 0; 2494773647a0SAndy Whitcroft # extract the filename as it passes 24953bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 24963bf9a009SRabin Vincent $realfile = $1; 24972b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2498270c49a0SJoe Perches $in_commit_log = 0; 24992ac73b4fSJoe Perches $found_file = 1; 25003bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2501773647a0SAndy Whitcroft $realfile = $1; 25022b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2503270c49a0SJoe Perches $in_commit_log = 0; 25041e855726SWolfram Sang 25051e855726SWolfram Sang $p1_prefix = $1; 2506e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2507e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2508000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2509000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 25101e855726SWolfram Sang } 2511773647a0SAndy Whitcroft 2512c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2513000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2514000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2515773647a0SAndy Whitcroft } 25162ac73b4fSJoe Perches $found_file = 1; 25172ac73b4fSJoe Perches } 25182ac73b4fSJoe Perches 251934d8815fSJoe Perches#make up the handle for any error we report on this line 252034d8815fSJoe Perches if ($showfile) { 252134d8815fSJoe Perches $prefix = "$realfile:$realline: " 252234d8815fSJoe Perches } elsif ($emacs) { 25237d3a9f67SJoe Perches if ($file) { 25247d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 25257d3a9f67SJoe Perches } else { 252634d8815fSJoe Perches $prefix = "$filename:$linenr: "; 252734d8815fSJoe Perches } 25287d3a9f67SJoe Perches } 252934d8815fSJoe Perches 25302ac73b4fSJoe Perches if ($found_file) { 253185b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 253285b0ee18SJoe Perches WARN("OBSOLETE", 253385b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 253485b0ee18SJoe Perches } 25357bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 25362ac73b4fSJoe Perches $check = 1; 25372ac73b4fSJoe Perches } else { 25382ac73b4fSJoe Perches $check = $check_orig; 25392ac73b4fSJoe Perches } 25409f3a8992SRob Herring $checklicenseline = 1; 2541133712a2SRob Herring 2542133712a2SRob Herring if ($realfile !~ /^MAINTAINERS/) { 2543133712a2SRob Herring my $last_binding_patch = $is_binding_patch; 2544133712a2SRob Herring 2545133712a2SRob Herring $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; 2546133712a2SRob Herring 2547133712a2SRob Herring if (($last_binding_patch != -1) && 2548133712a2SRob Herring ($last_binding_patch ^ $is_binding_patch)) { 2549133712a2SRob Herring WARN("DT_SPLIT_BINDING_PATCH", 2550133712a2SRob Herring "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); 2551133712a2SRob Herring } 2552133712a2SRob Herring } 2553133712a2SRob Herring 2554773647a0SAndy Whitcroft next; 2555773647a0SAndy Whitcroft } 2556773647a0SAndy Whitcroft 2557389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 25580a920b5bSAndy Whitcroft 2559c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2560c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2561c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 25620a920b5bSAndy Whitcroft 25636c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 25646c72ffaaSAndy Whitcroft 2565490b292cSJoe Perches# Verify the existence of a commit log if appropriate 2566490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines 2567490b292cSJoe Perches if ($in_commit_log) { 2568490b292cSJoe Perches if ($line !~ /^\s*$/) { 2569490b292cSJoe Perches $commit_log_lines++; #could be a $signature 2570490b292cSJoe Perches } 2571490b292cSJoe Perches } elsif ($has_commit_log && $commit_log_lines < 2) { 2572490b292cSJoe Perches WARN("COMMIT_MESSAGE", 2573490b292cSJoe Perches "Missing commit description - Add an appropriate one\n"); 2574490b292cSJoe Perches $commit_log_lines = 2; #warn only once 2575490b292cSJoe Perches } 2576490b292cSJoe Perches 2577e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2578e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 2579e518e9a5SJoe Perches (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2580e518e9a5SJoe Perches $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 2581e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2582e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2583e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2584e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2585e518e9a5SJoe Perches $commit_log_has_diff = 1; 2586e518e9a5SJoe Perches } 2587e518e9a5SJoe Perches 25883bf9a009SRabin Vincent# Check for incorrect file permissions 25893bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 25903bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 259104db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 259204db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2593000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2594000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 25953bf9a009SRabin Vincent } 25963bf9a009SRabin Vincent } 25973bf9a009SRabin Vincent 2598cd261496SGeert Uytterhoeven# Check the patch for a From: 2599cd261496SGeert Uytterhoeven if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { 2600cd261496SGeert Uytterhoeven $author = $1; 2601cd261496SGeert Uytterhoeven $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); 2602cd261496SGeert Uytterhoeven $author =~ s/"//g; 2603cd261496SGeert Uytterhoeven } 2604cd261496SGeert Uytterhoeven 260520112475SJoe Perches# Check the patch for a signoff: 2606d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 26074a0df2efSAndy Whitcroft $signoff++; 260815662b3eSJoe Perches $in_commit_log = 0; 2609cd261496SGeert Uytterhoeven if ($author ne '') { 2610cd261496SGeert Uytterhoeven my $l = $line; 2611cd261496SGeert Uytterhoeven $l =~ s/"//g; 2612cd261496SGeert Uytterhoeven if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) { 2613cd261496SGeert Uytterhoeven $authorsignoff = 1; 2614cd261496SGeert Uytterhoeven } 2615cd261496SGeert Uytterhoeven } 26160a920b5bSAndy Whitcroft } 261720112475SJoe Perches 2618e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2619e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2620e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2621e0d975b1SJoe Perches $reported_maintainer_file = 1; 2622e0d975b1SJoe Perches } 2623e0d975b1SJoe Perches 262420112475SJoe Perches# Check signature styles 2625270c49a0SJoe Perches if (!$in_header_lines && 2626ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 262720112475SJoe Perches my $space_before = $1; 262820112475SJoe Perches my $sign_off = $2; 262920112475SJoe Perches my $space_after = $3; 263020112475SJoe Perches my $email = $4; 263120112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 263220112475SJoe Perches 2633ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2634ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2635ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2636ce0338dfSJoe Perches } 263720112475SJoe Perches if (defined $space_before && $space_before ne "") { 26383705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 26393705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 26403705ce5bSJoe Perches $fix) { 2641194f66fcSJoe Perches $fixed[$fixlinenr] = 26423705ce5bSJoe Perches "$ucfirst_sign_off $email"; 26433705ce5bSJoe Perches } 264420112475SJoe Perches } 264520112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 26463705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 26473705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 26483705ce5bSJoe Perches $fix) { 2649194f66fcSJoe Perches $fixed[$fixlinenr] = 26503705ce5bSJoe Perches "$ucfirst_sign_off $email"; 26513705ce5bSJoe Perches } 26523705ce5bSJoe Perches 265320112475SJoe Perches } 265420112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 26553705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 26563705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 26573705ce5bSJoe Perches $fix) { 2658194f66fcSJoe Perches $fixed[$fixlinenr] = 26593705ce5bSJoe Perches "$ucfirst_sign_off $email"; 26603705ce5bSJoe Perches } 266120112475SJoe Perches } 266220112475SJoe Perches 266320112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 266420112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 266520112475SJoe Perches if ($suggested_email eq "") { 2666000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2667000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 266820112475SJoe Perches } else { 266920112475SJoe Perches my $dequoted = $suggested_email; 267020112475SJoe Perches $dequoted =~ s/^"//; 267120112475SJoe Perches $dequoted =~ s/" </ </; 267220112475SJoe Perches # Don't force email to have quotes 267320112475SJoe Perches # Allow just an angle bracketed address 267420112475SJoe Perches if ("$dequoted$comment" ne $email && 267520112475SJoe Perches "<$email_address>$comment" ne $email && 267620112475SJoe Perches "$suggested_email$comment" ne $email) { 2677000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2678000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 267920112475SJoe Perches } 26800a920b5bSAndy Whitcroft } 26817e51f197SJoe Perches 26827e51f197SJoe Perches# Check for duplicate signatures 26837e51f197SJoe Perches my $sig_nospace = $line; 26847e51f197SJoe Perches $sig_nospace =~ s/\s//g; 26857e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 26867e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 26877e51f197SJoe Perches WARN("BAD_SIGN_OFF", 26887e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 26897e51f197SJoe Perches } else { 26907e51f197SJoe Perches $signatures{$sig_nospace} = 1; 26917e51f197SJoe Perches } 26926c5d24eeSSean Christopherson 26936c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email 26946c5d24eeSSean Christopherson if ($sign_off =~ /^co-developed-by:$/i) { 26956c5d24eeSSean Christopherson if ($email eq $author) { 26966c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 26976c5d24eeSSean Christopherson "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); 26986c5d24eeSSean Christopherson } 26996c5d24eeSSean Christopherson if (!defined $lines[$linenr]) { 27006c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27016c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); 27026c5d24eeSSean Christopherson } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { 27036c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27046c5d24eeSSean Christopherson "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 27056c5d24eeSSean Christopherson } elsif ($1 ne $email) { 27066c5d24eeSSean Christopherson WARN("BAD_SIGN_OFF", 27076c5d24eeSSean Christopherson "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); 27086c5d24eeSSean Christopherson } 27096c5d24eeSSean Christopherson } 27100a920b5bSAndy Whitcroft } 27110a920b5bSAndy Whitcroft 2712a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2713a2fe16b9SJoe Perches if ($in_header_lines && 2714a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2715a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2716a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2717a2fe16b9SJoe Perches } 2718a2fe16b9SJoe Perches 27197ebd05efSChristopher Covington# Check for unwanted Gerrit info 27207ebd05efSChristopher Covington if ($in_commit_log && $line =~ /^\s*change-id:/i) { 27217ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 27227ebd05efSChristopher Covington "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 27237ebd05efSChristopher Covington } 27247ebd05efSChristopher Covington 2725369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 2726369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2727369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 2728369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 2729369c8dd3SJoe Perches # timestamp 2730634cffccSJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || 2731634cffccSJoe Perches $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || 2732634cffccSJoe Perches $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { 2733634cffccSJoe Perches # stack dump address styles 2734369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 2735369c8dd3SJoe Perches } 2736369c8dd3SJoe Perches 27372a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 27382a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 2739bf4daf12SJoe Perches length($line) > 75 && 2740bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 2741bf4daf12SJoe Perches # file delta changes 2742bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 2743bf4daf12SJoe Perches # filename then : 2744bf4daf12SJoe Perches $line =~ /^\s*(?:Fixes:|Link:)/i || 2745bf4daf12SJoe Perches # A Fixes: or Link: line 2746bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 27472a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 27482a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 27492a076f40SJoe Perches $commit_log_long_line = 1; 27502a076f40SJoe Perches } 27512a076f40SJoe Perches 2752bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 2753bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 2754bf4daf12SJoe Perches $line =~ /^\s*$/) { 2755bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 2756bf4daf12SJoe Perches } 2757bf4daf12SJoe Perches 27580d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 2759369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2760aab38f51SJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && 2761e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 2762fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 2763aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 2764369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 2765bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 2766fe043ea1SJoe Perches my $init_char = "c"; 2767fe043ea1SJoe Perches my $orig_commit = ""; 27680d7835fcSJoe Perches my $short = 1; 27690d7835fcSJoe Perches my $long = 0; 27700d7835fcSJoe Perches my $case = 1; 27710d7835fcSJoe Perches my $space = 1; 27720d7835fcSJoe Perches my $hasdesc = 0; 277319c146a6SJoe Perches my $hasparens = 0; 27740d7835fcSJoe Perches my $id = '0123456789ab'; 27750d7835fcSJoe Perches my $orig_desc = "commit description"; 27760d7835fcSJoe Perches my $description = ""; 27770d7835fcSJoe Perches 2778fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 2779fe043ea1SJoe Perches $init_char = $1; 2780fe043ea1SJoe Perches $orig_commit = lc($2); 2781fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 2782fe043ea1SJoe Perches $orig_commit = lc($1); 2783fe043ea1SJoe Perches } 2784fe043ea1SJoe Perches 27850d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 27860d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 27870d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 27880d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 27890d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 27900d7835fcSJoe Perches $orig_desc = $1; 279119c146a6SJoe Perches $hasparens = 1; 27920d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 27930d7835fcSJoe Perches defined $rawlines[$linenr] && 27940d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 27950d7835fcSJoe Perches $orig_desc = $1; 279619c146a6SJoe Perches $hasparens = 1; 2797b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2798b671fde0SJoe Perches defined $rawlines[$linenr] && 2799b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2800b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2801b671fde0SJoe Perches $orig_desc = $1; 2802b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2803b671fde0SJoe Perches $orig_desc .= " " . $1; 280419c146a6SJoe Perches $hasparens = 1; 28050d7835fcSJoe Perches } 28060d7835fcSJoe Perches 28070d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 28080d7835fcSJoe Perches $id, $orig_desc); 28090d7835fcSJoe Perches 2810948b133aSHeinrich Schuchardt if (defined($id) && 2811948b133aSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 2812d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 28130d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 28140d7835fcSJoe Perches } 2815d311cd44SJoe Perches } 2816d311cd44SJoe Perches 281713f1937eSJoe Perches# Check for added, moved or deleted files 281813f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 281913f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 282013f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 282113f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 282213f1937eSJoe Perches (defined($1) || defined($2))))) { 2823a82603a8SAndrew Jeffery $is_patch = 1; 282413f1937eSJoe Perches $reported_maintainer_file = 1; 282513f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 282613f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 282713f1937eSJoe Perches } 282813f1937eSJoe Perches 282900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 28308905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2831000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2832000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 28336c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2834de7d4f0eSAndy Whitcroft } 2835de7d4f0eSAndy Whitcroft 2836de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2837de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2838171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2839171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2840171ae1a4SAndy Whitcroft 2841171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2842171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2843171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2844171ae1a4SAndy Whitcroft 284534d99219SJoe Perches CHK("INVALID_UTF8", 2846000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 284700df344fSAndy Whitcroft } 28480a920b5bSAndy Whitcroft 284915662b3eSJoe Perches# Check if it's the start of a commit log 285015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 285115662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 2852eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 2853eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 285415662b3eSJoe Perches $in_header_lines = 0; 285515662b3eSJoe Perches $in_commit_log = 1; 2856ed43c4e5SAllen Hubbe $has_commit_log = 1; 285715662b3eSJoe Perches } 285815662b3eSJoe Perches 2859fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2860fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2861fa64205dSPasi Savanainen if ($in_header_lines && 2862fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2863fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2864fa64205dSPasi Savanainen $non_utf8_charset = 1; 2865fa64205dSPasi Savanainen } 2866fa64205dSPasi Savanainen 2867fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 286815662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2869fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 287015662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 287115662b3eSJoe Perches } 287215662b3eSJoe Perches 2873d6430f71SJoe Perches# Check for absolute kernel paths in commit message 2874d6430f71SJoe Perches if ($tree && $in_commit_log) { 2875d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 2876d6430f71SJoe Perches my $file = $1; 2877d6430f71SJoe Perches 2878d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 2879d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 2880d6430f71SJoe Perches # 2881d6430f71SJoe Perches } else { 2882d6430f71SJoe Perches check_absolute_file($file, $herecurr); 2883d6430f71SJoe Perches } 2884d6430f71SJoe Perches } 2885d6430f71SJoe Perches } 2886d6430f71SJoe Perches 288766b47b4aSKees Cook# Check for various typo / spelling mistakes 288866d7a382SJoe Perches if (defined($misspellings) && 288966d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2890ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 289166b47b4aSKees Cook my $typo = $1; 289266b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 289366b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 289466b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 28950675a8fbSJean Delvare my $msg_level = \&WARN; 28960675a8fbSJean Delvare $msg_level = \&CHK if ($file); 28970675a8fbSJean Delvare if (&{$msg_level}("TYPO_SPELLING", 289866b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 289966b47b4aSKees Cook $fix) { 290066b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 290166b47b4aSKees Cook } 290266b47b4aSKees Cook } 290366b47b4aSKees Cook } 290466b47b4aSKees Cook 2905a8dd86bfSMatteo Croce# check for invalid commit id 2906a8dd86bfSMatteo Croce if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { 2907a8dd86bfSMatteo Croce my $id; 2908a8dd86bfSMatteo Croce my $description; 2909a8dd86bfSMatteo Croce ($id, $description) = git_commit_info($2, undef, undef); 2910a8dd86bfSMatteo Croce if (!defined($id)) { 2911a8dd86bfSMatteo Croce WARN("UNKNOWN_COMMIT_ID", 2912a8dd86bfSMatteo Croce "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); 2913a8dd86bfSMatteo Croce } 2914a8dd86bfSMatteo Croce } 2915a8dd86bfSMatteo Croce 291630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 291730670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 291800df344fSAndy Whitcroft 29190a920b5bSAndy Whitcroft#trailing whitespace 29209c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2921c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2922d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2923d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2924d5e616fcSJoe Perches $fix) { 2925194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2926d5e616fcSJoe Perches } 2927c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2928c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29293705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 29303705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 29313705ce5bSJoe Perches $fix) { 2932194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 29333705ce5bSJoe Perches } 29343705ce5bSJoe Perches 2935d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29360a920b5bSAndy Whitcroft } 29375368df20SAndy Whitcroft 29384783f894SJosh Triplett# Check for FSF mailing addresses. 2939109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 29401bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 29413e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 29423e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 29434783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29440675a8fbSJean Delvare my $msg_level = \&ERROR; 29450675a8fbSJean Delvare $msg_level = \&CHK if ($file); 29460675a8fbSJean Delvare &{$msg_level}("FSF_MAILING_ADDRESS", 29474783f894SJosh 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) 29484783f894SJosh Triplett } 29494783f894SJosh Triplett 29503354957aSAndi Kleen# check for Kconfig help text having a real description 29519fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 29529fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 29533354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 2954678ae162SUlf Magnusson # 'choice' is usually the last thing on the line (though 2955678ae162SUlf Magnusson # Kconfig supports named choices), so use a word boundary 2956678ae162SUlf Magnusson # (\b) rather than a whitespace character (\s) 2957678ae162SUlf Magnusson $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { 29583354957aSAndi Kleen my $length = 0; 29599fe287d7SAndy Whitcroft my $cnt = $realcnt; 29609fe287d7SAndy Whitcroft my $ln = $linenr + 1; 29619fe287d7SAndy Whitcroft my $f; 2962a1385803SAndy Whitcroft my $is_start = 0; 29639fe287d7SAndy Whitcroft my $is_end = 0; 2964a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 29659fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 29669fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 29679fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 29689fe287d7SAndy Whitcroft 29699fe287d7SAndy Whitcroft next if ($f =~ /^-/); 29708d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 2971a1385803SAndy Whitcroft 297286adf1a0SUlf Magnusson if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { 2973a1385803SAndy Whitcroft $is_start = 1; 297484af7a61SUlf Magnusson } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) { 297584af7a61SUlf Magnusson if ($lines[$ln - 1] =~ "---help---") { 297684af7a61SUlf Magnusson WARN("CONFIG_DESCRIPTION", 297784af7a61SUlf Magnusson "prefer 'help' over '---help---' for new help texts\n" . $herecurr); 297884af7a61SUlf Magnusson } 2979a1385803SAndy Whitcroft $length = -1; 2980a1385803SAndy Whitcroft } 2981a1385803SAndy Whitcroft 29829fe287d7SAndy Whitcroft $f =~ s/^.//; 29833354957aSAndi Kleen $f =~ s/#.*//; 29843354957aSAndi Kleen $f =~ s/^\s+//; 29853354957aSAndi Kleen next if ($f =~ /^$/); 2986678ae162SUlf Magnusson 2987678ae162SUlf Magnusson # This only checks context lines in the patch 2988678ae162SUlf Magnusson # and so hopefully shouldn't trigger false 2989678ae162SUlf Magnusson # positives, even though some of these are 2990678ae162SUlf Magnusson # common words in help texts 2991678ae162SUlf Magnusson if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| 2992678ae162SUlf Magnusson if|endif|menu|endmenu|source)\b/x) { 29939fe287d7SAndy Whitcroft $is_end = 1; 29949fe287d7SAndy Whitcroft last; 29959fe287d7SAndy Whitcroft } 29963354957aSAndi Kleen $length++; 29973354957aSAndi Kleen } 299856193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 2999000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 300056193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 300156193274SVadim Bendebury } 3002a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 30033354957aSAndi Kleen } 30043354957aSAndi Kleen 3005628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form 3006628f91a2SJoe Perches if ($realfile =~ /^MAINTAINERS$/ && 3007628f91a2SJoe Perches $rawline =~ /^\+[A-Z]:/ && 3008628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 3009628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 3010628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 3011628f91a2SJoe Perches $fix) { 3012628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 3013628f91a2SJoe Perches } 3014628f91a2SJoe Perches } 3015628f91a2SJoe Perches 3016327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 3017327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 3018327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 3019327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 3020327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 3021327953e9SChristoph Jaeger } 3022327953e9SChristoph Jaeger 3023c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 3024c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 3025c68e5878SArnaud Lacombe my $flag = $1; 3026c68e5878SArnaud Lacombe my $replacement = { 3027c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 3028c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 3029c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 3030c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 3031c68e5878SArnaud Lacombe }; 3032c68e5878SArnaud Lacombe 3033c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 3034c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 3035c68e5878SArnaud Lacombe } 3036c68e5878SArnaud Lacombe 3037bff5da43SRob Herring# check for DT compatible documentation 30387dd05b38SFlorian Vaussard if (defined $root && 30397dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 30407dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 30417dd05b38SFlorian Vaussard 3042bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 3043bff5da43SRob Herring 3044cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 3045852d095dSRob Herring my $vp_file = $dt_path . "vendor-prefixes.yaml"; 3046cc93319bSFlorian Vaussard 3047bff5da43SRob Herring foreach my $compat (@compats) { 3048bff5da43SRob Herring my $compat2 = $compat; 3049185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 3050185d566bSRob Herring my $compat3 = $compat; 3051185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 3052185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 3053bff5da43SRob Herring if ( $? >> 8 ) { 3054bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3055bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 3056bff5da43SRob Herring } 3057bff5da43SRob Herring 30584fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 30594fbf32a6SFlorian Vaussard my $vendor = $1; 3060852d095dSRob Herring `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; 3061bff5da43SRob Herring if ( $? >> 8 ) { 3062bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 3063cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 3064bff5da43SRob Herring } 3065bff5da43SRob Herring } 3066bff5da43SRob Herring } 3067bff5da43SRob Herring 30689f3a8992SRob Herring# check for using SPDX license tag at beginning of files 30699f3a8992SRob Herring if ($realline == $checklicenseline) { 30709f3a8992SRob Herring if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { 30719f3a8992SRob Herring $checklicenseline = 2; 30729f3a8992SRob Herring } elsif ($rawline =~ /^\+/) { 30739f3a8992SRob Herring my $comment = ""; 30749f3a8992SRob Herring if ($realfile =~ /\.(h|s|S)$/) { 30759f3a8992SRob Herring $comment = '/*'; 30769f3a8992SRob Herring } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { 30779f3a8992SRob Herring $comment = '//'; 30789f3a8992SRob Herring } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) { 30799f3a8992SRob Herring $comment = '#'; 30809f3a8992SRob Herring } elsif ($realfile =~ /\.rst$/) { 30819f3a8992SRob Herring $comment = '..'; 30829f3a8992SRob Herring } 30839f3a8992SRob Herring 3084fdf13693SJoe Perches# check SPDX comment style for .[chsS] files 3085fdf13693SJoe Perches if ($realfile =~ /\.[chsS]$/ && 3086fdf13693SJoe Perches $rawline =~ /SPDX-License-Identifier:/ && 3087ffbce897SJoe Perches $rawline !~ m@^\+\s*\Q$comment\E\s*@) { 3088fdf13693SJoe Perches WARN("SPDX_LICENSE_TAG", 3089fdf13693SJoe Perches "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); 3090fdf13693SJoe Perches } 3091fdf13693SJoe Perches 30929f3a8992SRob Herring if ($comment !~ /^$/ && 3093ffbce897SJoe Perches $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { 30949f3a8992SRob Herring WARN("SPDX_LICENSE_TAG", 30959f3a8992SRob Herring "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); 30963b6e8ac9SJoe Perches } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { 30973b6e8ac9SJoe Perches my $spdx_license = $1; 30983b6e8ac9SJoe Perches if (!is_SPDX_License_valid($spdx_license)) { 30993b6e8ac9SJoe Perches WARN("SPDX_LICENSE_TAG", 31003b6e8ac9SJoe Perches "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); 31013b6e8ac9SJoe Perches } 31029f3a8992SRob Herring } 31039f3a8992SRob Herring } 31049f3a8992SRob Herring } 31059f3a8992SRob Herring 31065368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 3107d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 31085368df20SAndy Whitcroft 3109a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number 3110a8da38a9SJoe Perches if ($realline != $checklicenseline && 3111a8da38a9SJoe Perches $rawline =~ /\bSPDX-License-Identifier:/ && 3112a8da38a9SJoe Perches substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { 3113a8da38a9SJoe Perches WARN("SPDX_LICENSE_TAG", 3114a8da38a9SJoe Perches "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); 3115a8da38a9SJoe Perches } 3116a8da38a9SJoe Perches 311747e0c88bSJoe Perches# line length limit (with some exclusions) 311847e0c88bSJoe Perches# 311947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 312047e0c88bSJoe Perches# logging functions like pr_info that end in a string 312147e0c88bSJoe Perches# lines with a single string 312247e0c88bSJoe Perches# #defines that are a single string 31232e4bbbc5SAndreas Brauchli# lines with an RFC3986 like URL 312447e0c88bSJoe Perches# 312547e0c88bSJoe Perches# There are 3 different line length message types: 3126ab1ecabfSJean Delvare# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length 312747e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 312847e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 312947e0c88bSJoe Perches# 313047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 313147e0c88bSJoe Perches# 313247e0c88bSJoe Perches 3133b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 313447e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 313547e0c88bSJoe Perches 313647e0c88bSJoe Perches # Check the allowed long line types first 313747e0c88bSJoe Perches 313847e0c88bSJoe Perches # logging functions that end in a string that starts 313947e0c88bSJoe Perches # before $max_line_length 314047e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 314147e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 314247e0c88bSJoe Perches $msg_type = ""; 314347e0c88bSJoe Perches 314447e0c88bSJoe Perches # lines with only strings (w/ possible termination) 314547e0c88bSJoe Perches # #defines with only strings 314647e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 314747e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 314847e0c88bSJoe Perches $msg_type = ""; 314947e0c88bSJoe Perches 3150cc147506SJoe Perches # More special cases 3151cc147506SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || 3152cc147506SJoe Perches $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { 3153d560a5f8SJoe Perches $msg_type = ""; 3154d560a5f8SJoe Perches 31552e4bbbc5SAndreas Brauchli # URL ($rawline is used in case the URL is in a comment) 31562e4bbbc5SAndreas Brauchli } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { 31572e4bbbc5SAndreas Brauchli $msg_type = ""; 31582e4bbbc5SAndreas Brauchli 315947e0c88bSJoe Perches # Otherwise set the alternate message types 316047e0c88bSJoe Perches 316147e0c88bSJoe Perches # a comment starts before $max_line_length 316247e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 316347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 316447e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 316547e0c88bSJoe Perches 316647e0c88bSJoe Perches # a quoted string starts before $max_line_length 316747e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 316847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 316947e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 317047e0c88bSJoe Perches } 317147e0c88bSJoe Perches 317247e0c88bSJoe Perches if ($msg_type ne "" && 317347e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 317447e0c88bSJoe Perches WARN($msg_type, 31756cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 31760a920b5bSAndy Whitcroft } 317747e0c88bSJoe Perches } 31780a920b5bSAndy Whitcroft 31798905a67cSAndy Whitcroft# check for adding lines without a newline. 31808905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 3181000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 3182000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 31838905a67cSAndy Whitcroft } 31848905a67cSAndy Whitcroft 3185b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 3186de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 31870a920b5bSAndy Whitcroft 31880a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 31890a920b5bSAndy Whitcroft# more than 8 must use tabs. 3190c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 3191c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 3192c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 3193d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 31943705ce5bSJoe Perches if (ERROR("CODE_INDENT", 31953705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 31963705ce5bSJoe Perches $fix) { 3197194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31983705ce5bSJoe Perches } 31990a920b5bSAndy Whitcroft } 32000a920b5bSAndy Whitcroft 320108e44365SAlberto Panizzo# check for space before tabs. 320208e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 320308e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 32043705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 32053705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 32063705ce5bSJoe Perches $fix) { 3207194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3208d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 3209194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 3210c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 32113705ce5bSJoe Perches } 321208e44365SAlberto Panizzo } 321308e44365SAlberto Panizzo 32146a487211SJoe Perches# check for assignments on the start of a line 32156a487211SJoe Perches if ($sline =~ /^\+\s+($Assignment)[^=]/) { 32166a487211SJoe Perches CHK("ASSIGNMENT_CONTINUATIONS", 32176a487211SJoe Perches "Assignment operator '$1' should be on the previous line\n" . $hereprev); 32186a487211SJoe Perches } 32196a487211SJoe Perches 3220d1fe9c09SJoe Perches# check for && or || at the start of a line 3221d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 3222d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 3223d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 3224d1fe9c09SJoe Perches } 3225d1fe9c09SJoe Perches 3226a91e8994SJoe Perches# check indentation starts on a tab stop 32275b57980dSJoe Perches if ($perl_version_ok && 3228bd49111fSJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { 3229a91e8994SJoe Perches my $indent = length($1); 3230a91e8994SJoe Perches if ($indent % 8) { 3231a91e8994SJoe Perches if (WARN("TABSTOP", 3232a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 3233a91e8994SJoe Perches $fix) { 3234a91e8994SJoe Perches $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 3235a91e8994SJoe Perches } 3236a91e8994SJoe Perches } 3237a91e8994SJoe Perches } 3238a91e8994SJoe Perches 3239d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 32405b57980dSJoe Perches if ($perl_version_ok && 3241fd71f632SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 3242d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 3243d1fe9c09SJoe Perches my $oldindent = $1; 3244d1fe9c09SJoe Perches my $rest = $2; 3245d1fe9c09SJoe Perches 3246d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 3247d1fe9c09SJoe Perches if ($pos >= 0) { 3248b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 3249b34a26f3SJoe Perches my $newindent = $2; 3250d1fe9c09SJoe Perches 3251d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 3252d1fe9c09SJoe Perches "\t" x ($pos / 8) . 3253d1fe9c09SJoe Perches " " x ($pos % 8); 3254d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 3255d1fe9c09SJoe Perches 3256d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 3257d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 32583705ce5bSJoe Perches 32593705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 32603705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 32613705ce5bSJoe Perches $fix && $line =~ /^\+/) { 3262194f66fcSJoe Perches $fixed[$fixlinenr] =~ 32633705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 32643705ce5bSJoe Perches } 3265d1fe9c09SJoe Perches } 3266d1fe9c09SJoe Perches } 3267d1fe9c09SJoe Perches } 3268d1fe9c09SJoe Perches 32696ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 32706ab3a970SJoe Perches# avoid checking a few false positives: 32716ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 32726ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 32736ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 32746ab3a970SJoe Perches# multiline macros that define functions 32756ab3a970SJoe Perches# known attributes or the __attribute__ keyword 32766ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 32776ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 32783705ce5bSJoe Perches if (CHK("SPACING", 3279f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 32803705ce5bSJoe Perches $fix) { 3281194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3282f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 32833705ce5bSJoe Perches } 3284aad4f614SJoe Perches } 3285aad4f614SJoe Perches 328686406b1cSJoe Perches# Block comment styles 328786406b1cSJoe Perches# Networking with an initial /* 328805880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3289fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 329085ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 329185ad978cSJoe Perches $realline > 2) { 329205880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 329305880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 329405880600SJoe Perches } 329505880600SJoe Perches 329686406b1cSJoe Perches# Block comments use * on subsequent lines 329786406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 329886406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3299a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 330061135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3301a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 330286406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 330386406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3304a605e32eSJoe Perches } 3305a605e32eSJoe Perches 330686406b1cSJoe Perches# Block comments use */ on trailing lines 330786406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3308c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3309c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3310c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 331186406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 331286406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 331305880600SJoe Perches } 331405880600SJoe Perches 331508eb9b80SJoe Perches# Block comment * alignment 331608eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3317af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3318af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3319af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 332008eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3321af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3322af207524SJoe Perches my $oldindent; 332308eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3324af207524SJoe Perches if (defined($1)) { 3325af207524SJoe Perches $oldindent = expand_tabs($1); 3326af207524SJoe Perches } else { 3327af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3328af207524SJoe Perches $oldindent = expand_tabs($1); 3329af207524SJoe Perches } 333008eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 333108eb9b80SJoe Perches my $newindent = $1; 333208eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3333af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 333408eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 333508eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 333608eb9b80SJoe Perches } 333708eb9b80SJoe Perches } 333808eb9b80SJoe Perches 33397f619191SJoe Perches# check for missing blank lines after struct/union declarations 33407f619191SJoe Perches# with exceptions for various attributes and macros 33417f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 33427f619191SJoe Perches $line =~ /^\+/ && 33437f619191SJoe Perches !($line =~ /^\+\s*$/ || 33447f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 33457f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 33467f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 33477f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 33487f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 33497f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 33500bc989ffSMasahiro Yamada $line =~ /^\+\s*builtin_[\w_]*driver/ || 33517f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3352d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3353d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3354d752fcc8SJoe Perches $fix) { 3355f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3356d752fcc8SJoe Perches } 33577f619191SJoe Perches } 33587f619191SJoe Perches 3359365dd4eaSJoe Perches# check for multiple consecutive blank lines 3360365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3361365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3362365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3363d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3364d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3365d752fcc8SJoe Perches $fix) { 3366f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3367d752fcc8SJoe Perches } 3368d752fcc8SJoe Perches 3369365dd4eaSJoe Perches $last_blank_line = $linenr; 3370365dd4eaSJoe Perches } 3371365dd4eaSJoe Perches 33723b617e3bSJoe Perches# check for missing blank lines after declarations 33733f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 33743f7bac03SJoe Perches # actual declarations 33753f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 33765a4e1fd3SJoe Perches # function pointer declarations 33775a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 33783f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 33793f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 33803f7bac03SJoe Perches # known declaration macros 33813f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 33823f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 33833f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 33843f7bac03SJoe Perches # other possible extensions of declaration lines 33853f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 33863f7bac03SJoe Perches # not starting a section or a macro "\" extended line 33873f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 33883f7bac03SJoe Perches # looks like a declaration 33893f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 33905a4e1fd3SJoe Perches # function pointer declarations 33915a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 33923f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 33933f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 33943f7bac03SJoe Perches # known declaration macros 33953f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 33963f7bac03SJoe Perches # start of struct or union or enum 3397328b5f41SJoe Perches $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || 33983f7bac03SJoe Perches # start or end of block or continuation of declaration 33993f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 34003f7bac03SJoe Perches # bitfield continuation 34013f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 34023f7bac03SJoe Perches # other possible extensions of declaration lines 34033f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 34043f7bac03SJoe Perches # indentation of previous and current line are the same 34053f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3406d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3407d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3408d752fcc8SJoe Perches $fix) { 3409f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3410d752fcc8SJoe Perches } 34113b617e3bSJoe Perches } 34123b617e3bSJoe Perches 34135f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 34146b4c5bebSAndy Whitcroft# Exceptions: 34156b4c5bebSAndy Whitcroft# 1) within comments 34166b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 34176b4c5bebSAndy Whitcroft# 3) hanging labels 34183705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 34195f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 34203705ce5bSJoe Perches if (WARN("LEADING_SPACE", 34213705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 34223705ce5bSJoe Perches $fix) { 3423194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 34243705ce5bSJoe Perches } 34255f7ddae6SRaffaele Recalcati } 34265f7ddae6SRaffaele Recalcati 3427b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3428b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3429b9ea10d6SAndy Whitcroft 34305751a24eSJoe Perches# check for unusual line ending [ or ( 34315751a24eSJoe Perches if ($line =~ /^\+.*([\[\(])\s*$/) { 34325751a24eSJoe Perches CHK("OPEN_ENDED_LINE", 34335751a24eSJoe Perches "Lines should not end with a '$1'\n" . $herecurr); 34345751a24eSJoe Perches } 34355751a24eSJoe Perches 34364dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 34374dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 34384dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 34394dbed76fSJoe Perches $context_function = $1; 34404dbed76fSJoe Perches } 34414dbed76fSJoe Perches 34424dbed76fSJoe Perches# check if this appears to be the end of function declaration 34434dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 34444dbed76fSJoe Perches undef $context_function; 34454dbed76fSJoe Perches } 34464dbed76fSJoe Perches 3447032a4c0fSJoe Perches# check indentation of any line with a bare else 3448840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3449032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3450032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3451032a4c0fSJoe Perches my $tabs = length($1) + 1; 3452840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3453840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3454840080a0SJoe Perches defined $lines[$linenr] && 3455840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3456032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3457032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3458032a4c0fSJoe Perches } 3459032a4c0fSJoe Perches } 3460032a4c0fSJoe Perches 3461c00df19aSJoe Perches# check indentation of a line with a break; 3462c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3463c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3464c00df19aSJoe Perches my $tabs = $1; 3465c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3466c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3467c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3468c00df19aSJoe Perches } 3469c00df19aSJoe Perches } 3470c00df19aSJoe Perches 3471c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3472cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3473000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3474000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3475c2fdda0dSAndy Whitcroft } 347622f2a2efSAndy Whitcroft 347756e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 347856e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 347956e77d70SJoe Perches WARN("HOTPLUG_SECTION", 348056e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 348156e77d70SJoe Perches } 348256e77d70SJoe Perches 34839c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 34842b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 34852b474a1aSAndy Whitcroft $realline_next); 34863e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3487ca819864SJoe Perches if ($linenr > $suppress_statement && 34881b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3489170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3490f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3491171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3492171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3493171ae1a4SAndy Whitcroft 34943e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 34953e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 34963e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 34973e469cdcSAndy Whitcroft # until we hit end of it. 34983e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 34993e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 35003e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 35013e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 35023e469cdcSAndy Whitcroft } 3503f74bd194SAndy Whitcroft 35042b474a1aSAndy Whitcroft # Find the real next line. 35052b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 35062b474a1aSAndy Whitcroft if (defined $realline_next && 35072b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 35082b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 35092b474a1aSAndy Whitcroft $realline_next++; 35102b474a1aSAndy Whitcroft } 35112b474a1aSAndy Whitcroft 3512171ae1a4SAndy Whitcroft my $s = $stat; 3513171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3514cf655043SAndy Whitcroft 3515c2fdda0dSAndy Whitcroft # Ignore goto labels. 3516171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3517c2fdda0dSAndy Whitcroft 3518c2fdda0dSAndy Whitcroft # Ignore functions being called 3519171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3520c2fdda0dSAndy Whitcroft 3521463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3522463f2864SAndy Whitcroft 3523c45dcabdSAndy Whitcroft # declarations always start with types 3524d2506586SAndy 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) { 3525c45dcabdSAndy Whitcroft my $type = $1; 3526c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3527c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3528c45dcabdSAndy Whitcroft 35296c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3530a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3531c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3532c2fdda0dSAndy Whitcroft } 35338905a67cSAndy Whitcroft 35346c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 353565863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3536c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 35379c0ca6f9SAndy Whitcroft } 35388905a67cSAndy Whitcroft 35398905a67cSAndy Whitcroft # Check for any sort of function declaration. 35408905a67cSAndy Whitcroft # int foo(something bar, other baz); 35418905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3542171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 35438905a67cSAndy Whitcroft my ($name_len) = length($1); 35448905a67cSAndy Whitcroft 3545cf655043SAndy Whitcroft my $ctx = $s; 3546773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 35478905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3548cf655043SAndy Whitcroft 35498905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3550c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 35518905a67cSAndy Whitcroft 3552c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 35538905a67cSAndy Whitcroft } 35548905a67cSAndy Whitcroft } 35558905a67cSAndy Whitcroft } 35568905a67cSAndy Whitcroft 35579c0ca6f9SAndy Whitcroft } 35589c0ca6f9SAndy Whitcroft 355900df344fSAndy Whitcroft# 356000df344fSAndy Whitcroft# Checks which may be anchored in the context. 356100df344fSAndy Whitcroft# 356200df344fSAndy Whitcroft 356300df344fSAndy Whitcroft# Check for switch () and associated case and default 356400df344fSAndy Whitcroft# statements should be at the same indent. 356500df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 356600df344fSAndy Whitcroft my $err = ''; 356700df344fSAndy Whitcroft my $sep = ''; 356800df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 356900df344fSAndy Whitcroft shift(@ctx); 357000df344fSAndy Whitcroft for my $ctx (@ctx) { 357100df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 357200df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 357300df344fSAndy Whitcroft $indent != $cindent) { 357400df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 357500df344fSAndy Whitcroft $sep = ''; 357600df344fSAndy Whitcroft } else { 357700df344fSAndy Whitcroft $sep = "[...]\n"; 357800df344fSAndy Whitcroft } 357900df344fSAndy Whitcroft } 358000df344fSAndy Whitcroft if ($err ne '') { 3581000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3582000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3583de7d4f0eSAndy Whitcroft } 3584de7d4f0eSAndy Whitcroft } 3585de7d4f0eSAndy Whitcroft 3586de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3587de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 35880fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3589773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3590773647a0SAndy Whitcroft 35919c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 35928eef05ddSJoe Perches 35938eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 35948eef05ddSJoe Perches WARN("DEEP_INDENTATION", 35958eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 35968eef05ddSJoe Perches } 35978eef05ddSJoe Perches 3598de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3599de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3600de7d4f0eSAndy Whitcroft 3601548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3602548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3603de7d4f0eSAndy Whitcroft 3604548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3605548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3606548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3607548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3608548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3609773647a0SAndy Whitcroft $ctx_ln++; 3610773647a0SAndy Whitcroft } 3611548596d5SAndy Whitcroft 361253210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 361353210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3614773647a0SAndy Whitcroft 3615773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3616000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3617000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 361801464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 361900df344fSAndy Whitcroft } 3620773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3621773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3622773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3623773647a0SAndy Whitcroft { 36249c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 36259c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3626000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3627000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 362801464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 36299c0ca6f9SAndy Whitcroft } 36309c0ca6f9SAndy Whitcroft } 363100df344fSAndy Whitcroft } 363200df344fSAndy Whitcroft 36334d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3634f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 36353e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 36363e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 36373e469cdcSAndy Whitcroft if (!defined $stat); 36384d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 36394d001e4dSAndy Whitcroft 36404d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 36414d001e4dSAndy Whitcroft 36429f5af480SJoe Perches # remove inline comments 36439f5af480SJoe Perches $s =~ s/$;/ /g; 36449f5af480SJoe Perches $c =~ s/$;/ /g; 36454d001e4dSAndy Whitcroft 36464d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 36476f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 36486f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 36494d001e4dSAndy Whitcroft 36509f5af480SJoe Perches # Make sure we remove the line prefixes as we have 36519f5af480SJoe Perches # none on the first line, and are going to readd them 36529f5af480SJoe Perches # where necessary. 36539f5af480SJoe Perches $s =~ s/\n./\n/gs; 36549f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 36559f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 36569f5af480SJoe Perches } 36579f5af480SJoe Perches 36584d001e4dSAndy Whitcroft # We want to check the first line inside the block 36594d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 36604d001e4dSAndy Whitcroft # 1) any blank line termination 36614d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 36624d001e4dSAndy Whitcroft # 3) any do (...) { 36634d001e4dSAndy Whitcroft my $continuation = 0; 36644d001e4dSAndy Whitcroft my $check = 0; 36654d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 36664d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 36674d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 36684d001e4dSAndy Whitcroft $continuation = 1; 36694d001e4dSAndy Whitcroft } 36709bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 36714d001e4dSAndy Whitcroft $check = 1; 36724d001e4dSAndy Whitcroft $cond_lines++; 36734d001e4dSAndy Whitcroft } 36744d001e4dSAndy Whitcroft 36754d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 36764d001e4dSAndy Whitcroft # preprocessor statement. 36774d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 36784d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 36794d001e4dSAndy Whitcroft $check = 0; 36804d001e4dSAndy Whitcroft } 36814d001e4dSAndy Whitcroft 36829bd49efeSAndy Whitcroft my $cond_ptr = -1; 3683740504c6SAndy Whitcroft $continuation = 0; 36849bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 36859bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 36864d001e4dSAndy Whitcroft 3687f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3688f16fa28fSAndy Whitcroft # is not linear. 3689f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3690f16fa28fSAndy Whitcroft $check = 0; 3691f16fa28fSAndy Whitcroft } 3692f16fa28fSAndy Whitcroft 36939bd49efeSAndy Whitcroft # Ignore: 36949bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 36959bd49efeSAndy Whitcroft # 2) preprocessor lines, and 36969bd49efeSAndy Whitcroft # 3) labels. 3697740504c6SAndy Whitcroft if ($continuation || 3698740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 36999bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 37009bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3701740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 370230dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 37039bd49efeSAndy Whitcroft $cond_lines++; 37049bd49efeSAndy Whitcroft } 37054d001e4dSAndy Whitcroft } 370630dad6ebSAndy Whitcroft } 37074d001e4dSAndy Whitcroft 37084d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 37094d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 37104d001e4dSAndy Whitcroft 37114d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 37124d001e4dSAndy Whitcroft # this is not this patch's fault. 37134d001e4dSAndy Whitcroft if (!defined($stat_real) || 37144d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 37154d001e4dSAndy Whitcroft $check = 0; 37164d001e4dSAndy Whitcroft } 37174d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 37184d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 37194d001e4dSAndy Whitcroft } 37204d001e4dSAndy Whitcroft 37219bd49efeSAndy 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"; 37224d001e4dSAndy Whitcroft 37239f5af480SJoe Perches if ($check && $s ne '' && 37249f5af480SJoe Perches (($sindent % 8) != 0 || 37259f5af480SJoe Perches ($sindent < $indent) || 3726f6950a73SJoe Perches ($sindent == $indent && 3727f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 37289f5af480SJoe Perches ($sindent > $indent + 8))) { 3729000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3730000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 37314d001e4dSAndy Whitcroft } 37324d001e4dSAndy Whitcroft } 37334d001e4dSAndy Whitcroft 37346c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 37356c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 37361f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 37371f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 37386c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3739c2fdda0dSAndy Whitcroft if ($dbg_values) { 3740c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3741cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3742cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 37431f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3744c2fdda0dSAndy Whitcroft } 37456c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 37466c72ffaaSAndy Whitcroft 374700df344fSAndy Whitcroft#ignore lines not being added 37483705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 374900df344fSAndy Whitcroft 375011ca40a0SJoe Perches# check for dereferences that span multiple lines 375111ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 375211ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 375311ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 375411ca40a0SJoe Perches my $ref = $1; 375511ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 375611ca40a0SJoe Perches $ref .= $1; 375711ca40a0SJoe Perches $ref =~ s/\s//g; 375811ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 375911ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 376011ca40a0SJoe Perches } 376111ca40a0SJoe Perches 3762a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3763c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3764a1ce18e4SJoe Perches my $type = $1; 3765a1ce18e4SJoe Perches my $var = $2; 3766207a8e84SJoe Perches $var = "" if (!defined $var); 3767207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3768a1ce18e4SJoe Perches my $sign = $1; 3769a1ce18e4SJoe Perches my $pointer = $2; 3770a1ce18e4SJoe Perches 3771a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3772a1ce18e4SJoe Perches 3773a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3774a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3775a1ce18e4SJoe Perches $fix) { 3776a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3777207a8e84SJoe Perches my $comp_pointer = $pointer; 3778207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3779207a8e84SJoe Perches $decl .= $comp_pointer; 3780207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3781207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3782a1ce18e4SJoe Perches } 3783a1ce18e4SJoe Perches } 3784a1ce18e4SJoe Perches } 3785a1ce18e4SJoe Perches 3786653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 37877429c690SAndy Whitcroft if ($dbg_type) { 37887429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3789000d1cc1SJoe Perches ERROR("TEST_TYPE", 3790000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 37917429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3792000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3793000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 37947429c690SAndy Whitcroft } 3795653d4876SAndy Whitcroft next; 3796653d4876SAndy Whitcroft } 3797a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3798a1ef277eSAndy Whitcroft if ($dbg_attr) { 37999360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3800000d1cc1SJoe Perches ERROR("TEST_ATTR", 3801000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 38029360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3803000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3804000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3805a1ef277eSAndy Whitcroft } 3806a1ef277eSAndy Whitcroft next; 3807a1ef277eSAndy Whitcroft } 3808653d4876SAndy Whitcroft 3809f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 381099423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 381199423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3812d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3813d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3814f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3815f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3816f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3817d752fcc8SJoe Perches my $fixedline = $prevrawline; 3818d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3819f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3820d752fcc8SJoe Perches $fixedline = $line; 38218d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 3822f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3823d752fcc8SJoe Perches } 3824f0a594c1SAndy Whitcroft } 3825f0a594c1SAndy Whitcroft 382600df344fSAndy Whitcroft# 382700df344fSAndy Whitcroft# Checks which are anchored on the added line. 382800df344fSAndy Whitcroft# 382900df344fSAndy Whitcroft 3830653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3831c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3832653d4876SAndy Whitcroft my $path = $1; 3833653d4876SAndy Whitcroft if ($path =~ m{//}) { 3834000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3835495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3836495e9d84SJoe Perches } 3837495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3838495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3839495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3840653d4876SAndy Whitcroft } 3841653d4876SAndy Whitcroft } 3842653d4876SAndy Whitcroft 384300df344fSAndy Whitcroft# no C99 // comments 384400df344fSAndy Whitcroft if ($line =~ m{//}) { 38453705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 38463705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 38473705ce5bSJoe Perches $fix) { 3848194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 38493705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 38503705ce5bSJoe Perches my $comment = trim($1); 3851194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 38523705ce5bSJoe Perches } 38533705ce5bSJoe Perches } 385400df344fSAndy Whitcroft } 385500df344fSAndy Whitcroft # Remove C99 comments. 38560a920b5bSAndy Whitcroft $line =~ s@//.*@@; 38576c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 38580a920b5bSAndy Whitcroft 38592b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 38602b474a1aSAndy Whitcroft# the whole statement. 38612b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 38622b474a1aSAndy Whitcroft if (defined $realline_next && 38632b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 38642b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 38652b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 38662b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 38673cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 38683cbf62dfSAndy Whitcroft # a prefix: 38693cbf62dfSAndy Whitcroft # XXX(foo); 38703cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3871653d4876SAndy Whitcroft my $name = $1; 387287a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 38733cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 38743cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 38753cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 38763cbf62dfSAndy Whitcroft 38773cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 38782b474a1aSAndy Whitcroft \n.}\s*$| 387948012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 388048012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 388148012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 38822b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 38832b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 388448012058SAndy Whitcroft )/x) { 38852b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 38862b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 38872b474a1aSAndy Whitcroft } else { 38882b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 38890a920b5bSAndy Whitcroft } 38900a920b5bSAndy Whitcroft } 38912b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 38922b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 38932b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 38942b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 38952b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 38962b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 38972b474a1aSAndy Whitcroft } 38982b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 38992b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3900000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3901000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 39022b474a1aSAndy Whitcroft } 39030a920b5bSAndy Whitcroft 39045150bda4SJoe Eloff# check for global initialisers. 39056d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3906d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 39076d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3908d5e616fcSJoe Perches $fix) { 39096d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3910d5e616fcSJoe Perches } 3911f0a594c1SAndy Whitcroft } 39120a920b5bSAndy Whitcroft# check for static initialisers. 39136d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3914d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 39156d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3916d5e616fcSJoe Perches $herecurr) && 3917d5e616fcSJoe Perches $fix) { 39186d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3919d5e616fcSJoe Perches } 39200a920b5bSAndy Whitcroft } 39210a920b5bSAndy Whitcroft 39221813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 39231813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 39241813087dSJoe Perches my $tmp = trim($1); 39251813087dSJoe Perches WARN("MISORDERED_TYPE", 39261813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 39271813087dSJoe Perches } 39281813087dSJoe Perches 3929809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long 3930809e082eSJoe Perches while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { 3931809e082eSJoe Perches my $type = trim($1); 3932809e082eSJoe Perches next if ($type !~ /\bint\b/); 3933809e082eSJoe Perches next if ($type !~ /\b(?:short|long\s+long|long)\b/); 3934809e082eSJoe Perches my $new_type = $type; 3935809e082eSJoe Perches $new_type =~ s/\b\s*int\s*\b/ /; 3936809e082eSJoe Perches $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; 3937809e082eSJoe Perches $new_type =~ s/^const\s+//; 3938809e082eSJoe Perches $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); 3939809e082eSJoe Perches $new_type = "const $new_type" if ($type =~ /^const\b/); 3940809e082eSJoe Perches $new_type =~ s/\s+/ /g; 3941809e082eSJoe Perches $new_type = trim($new_type); 3942809e082eSJoe Perches if (WARN("UNNECESSARY_INT", 3943809e082eSJoe Perches "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && 3944809e082eSJoe Perches $fix) { 3945809e082eSJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; 3946809e082eSJoe Perches } 3947809e082eSJoe Perches } 3948809e082eSJoe Perches 3949cb710ecaSJoe Perches# check for static const char * arrays. 3950cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3951000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3952000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3953cb710ecaSJoe Perches $herecurr); 3954cb710ecaSJoe Perches } 3955cb710ecaSJoe Perches 395677b8c0a8SJoe Perches# check for initialized const char arrays that should be static const 395777b8c0a8SJoe Perches if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { 395877b8c0a8SJoe Perches if (WARN("STATIC_CONST_CHAR_ARRAY", 395977b8c0a8SJoe Perches "const array should probably be static const\n" . $herecurr) && 396077b8c0a8SJoe Perches $fix) { 396177b8c0a8SJoe Perches $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; 396277b8c0a8SJoe Perches } 396377b8c0a8SJoe Perches } 396477b8c0a8SJoe Perches 3965cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3966cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3967000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3968000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3969cb710ecaSJoe Perches $herecurr); 3970cb710ecaSJoe Perches } 3971cb710ecaSJoe Perches 3972ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3973ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3974ab7e23f3SJoe Perches my $found = $1; 3975ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3976ab7e23f3SJoe Perches WARN("CONST_CONST", 3977ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3978ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3979ab7e23f3SJoe Perches WARN("CONST_CONST", 3980ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3981ab7e23f3SJoe Perches } 3982ab7e23f3SJoe Perches } 3983ab7e23f3SJoe Perches 39849b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 39859b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 39869b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 39879b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 39889b0fa60dSJoe Perches $herecurr); 39899b0fa60dSJoe Perches } 39909b0fa60dSJoe Perches 3991b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3992b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3993b598b670SJoe Perches my $array = $1; 3994b598b670SJoe 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*\))@) { 3995b598b670SJoe Perches my $array_div = $1; 3996b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3997b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3998b598b670SJoe Perches $fix) { 3999b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 4000b598b670SJoe Perches } 4001b598b670SJoe Perches } 4002b598b670SJoe Perches } 4003b598b670SJoe Perches 4004b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 4005b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 4006b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 4007b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 4008b36190c5SJoe Perches $fix) { 4009194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 4010b36190c5SJoe Perches } 4011b36190c5SJoe Perches } 4012b36190c5SJoe Perches 4013653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 4014653d4876SAndy Whitcroft# make sense. 4015653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 40168054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 4017c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 40188ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 401946d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 4020000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 4021000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 40220a920b5bSAndy Whitcroft } 40230a920b5bSAndy Whitcroft 40240a920b5bSAndy Whitcroft# * goes on variable not on type 402565863862SAndy Whitcroft # (char*[ const]) 4026bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 4027bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 40283705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 4029d8aaf121SAndy Whitcroft 403065863862SAndy Whitcroft # Should start with a space. 403165863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 403265863862SAndy Whitcroft # Should not end with a space. 403365863862SAndy Whitcroft $to =~ s/\s+$//; 403465863862SAndy Whitcroft # '*'s should not have spaces between. 4035f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 403665863862SAndy Whitcroft } 4037d8aaf121SAndy Whitcroft 40383705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 403965863862SAndy Whitcroft if ($from ne $to) { 40403705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 40413705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 40423705ce5bSJoe Perches $fix) { 40433705ce5bSJoe Perches my $sub_from = $ident; 40443705ce5bSJoe Perches my $sub_to = $ident; 40453705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4046194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40473705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 40483705ce5bSJoe Perches } 404965863862SAndy Whitcroft } 4050bfcb2cc7SAndy Whitcroft } 4051bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 4052bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 40533705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 4054d8aaf121SAndy Whitcroft 405565863862SAndy Whitcroft # Should start with a space. 405665863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 405765863862SAndy Whitcroft # Should not end with a space. 405865863862SAndy Whitcroft $to =~ s/\s+$//; 405965863862SAndy Whitcroft # '*'s should not have spaces between. 4060f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 406165863862SAndy Whitcroft } 406265863862SAndy Whitcroft # Modifiers should have spaces. 406365863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 406465863862SAndy Whitcroft 40653705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 4066667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 40673705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 40683705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 40693705ce5bSJoe Perches $fix) { 40703705ce5bSJoe Perches 40713705ce5bSJoe Perches my $sub_from = $match; 40723705ce5bSJoe Perches my $sub_to = $match; 40733705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 4074194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40753705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 40763705ce5bSJoe Perches } 407765863862SAndy Whitcroft } 40780a920b5bSAndy Whitcroft } 40790a920b5bSAndy Whitcroft 40809d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 40819d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 40820675a8fbSJean Delvare my $msg_level = \&WARN; 40830675a8fbSJean Delvare $msg_level = \&CHK if ($file); 40840675a8fbSJean Delvare &{$msg_level}("AVOID_BUG", 40859d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 40869d3e3c70SJoe Perches } 40870a920b5bSAndy Whitcroft 40889d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 40898905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 4090000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 4091000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 40928905a67cSAndy Whitcroft } 40938905a67cSAndy Whitcroft 409417441227SJoe Perches# check for uses of printk_ratelimit 409517441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 4096000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 4097000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 409817441227SJoe Perches } 409917441227SJoe Perches 4100eeef5733SJoe Perches# printk should use KERN_* levels 4101eeef5733SJoe Perches if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { 4102000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 4103eeef5733SJoe Perches "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); 410400df344fSAndy Whitcroft } 41050a920b5bSAndy Whitcroft 4106243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 4107243f3803SJoe Perches my $orig = $1; 4108243f3803SJoe Perches my $level = lc($orig); 4109243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 41108f26b837SJoe Perches my $level2 = $level; 41118f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 4112243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 4113daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 4114243f3803SJoe Perches } 4115243f3803SJoe Perches 4116243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 4117d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 4118d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 4119d5e616fcSJoe Perches $fix) { 4120194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4121d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 4122d5e616fcSJoe Perches } 4123243f3803SJoe Perches } 4124243f3803SJoe Perches 4125dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 4126dc139313SJoe Perches my $orig = $1; 4127dc139313SJoe Perches my $level = lc($orig); 4128dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 4129dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 4130dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 4131dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 4132dc139313SJoe Perches } 4133dc139313SJoe Perches 413491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 413591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 413691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 413791c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 413891c9afafSAndy Lutomirski WARN("ENOSYS", 413991c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 414091c9afafSAndy Lutomirski } 414191c9afafSAndy Lutomirski 4142653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 4143653d4876SAndy Whitcroft# or if closed on same line 41445b57980dSJoe Perches if ($perl_version_ok && 41452d453e3bSJoe Perches $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && 41462d453e3bSJoe Perches $sline !~ /\#\s*define\b.*do\s*\{/ && 41472d453e3bSJoe Perches $sline !~ /}/) { 41488d182478SJoe Perches if (ERROR("OPEN_BRACE", 41492d453e3bSJoe Perches "open brace '{' following function definitions go on the next line\n" . $herecurr) && 41508d182478SJoe Perches $fix) { 41518d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 41528d182478SJoe Perches my $fixed_line = $rawline; 41538d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 41548d182478SJoe Perches my $line1 = $1; 41558d182478SJoe Perches my $line2 = $2; 41568d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 41578d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 41588d182478SJoe Perches if ($line2 !~ /^\s*$/) { 41598d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 41608d182478SJoe Perches } 41618d182478SJoe Perches } 41620a920b5bSAndy Whitcroft } 4163653d4876SAndy Whitcroft 41648905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 41658905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 41668905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 41678d182478SJoe Perches if (ERROR("OPEN_BRACE", 41688d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 41698d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 41708d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 41718d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 41728d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 41738d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 41748d182478SJoe Perches $fixedline = $rawline; 41758d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 41768d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 41778d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 41788d182478SJoe Perches } 41798d182478SJoe Perches } 41808905a67cSAndy Whitcroft } 41818905a67cSAndy Whitcroft 41820c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 41833705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 41843705ce5bSJoe Perches if (WARN("SPACING", 41853705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 41863705ce5bSJoe Perches $fix) { 4187194f66fcSJoe Perches $fixed[$fixlinenr] =~ 41883705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 41893705ce5bSJoe Perches } 41900c73b4ebSAndy Whitcroft } 41910c73b4ebSAndy Whitcroft 419231070b5dSJoe Perches# Function pointer declarations 419331070b5dSJoe Perches# check spacing between type, funcptr, and args 419431070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 419591f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 419631070b5dSJoe Perches my $declare = $1; 419731070b5dSJoe Perches my $pre_pointer_space = $2; 419831070b5dSJoe Perches my $post_pointer_space = $3; 419931070b5dSJoe Perches my $funcname = $4; 420031070b5dSJoe Perches my $post_funcname_space = $5; 420131070b5dSJoe Perches my $pre_args_space = $6; 420231070b5dSJoe Perches 420391f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 420491f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 420591f72e9cSJoe Perches# don't need a space so don't warn for those. 420691f72e9cSJoe Perches my $post_declare_space = ""; 420791f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 420891f72e9cSJoe Perches $post_declare_space = $1; 420991f72e9cSJoe Perches $declare = rtrim($declare); 421091f72e9cSJoe Perches } 421191f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 421231070b5dSJoe Perches WARN("SPACING", 421331070b5dSJoe Perches "missing space after return type\n" . $herecurr); 421491f72e9cSJoe Perches $post_declare_space = " "; 421531070b5dSJoe Perches } 421631070b5dSJoe Perches 421731070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 421891f72e9cSJoe Perches# This test is not currently implemented because these declarations are 421991f72e9cSJoe Perches# equivalent to 422091f72e9cSJoe Perches# int foo(int bar, ...) 422191f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 422291f72e9cSJoe Perches# 422391f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 422491f72e9cSJoe Perches# WARN("SPACING", 422591f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 422691f72e9cSJoe Perches# } 422731070b5dSJoe Perches 422831070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 422931070b5dSJoe Perches if (defined $pre_pointer_space && 423031070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 423131070b5dSJoe Perches WARN("SPACING", 423231070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 423331070b5dSJoe Perches } 423431070b5dSJoe Perches 423531070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 423631070b5dSJoe Perches if (defined $post_pointer_space && 423731070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 423831070b5dSJoe Perches WARN("SPACING", 423931070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 424031070b5dSJoe Perches } 424131070b5dSJoe Perches 424231070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 424331070b5dSJoe Perches if (defined $post_funcname_space && 424431070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 424531070b5dSJoe Perches WARN("SPACING", 424631070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 424731070b5dSJoe Perches } 424831070b5dSJoe Perches 424931070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 425031070b5dSJoe Perches if (defined $pre_args_space && 425131070b5dSJoe Perches $pre_args_space =~ /^\s/) { 425231070b5dSJoe Perches WARN("SPACING", 425331070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 425431070b5dSJoe Perches } 425531070b5dSJoe Perches 425631070b5dSJoe Perches if (show_type("SPACING") && $fix) { 4257194f66fcSJoe Perches $fixed[$fixlinenr] =~ 425891f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 425931070b5dSJoe Perches } 426031070b5dSJoe Perches } 426131070b5dSJoe Perches 42628d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 42638d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 4264fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 4265fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 42668d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 42678d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 42688d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 4269fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 427038dca988SHeinrich Schuchardt $prefix !~ /[{,:]\s+$/) { 42713705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 42723705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 42733705ce5bSJoe Perches $fix) { 4274194f66fcSJoe Perches $fixed[$fixlinenr] =~ 42753705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 42763705ce5bSJoe Perches } 42778d31cfceSAndy Whitcroft } 42788d31cfceSAndy Whitcroft } 42798d31cfceSAndy Whitcroft 4280f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 42816c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4282c2fdda0dSAndy Whitcroft my $name = $1; 4283773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4284773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4285c2fdda0dSAndy Whitcroft 4286c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4287773647a0SAndy Whitcroft if ($name =~ /^(?: 4288773647a0SAndy Whitcroft if|for|while|switch|return|case| 4289773647a0SAndy Whitcroft volatile|__volatile__| 4290773647a0SAndy Whitcroft __attribute__|format|__extension__| 4291773647a0SAndy Whitcroft asm|__asm__)$/x) 4292773647a0SAndy Whitcroft { 4293c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4294c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4295c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4296c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4297773647a0SAndy Whitcroft 4298773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4299c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4300c2fdda0dSAndy Whitcroft 4301c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4302c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4303773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4304c2fdda0dSAndy Whitcroft 4305c2fdda0dSAndy Whitcroft } else { 43063705ce5bSJoe Perches if (WARN("SPACING", 43073705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 43083705ce5bSJoe Perches $fix) { 4309194f66fcSJoe Perches $fixed[$fixlinenr] =~ 43103705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 43113705ce5bSJoe Perches } 4312f0a594c1SAndy Whitcroft } 43136c72ffaaSAndy Whitcroft } 43149a4cad4eSEric Nelson 4315653d4876SAndy Whitcroft# Check operator spacing. 43160a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 43173705ce5bSJoe Perches my $fixed_line = ""; 43183705ce5bSJoe Perches my $line_fixed = 0; 43193705ce5bSJoe Perches 43209c0ca6f9SAndy Whitcroft my $ops = qr{ 43219c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 43229c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 43239c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 43241f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 432584731623SJoe Perches \?:|\?|: 43269c0ca6f9SAndy Whitcroft }x; 4327cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 43283705ce5bSJoe Perches 43293705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 43303705ce5bSJoe Perches## foreach my $el (@elements) { 43313705ce5bSJoe Perches## print("el: <$el>\n"); 43323705ce5bSJoe Perches## } 43333705ce5bSJoe Perches 43343705ce5bSJoe Perches my @fix_elements = (); 433500df344fSAndy Whitcroft my $off = 0; 43366c72ffaaSAndy Whitcroft 43373705ce5bSJoe Perches foreach my $el (@elements) { 43383705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 43393705ce5bSJoe Perches $off += length($el); 43403705ce5bSJoe Perches } 43413705ce5bSJoe Perches 43423705ce5bSJoe Perches $off = 0; 43433705ce5bSJoe Perches 43446c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4345b34c648bSJoe Perches my $last_after = -1; 43466c72ffaaSAndy Whitcroft 43470a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 43483705ce5bSJoe Perches 43493705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 43503705ce5bSJoe Perches 43513705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 43523705ce5bSJoe Perches 43534a0df2efSAndy Whitcroft $off += length($elements[$n]); 43544a0df2efSAndy Whitcroft 435525985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4356773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4357773647a0SAndy Whitcroft my $cc = ''; 4358773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4359773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4360773647a0SAndy Whitcroft } 4361773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4362773647a0SAndy Whitcroft 43634a0df2efSAndy Whitcroft my $a = ''; 43644a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 43654a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4366cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 43674a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 43684a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4369773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 43704a0df2efSAndy Whitcroft 43710a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 43724a0df2efSAndy Whitcroft 43734a0df2efSAndy Whitcroft my $c = ''; 43740a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 43754a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 43764a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4377cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 43784a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 43794a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 43808b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 43814a0df2efSAndy Whitcroft } else { 43824a0df2efSAndy Whitcroft $c = 'E'; 43830a920b5bSAndy Whitcroft } 43840a920b5bSAndy Whitcroft 43854a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 43864a0df2efSAndy Whitcroft 43874a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 43884a0df2efSAndy Whitcroft 43896c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4390de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 43910a920b5bSAndy Whitcroft 439274048ed8SAndy Whitcroft # Pull out the value of this operator. 43936c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 43940a920b5bSAndy Whitcroft 43951f65f947SAndy Whitcroft # Get the full operator variant. 43961f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 43971f65f947SAndy Whitcroft 439813214adfSAndy Whitcroft # Ignore operators passed as parameters. 439913214adfSAndy Whitcroft if ($op_type ne 'V' && 4400d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 440113214adfSAndy Whitcroft 4402cf655043SAndy Whitcroft# # Ignore comments 4403cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 440413214adfSAndy Whitcroft 4405d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 440613214adfSAndy Whitcroft } elsif ($op eq ';') { 4407cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4408cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 44093705ce5bSJoe Perches if (ERROR("SPACING", 44103705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4411b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 44123705ce5bSJoe Perches $line_fixed = 1; 44133705ce5bSJoe Perches } 4414d8aaf121SAndy Whitcroft } 4415d8aaf121SAndy Whitcroft 4416d8aaf121SAndy Whitcroft # // is a comment 4417d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 44180a920b5bSAndy Whitcroft 4419b00e4814SJoe Perches # : when part of a bitfield 4420b00e4814SJoe Perches } elsif ($opv eq ':B') { 4421b00e4814SJoe Perches # skip the bitfield test for now 4422b00e4814SJoe Perches 44231f65f947SAndy Whitcroft # No spaces for: 44241f65f947SAndy Whitcroft # -> 4425b00e4814SJoe Perches } elsif ($op eq '->') { 44264a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 44273705ce5bSJoe Perches if (ERROR("SPACING", 44283705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4429b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 44303705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 44313705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 44323705ce5bSJoe Perches } 4433b34c648bSJoe Perches $line_fixed = 1; 44343705ce5bSJoe Perches } 44350a920b5bSAndy Whitcroft } 44360a920b5bSAndy Whitcroft 44372381097bSJoe Perches # , must not have a space before and must have a space on the right. 44380a920b5bSAndy Whitcroft } elsif ($op eq ',') { 44392381097bSJoe Perches my $rtrim_before = 0; 44402381097bSJoe Perches my $space_after = 0; 44412381097bSJoe Perches if ($ctx =~ /Wx./) { 44422381097bSJoe Perches if (ERROR("SPACING", 44432381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 44442381097bSJoe Perches $line_fixed = 1; 44452381097bSJoe Perches $rtrim_before = 1; 44462381097bSJoe Perches } 44472381097bSJoe Perches } 4448cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 44493705ce5bSJoe Perches if (ERROR("SPACING", 44503705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 44513705ce5bSJoe Perches $line_fixed = 1; 4452b34c648bSJoe Perches $last_after = $n; 44532381097bSJoe Perches $space_after = 1; 44542381097bSJoe Perches } 44552381097bSJoe Perches } 44562381097bSJoe Perches if ($rtrim_before || $space_after) { 44572381097bSJoe Perches if ($rtrim_before) { 44582381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 44592381097bSJoe Perches } else { 44602381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 44612381097bSJoe Perches } 44622381097bSJoe Perches if ($space_after) { 44632381097bSJoe Perches $good .= " "; 44643705ce5bSJoe Perches } 44650a920b5bSAndy Whitcroft } 44660a920b5bSAndy Whitcroft 44679c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 446874048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 44699c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 44709c0ca6f9SAndy Whitcroft 44719c0ca6f9SAndy Whitcroft # unary operators should have a space before and 44729c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 44739c0ca6f9SAndy Whitcroft # unary operator, or a cast 44749c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 447574048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 44760d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4477cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 44783705ce5bSJoe Perches if (ERROR("SPACING", 44793705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4480b34c648bSJoe Perches if ($n != $last_after + 2) { 4481b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 44823705ce5bSJoe Perches $line_fixed = 1; 44833705ce5bSJoe Perches } 44840a920b5bSAndy Whitcroft } 4485b34c648bSJoe Perches } 4486a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4487171ae1a4SAndy Whitcroft # A unary '*' may be const 4488171ae1a4SAndy Whitcroft 4489171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 44903705ce5bSJoe Perches if (ERROR("SPACING", 44913705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4492b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 44933705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 44943705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 44953705ce5bSJoe Perches } 4496b34c648bSJoe Perches $line_fixed = 1; 44973705ce5bSJoe Perches } 44980a920b5bSAndy Whitcroft } 44990a920b5bSAndy Whitcroft 45000a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 45010a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4502773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 45033705ce5bSJoe Perches if (ERROR("SPACING", 45043705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4505b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 45063705ce5bSJoe Perches $line_fixed = 1; 45073705ce5bSJoe Perches } 45080a920b5bSAndy Whitcroft } 4509773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4510773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 45113705ce5bSJoe Perches if (ERROR("SPACING", 45123705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4513b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45143705ce5bSJoe Perches $line_fixed = 1; 45153705ce5bSJoe Perches } 4516653d4876SAndy Whitcroft } 4517773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 45183705ce5bSJoe Perches if (ERROR("SPACING", 45193705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4520b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 45213705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 45223705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4523773647a0SAndy Whitcroft } 4524b34c648bSJoe Perches $line_fixed = 1; 45253705ce5bSJoe Perches } 45263705ce5bSJoe Perches } 45270a920b5bSAndy Whitcroft 45280a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 45299c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 45309c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 45319c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4532c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4533c2fdda0dSAndy Whitcroft $op eq '%') 45340a920b5bSAndy Whitcroft { 4535d2e025f3SJoe Perches if ($check) { 4536d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4537d2e025f3SJoe Perches if (CHK("SPACING", 4538d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4539d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4540d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4541d2e025f3SJoe Perches $line_fixed = 1; 4542d2e025f3SJoe Perches } 4543d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4544d2e025f3SJoe Perches if (CHK("SPACING", 4545d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4546d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4547d2e025f3SJoe Perches $line_fixed = 1; 4548d2e025f3SJoe Perches } 4549d2e025f3SJoe Perches } 4550d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 45513705ce5bSJoe Perches if (ERROR("SPACING", 45523705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4553b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4554b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4555b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4556b34c648bSJoe Perches } 45573705ce5bSJoe Perches $line_fixed = 1; 45583705ce5bSJoe Perches } 45590a920b5bSAndy Whitcroft } 45600a920b5bSAndy Whitcroft 45611f65f947SAndy Whitcroft # A colon needs no spaces before when it is 45621f65f947SAndy Whitcroft # terminating a case value or a label. 45631f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 45641f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 45653705ce5bSJoe Perches if (ERROR("SPACING", 45663705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4567b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 45683705ce5bSJoe Perches $line_fixed = 1; 45693705ce5bSJoe Perches } 45701f65f947SAndy Whitcroft } 45711f65f947SAndy Whitcroft 45720a920b5bSAndy Whitcroft # All the others need spaces both sides. 4573cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 45741f65f947SAndy Whitcroft my $ok = 0; 45751f65f947SAndy Whitcroft 457622f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 45771f65f947SAndy Whitcroft if (($op eq '<' && 45781f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 45791f65f947SAndy Whitcroft ($op eq '>' && 45801f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 45811f65f947SAndy Whitcroft { 45821f65f947SAndy Whitcroft $ok = 1; 45831f65f947SAndy Whitcroft } 45841f65f947SAndy Whitcroft 4585e0df7e1fSJoe Perches # for asm volatile statements 4586e0df7e1fSJoe Perches # ignore a colon with another 4587e0df7e1fSJoe Perches # colon immediately before or after 4588e0df7e1fSJoe Perches if (($op eq ':') && 4589e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4590e0df7e1fSJoe Perches $ok = 1; 4591e0df7e1fSJoe Perches } 4592e0df7e1fSJoe Perches 459384731623SJoe Perches # messages are ERROR, but ?: are CHK 45941f65f947SAndy Whitcroft if ($ok == 0) { 45950675a8fbSJean Delvare my $msg_level = \&ERROR; 45960675a8fbSJean Delvare $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 459784731623SJoe Perches 45980675a8fbSJean Delvare if (&{$msg_level}("SPACING", 45993705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4600b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4601b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4602b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4603b34c648bSJoe Perches } 46043705ce5bSJoe Perches $line_fixed = 1; 46053705ce5bSJoe Perches } 46060a920b5bSAndy Whitcroft } 460722f2a2efSAndy Whitcroft } 46084a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 46093705ce5bSJoe Perches 46103705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 46113705ce5bSJoe Perches 46123705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 46130a920b5bSAndy Whitcroft } 46143705ce5bSJoe Perches 46153705ce5bSJoe Perches if (($#elements % 2) == 0) { 46163705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 46173705ce5bSJoe Perches } 46183705ce5bSJoe Perches 4619194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4620194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 46213705ce5bSJoe Perches } 46223705ce5bSJoe Perches 46233705ce5bSJoe Perches 46240a920b5bSAndy Whitcroft } 46250a920b5bSAndy Whitcroft 4626786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4627d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4628786b6326SJoe Perches if (WARN("SPACING", 4629786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4630786b6326SJoe Perches $fix) { 4631194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4632786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4633786b6326SJoe Perches } 4634786b6326SJoe Perches } 4635786b6326SJoe Perches 4636f0a594c1SAndy Whitcroft# check for multiple assignments 4637f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4638000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4639000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4640f0a594c1SAndy Whitcroft } 4641f0a594c1SAndy Whitcroft 464222f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 464322f2a2efSAndy Whitcroft## # continuation. 464422f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 464522f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 464622f2a2efSAndy Whitcroft## 464722f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 464822f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 464922f2a2efSAndy Whitcroft## my $ln = $line; 465022f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 465122f2a2efSAndy Whitcroft## } 465222f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4653000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4654000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 465522f2a2efSAndy Whitcroft## } 465622f2a2efSAndy Whitcroft## } 4657f0a594c1SAndy Whitcroft 46580a920b5bSAndy Whitcroft#need space before brace following if, while, etc 46596b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 46606ad724e2SMichal Zylowski $line =~ /\b(?:else|do)\{/) { 46613705ce5bSJoe Perches if (ERROR("SPACING", 46623705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 46633705ce5bSJoe Perches $fix) { 46646ad724e2SMichal Zylowski $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; 46653705ce5bSJoe Perches } 4666de7d4f0eSAndy Whitcroft } 4667de7d4f0eSAndy Whitcroft 4668c4a62ef9SJoe Perches## # check for blank lines before declarations 4669c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4670c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4671c4a62ef9SJoe Perches## WARN("SPACING", 4672c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4673c4a62ef9SJoe Perches## } 4674c4a62ef9SJoe Perches## 4675c4a62ef9SJoe Perches 4676de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4677de7d4f0eSAndy Whitcroft# on the line 467894fb9845SJoe Perches if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { 4679d5e616fcSJoe Perches if (ERROR("SPACING", 4680d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4681d5e616fcSJoe Perches $fix) { 4682194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4683d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4684d5e616fcSJoe Perches } 46850a920b5bSAndy Whitcroft } 46860a920b5bSAndy Whitcroft 468722f2a2efSAndy Whitcroft# check spacing on square brackets 468822f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 46893705ce5bSJoe Perches if (ERROR("SPACING", 46903705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 46913705ce5bSJoe Perches $fix) { 4692194f66fcSJoe Perches $fixed[$fixlinenr] =~ 46933705ce5bSJoe Perches s/\[\s+/\[/; 46943705ce5bSJoe Perches } 469522f2a2efSAndy Whitcroft } 469622f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 46973705ce5bSJoe Perches if (ERROR("SPACING", 46983705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 46993705ce5bSJoe Perches $fix) { 4700194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47013705ce5bSJoe Perches s/\s+\]/\]/; 47023705ce5bSJoe Perches } 470322f2a2efSAndy Whitcroft } 470422f2a2efSAndy Whitcroft 4705c45dcabdSAndy Whitcroft# check spacing on parentheses 47069c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 47079c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 47083705ce5bSJoe Perches if (ERROR("SPACING", 47093705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 47103705ce5bSJoe Perches $fix) { 4711194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47123705ce5bSJoe Perches s/\(\s+/\(/; 47133705ce5bSJoe Perches } 471422f2a2efSAndy Whitcroft } 471513214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4716c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4717c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 47183705ce5bSJoe Perches if (ERROR("SPACING", 47193705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 47203705ce5bSJoe Perches $fix) { 4721194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47223705ce5bSJoe Perches s/\s+\)/\)/; 47233705ce5bSJoe Perches } 472422f2a2efSAndy Whitcroft } 472522f2a2efSAndy Whitcroft 4726e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4727e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4728e2826fd0SJoe Perches 4729e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4730ea4acbb1SJoe Perches my $var = $1; 4731ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4732ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4733ea4acbb1SJoe Perches $fix) { 4734ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4735ea4acbb1SJoe Perches } 4736ea4acbb1SJoe Perches } 4737ea4acbb1SJoe Perches 4738ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4739ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4740ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4741ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4742ea4acbb1SJoe Perches my $var = $2; 4743ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4744ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4745ea4acbb1SJoe Perches $fix) { 4746ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4747ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4748ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4749ea4acbb1SJoe Perches } 4750e2826fd0SJoe Perches } 4751e2826fd0SJoe Perches 475263b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses 4753a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict 4754a032aa4cSJoe Perches if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && 47555b57980dSJoe Perches $perl_version_ok && defined($stat) && 475663b7c73eSJoe Perches $stat =~ /(^.\s*if\s*($balanced_parens))/) { 475763b7c73eSJoe Perches my $if_stat = $1; 475863b7c73eSJoe Perches my $test = substr($2, 1, -1); 475963b7c73eSJoe Perches my $herectx; 476063b7c73eSJoe Perches while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { 476163b7c73eSJoe Perches my $match = $1; 476263b7c73eSJoe Perches # avoid parentheses around potential macro args 476363b7c73eSJoe Perches next if ($match =~ /^\s*\w+\s*$/); 476463b7c73eSJoe Perches if (!defined($herectx)) { 476563b7c73eSJoe Perches $herectx = $here . "\n"; 476663b7c73eSJoe Perches my $cnt = statement_rawlines($if_stat); 476763b7c73eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 476863b7c73eSJoe Perches my $rl = raw_line($linenr, $n); 476963b7c73eSJoe Perches $herectx .= $rl . "\n"; 477063b7c73eSJoe Perches last if $rl =~ /^[ \+].*\{/; 477163b7c73eSJoe Perches } 477263b7c73eSJoe Perches } 477363b7c73eSJoe Perches CHK("UNNECESSARY_PARENTHESES", 477463b7c73eSJoe Perches "Unnecessary parentheses around '$match'\n" . $herectx); 477563b7c73eSJoe Perches } 477663b7c73eSJoe Perches } 477763b7c73eSJoe Perches 47780a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 47794a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 47800a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 47813705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 47823705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 47833705ce5bSJoe Perches $fix) { 4784194f66fcSJoe Perches $fixed[$fixlinenr] =~ 47853705ce5bSJoe Perches s/^(.)\s+/$1/; 47863705ce5bSJoe Perches } 47870a920b5bSAndy Whitcroft } 47880a920b5bSAndy Whitcroft 47895b9553abSJoe Perches# return is not a function 4790507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4791c45dcabdSAndy Whitcroft my $spacing = $1; 47925b57980dSJoe Perches if ($perl_version_ok && 47935b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 47945b9553abSJoe Perches my $value = $1; 47955b9553abSJoe Perches $value = deparenthesize($value); 47965b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4797000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4798000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 47995b9553abSJoe Perches } 4800c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4801000d1cc1SJoe Perches ERROR("SPACING", 4802000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4803c45dcabdSAndy Whitcroft } 4804c45dcabdSAndy Whitcroft } 4805507e5141SJoe Perches 4806b43ae21bSJoe Perches# unnecessary return in a void function 4807b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4808b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4809b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4810b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4811b43ae21bSJoe Perches $linenr >= 3 && 4812b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4813b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 48149819cf25SJoe Perches WARN("RETURN_VOID", 4815b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 48169819cf25SJoe Perches } 48179819cf25SJoe Perches 4818189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 48195b57980dSJoe Perches if ($perl_version_ok && 4820189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4821189248d8SJoe Perches my $openparens = $1; 4822189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4823189248d8SJoe Perches my $msg = ""; 4824189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4825189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4826189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4827189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4828189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4829189248d8SJoe Perches } 4830189248d8SJoe Perches } 4831189248d8SJoe Perches 4832c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4833c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4834c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4835c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 48365b57980dSJoe Perches if ($perl_version_ok && 4837c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4838c5595fa2SJoe Perches my $lead = $1; 4839c5595fa2SJoe Perches my $const = $2; 4840c5595fa2SJoe Perches my $comp = $3; 4841c5595fa2SJoe Perches my $to = $4; 4842c5595fa2SJoe Perches my $newcomp = $comp; 4843f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4844c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4845c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4846c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4847c5595fa2SJoe Perches $fix) { 4848c5595fa2SJoe Perches if ($comp eq "<") { 4849c5595fa2SJoe Perches $newcomp = ">"; 4850c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4851c5595fa2SJoe Perches $newcomp = ">="; 4852c5595fa2SJoe Perches } elsif ($comp eq ">") { 4853c5595fa2SJoe Perches $newcomp = "<"; 4854c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4855c5595fa2SJoe Perches $newcomp = "<="; 4856c5595fa2SJoe Perches } 4857c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4858c5595fa2SJoe Perches } 4859c5595fa2SJoe Perches } 4860c5595fa2SJoe Perches 4861f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4862f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 486353a3c448SAndy Whitcroft my $name = $1; 486453a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4865000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4866f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 486753a3c448SAndy Whitcroft } 486853a3c448SAndy Whitcroft } 4869c45dcabdSAndy Whitcroft 48700a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 48714a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 48723705ce5bSJoe Perches if (ERROR("SPACING", 48733705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 48743705ce5bSJoe Perches $fix) { 4875194f66fcSJoe Perches $fixed[$fixlinenr] =~ 48763705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 48773705ce5bSJoe Perches } 48780a920b5bSAndy Whitcroft } 48790a920b5bSAndy Whitcroft 4880f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4881f5fe35ddSAndy Whitcroft# statements after the conditional. 4882170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 48833e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 48843e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 48853e469cdcSAndy Whitcroft if (!defined $stat); 4886170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4887170d3a22SAndy Whitcroft $remain_next, $off_next); 4888170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4889170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4890170d3a22SAndy Whitcroft 4891170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4892170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4893170d3a22SAndy Whitcroft # then count those as offsets. 4894170d3a22SAndy Whitcroft my ($whitespace) = 4895170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4896170d3a22SAndy Whitcroft my $offset = 4897170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4898170d3a22SAndy Whitcroft 4899170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4900170d3a22SAndy Whitcroft $offset} = 1; 4901170d3a22SAndy Whitcroft } 4902170d3a22SAndy Whitcroft } 4903170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4904c11230f4SJoe Perches defined($stat) && defined($cond) && 4905170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4906171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 49078905a67cSAndy Whitcroft 4908b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4909000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4910000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 49118905a67cSAndy Whitcroft } 49128905a67cSAndy Whitcroft 49138905a67cSAndy Whitcroft # Find out what is on the end of the line after the 49148905a67cSAndy Whitcroft # conditional. 4915773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 49168905a67cSAndy Whitcroft $s =~ s/\n.*//g; 491713214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 491853210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 491953210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4920773647a0SAndy Whitcroft { 4921bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4922bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4923bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 492442bdf74cSHidetoshi Seto my $stat_real = ''; 4925bb44ad39SAndy Whitcroft 492642bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 492742bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4928bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4929bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4930bb44ad39SAndy Whitcroft } 4931bb44ad39SAndy Whitcroft 4932000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4933000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 49348905a67cSAndy Whitcroft } 49358905a67cSAndy Whitcroft } 49368905a67cSAndy Whitcroft 493713214adfSAndy Whitcroft# Check for bitwise tests written as boolean 493813214adfSAndy Whitcroft if ($line =~ / 493913214adfSAndy Whitcroft (?: 494013214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 494113214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 494213214adfSAndy Whitcroft (?:\&\&|\|\|) 494313214adfSAndy Whitcroft | 494413214adfSAndy Whitcroft (?:\&\&|\|\|) 494513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 494613214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 494713214adfSAndy Whitcroft )/x) 494813214adfSAndy Whitcroft { 4949000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4950000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 495113214adfSAndy Whitcroft } 495213214adfSAndy Whitcroft 49538905a67cSAndy Whitcroft# if and else should not have general statements after it 495413214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 495513214adfSAndy Whitcroft my $s = $1; 495613214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 495713214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4958000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4959000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 49600a920b5bSAndy Whitcroft } 496113214adfSAndy Whitcroft } 496239667782SAndy Whitcroft# if should not continue a brace 496339667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4964000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4965048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 496639667782SAndy Whitcroft $herecurr); 496739667782SAndy Whitcroft } 4968a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4969a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4970a1080bf8SAndy Whitcroft $line !~ /\G(?: 49713fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4972a1080bf8SAndy Whitcroft \s*return\s+ 4973a1080bf8SAndy Whitcroft )/xg) 4974a1080bf8SAndy Whitcroft { 4975000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4976000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4977a1080bf8SAndy Whitcroft } 49780a920b5bSAndy Whitcroft 49790a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 49800a920b5bSAndy Whitcroft # indent level to be relevant to each other. 49818b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 49820a920b5bSAndy Whitcroft $previndent == $indent) { 49838b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 49848b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 49858b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 49868b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 49878b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 49888b8856f4SJoe Perches my $fixedline = $prevrawline; 49898b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 49908b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 49918b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 49928b8856f4SJoe Perches } 49938b8856f4SJoe Perches $fixedline = $rawline; 49948b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 49958b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 49968b8856f4SJoe Perches } 49970a920b5bSAndy Whitcroft } 49980a920b5bSAndy Whitcroft 49998b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 5000c2fdda0dSAndy Whitcroft $previndent == $indent) { 5001c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 5002c2fdda0dSAndy Whitcroft 5003c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 5004c2fdda0dSAndy Whitcroft # conditional. 5005773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 5006c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 5007c2fdda0dSAndy Whitcroft 5008c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 50098b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 50108b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 50118b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 50128b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 50138b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 50148b8856f4SJoe Perches my $fixedline = $prevrawline; 50158b8856f4SJoe Perches my $trailing = $rawline; 50168b8856f4SJoe Perches $trailing =~ s/^\+//; 50178b8856f4SJoe Perches $trailing = trim($trailing); 50188b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 50198b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 50208b8856f4SJoe Perches } 5021c2fdda0dSAndy Whitcroft } 5022c2fdda0dSAndy Whitcroft } 5023c2fdda0dSAndy Whitcroft 502495e2c602SJoe Perches#Specific variable tests 5025323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 5026323c1260SJoe Perches my $var = $1; 502795e2c602SJoe Perches 502895e2c602SJoe Perches#CamelCase 5029807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 5030be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 503122735ce8SJoe Perches#Ignore Page<foo> variants 5032807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 503322735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 5034f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 5035f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 5036f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 50377e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 50387e781f67SJoe Perches my $word = $1; 50397e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 5040d8b07710SJoe Perches if ($check) { 5041d8b07710SJoe Perches seed_camelcase_includes(); 5042d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 5043d8b07710SJoe Perches seed_camelcase_file($realfile); 5044d8b07710SJoe Perches $camelcase_file_seeded = 1; 5045d8b07710SJoe Perches } 5046d8b07710SJoe Perches } 50477e781f67SJoe Perches if (!defined $camelcase{$word}) { 50487e781f67SJoe Perches $camelcase{$word} = 1; 5049be79794bSJoe Perches CHK("CAMELCASE", 50507e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 50517e781f67SJoe Perches } 5052323c1260SJoe Perches } 5053323c1260SJoe Perches } 50543445686aSJoe Perches } 50550a920b5bSAndy Whitcroft 50560a920b5bSAndy Whitcroft#no spaces allowed after \ in define 5057d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 5058d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 5059d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 5060d5e616fcSJoe Perches $fix) { 5061194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 5062d5e616fcSJoe Perches } 50630a920b5bSAndy Whitcroft } 50640a920b5bSAndy Whitcroft 50650e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 50660e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 5067c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 5068e09dec48SAndy Whitcroft my $file = "$1.h"; 5069e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 5070e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 5071e09dec48SAndy Whitcroft $realfile ne $checkfile && 50727840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 5073c45dcabdSAndy Whitcroft { 50740e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 50750e212e0aSFabian Frederick if ($asminclude > 0) { 5076e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 5077000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 5078000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5079e09dec48SAndy Whitcroft } else { 5080000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 5081000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 5082e09dec48SAndy Whitcroft } 50830a920b5bSAndy Whitcroft } 50840a920b5bSAndy Whitcroft } 50850e212e0aSFabian Frederick } 50860a920b5bSAndy Whitcroft 5087653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 5088653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 5089cf655043SAndy Whitcroft# in a known good container 5090b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 5091b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5092d8aaf121SAndy Whitcroft my $ln = $linenr; 5093d8aaf121SAndy Whitcroft my $cnt = $realcnt; 5094c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 5095c45dcabdSAndy Whitcroft my $ctx = ''; 509608a2843eSJoe Perches my $has_flow_statement = 0; 509708a2843eSJoe Perches my $has_arg_concat = 0; 5098c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 5099f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 5100f74bd194SAndy Whitcroft $ctx = $dstat; 5101c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 5102a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 5103c45dcabdSAndy Whitcroft 510408a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 510562e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 510608a2843eSJoe Perches 5107f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 5108f59b64bfSJoe Perches my $define_args = $1; 5109f59b64bfSJoe Perches my $define_stmt = $dstat; 5110f59b64bfSJoe Perches my @def_args = (); 5111f59b64bfSJoe Perches 5112f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 5113f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 5114f59b64bfSJoe Perches $define_args =~ s/\s*//g; 51158c8c45cfSJoe Perches $define_args =~ s/\\\+?//g; 5116f59b64bfSJoe Perches @def_args = split(",", $define_args); 5117f59b64bfSJoe Perches } 5118f59b64bfSJoe Perches 5119292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 5120c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 5121c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 5122c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 5123c45dcabdSAndy Whitcroft 5124c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 5125bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 5126bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 51276b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 5128bf30d6edSAndy Whitcroft { 5129c45dcabdSAndy Whitcroft } 5130c45dcabdSAndy Whitcroft 5131e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 513233acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 513333acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 5134e45bab8eSAndy Whitcroft { 5135e45bab8eSAndy Whitcroft } 5136e45bab8eSAndy Whitcroft 513742e15293SJoe Perches # Make asm volatile uses seem like a generic function 513842e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 513942e15293SJoe Perches 5140c45dcabdSAndy Whitcroft my $exceptions = qr{ 5141c45dcabdSAndy Whitcroft $Declare| 5142c45dcabdSAndy Whitcroft module_param_named| 5143a0a0a7a9SKees Cook MODULE_PARM_DESC| 5144c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 5145c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 5146383099fdSAndy Whitcroft __typeof__\(| 514722fd2d3eSStefani Seibold union| 514822fd2d3eSStefani Seibold struct| 5149ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 51506b10df42SVladimir Zapolskiy ^\"|\"$| 51516b10df42SVladimir Zapolskiy ^\[ 5152c45dcabdSAndy Whitcroft }x; 51535eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 5154f59b64bfSJoe Perches 5155f59b64bfSJoe Perches $ctx =~ s/\n*$//; 5156f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 5157e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 5158f59b64bfSJoe Perches 5159f74bd194SAndy Whitcroft if ($dstat ne '' && 5160f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 5161f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 51623cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 5163356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 5164f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 5165f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 5166e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 516772f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 5168f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 5169f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 5170f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 51714e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 5172f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 5173c45dcabdSAndy Whitcroft { 5174e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 5175e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5176e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5177e795556aSJoe Perches } elsif ($dstat =~ /;/) { 5178f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5179f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5180f74bd194SAndy Whitcroft } else { 5181000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 5182388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5183d8aaf121SAndy Whitcroft } 5184f59b64bfSJoe Perches 5185f59b64bfSJoe Perches } 51865207649bSJoe Perches 51875207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 51885207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 51895207649bSJoe Perches my $first = 1; 51905207649bSJoe Perches $define_stmt = ""; 51915207649bSJoe Perches foreach my $l (@stmt_array) { 51925207649bSJoe Perches $l =~ s/\\$//; 51935207649bSJoe Perches if ($first) { 51945207649bSJoe Perches $define_stmt = $l; 51955207649bSJoe Perches $first = 0; 51965207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 51975207649bSJoe Perches $define_stmt .= substr($l, 1); 51985207649bSJoe Perches } 51995207649bSJoe Perches } 52005207649bSJoe Perches $define_stmt =~ s/$;//g; 52015207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 52025207649bSJoe Perches $define_stmt = trim($define_stmt); 52035207649bSJoe Perches 5204f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 5205f59b64bfSJoe Perches foreach my $arg (@def_args) { 5206f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 52079192d41aSJoe Perches next if ($arg =~ /^type$/i); 52087fe528a2SJoe Perches my $tmp_stmt = $define_stmt; 52096dba824eSBrendan Jackman $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 52107fe528a2SJoe Perches $tmp_stmt =~ s/\#+\s*$arg\b//g; 52117fe528a2SJoe Perches $tmp_stmt =~ s/\b$arg\s*\#\#//g; 5212d41362edSJoe Perches my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; 5213f59b64bfSJoe Perches if ($use_cnt > 1) { 5214f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 5215f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 5216f59b64bfSJoe Perches } 52179192d41aSJoe Perches# check if any macro arguments may have other precedence issues 52187fe528a2SJoe Perches if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 52199192d41aSJoe Perches ((defined($1) && $1 ne ',') || 52209192d41aSJoe Perches (defined($2) && $2 ne ','))) { 52219192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 52229192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 52239192d41aSJoe Perches } 52240a920b5bSAndy Whitcroft } 52255023d347SJoe Perches 522608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 522708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 522808a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 522908a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 5230e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 523108a2843eSJoe Perches 523208a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 523308a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 523408a2843eSJoe Perches } 523508a2843eSJoe Perches 5236481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 52375023d347SJoe Perches 52385023d347SJoe Perches } else { 52395023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 5240481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 5241481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 52425023d347SJoe Perches $line =~ /^\+.*\\$/) { 52435023d347SJoe Perches WARN("LINE_CONTINUATIONS", 52445023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 52455023d347SJoe Perches } 5246653d4876SAndy Whitcroft } 52470a920b5bSAndy Whitcroft 5248b13edf7fSJoe Perches# do {} while (0) macro tests: 5249b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 5250b13edf7fSJoe Perches# macro should not end with a semicolon 52515b57980dSJoe Perches if ($perl_version_ok && 5252b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 5253b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 5254b13edf7fSJoe Perches my $ln = $linenr; 5255b13edf7fSJoe Perches my $cnt = $realcnt; 5256b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 5257b13edf7fSJoe Perches my $ctx = ''; 5258b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 5259b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 5260b13edf7fSJoe Perches $ctx = $dstat; 5261b13edf7fSJoe Perches 5262b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 52631b36b201SJoe Perches $dstat =~ s/$;/ /g; 5264b13edf7fSJoe Perches 5265b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 5266b13edf7fSJoe Perches my $stmts = $2; 5267b13edf7fSJoe Perches my $semis = $3; 5268b13edf7fSJoe Perches 5269b13edf7fSJoe Perches $ctx =~ s/\n*$//; 5270b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 5271e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5272b13edf7fSJoe Perches 5273ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 5274ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 5275b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 5276b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 5277b13edf7fSJoe Perches } 5278b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 5279b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 5280b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5281b13edf7fSJoe Perches } 5282f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5283f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5284f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5285e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5286f5ef95b1SJoe Perches 5287f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5288f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5289b13edf7fSJoe Perches } 5290b13edf7fSJoe Perches } 5291b13edf7fSJoe Perches 5292f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 529313214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 529413214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5295cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 529613214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5297cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5298cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5299aad4f614SJoe Perches my @allowed = (); 5300aad4f614SJoe Perches my $allow = 0; 530113214adfSAndy Whitcroft my $seen = 0; 5302773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5303cf655043SAndy Whitcroft my $ln = $linenr - 1; 530413214adfSAndy Whitcroft for my $chunk (@chunks) { 530513214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 530613214adfSAndy Whitcroft 5307773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5308773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5309773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5310773647a0SAndy Whitcroft 5311aad4f614SJoe Perches $allowed[$allow] = 0; 5312773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5313773647a0SAndy Whitcroft 5314773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5315773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5316773647a0SAndy Whitcroft 5317773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5318cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5319cf655043SAndy Whitcroft 5320773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 532113214adfSAndy Whitcroft 532213214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 532313214adfSAndy Whitcroft 5324aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5325cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5326cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5327aad4f614SJoe Perches $allowed[$allow] = 1; 532813214adfSAndy Whitcroft } 532913214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5330cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5331aad4f614SJoe Perches $allowed[$allow] = 1; 533213214adfSAndy Whitcroft } 5333cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5334cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5335aad4f614SJoe Perches $allowed[$allow] = 1; 533613214adfSAndy Whitcroft } 5337aad4f614SJoe Perches $allow++; 533813214adfSAndy Whitcroft } 5339aad4f614SJoe Perches if ($seen) { 5340aad4f614SJoe Perches my $sum_allowed = 0; 5341aad4f614SJoe Perches foreach (@allowed) { 5342aad4f614SJoe Perches $sum_allowed += $_; 5343aad4f614SJoe Perches } 5344aad4f614SJoe Perches if ($sum_allowed == 0) { 5345000d1cc1SJoe Perches WARN("BRACES", 5346000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5347aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5348aad4f614SJoe Perches $seen != $allow) { 5349aad4f614SJoe Perches CHK("BRACES", 5350aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5351aad4f614SJoe Perches } 535213214adfSAndy Whitcroft } 535313214adfSAndy Whitcroft } 535413214adfSAndy Whitcroft } 5355773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 535613214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5357cf655043SAndy Whitcroft my $allowed = 0; 5358f0a594c1SAndy Whitcroft 5359cf655043SAndy Whitcroft # Check the pre-context. 5360cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5361cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5362cf655043SAndy Whitcroft $allowed = 1; 5363f0a594c1SAndy Whitcroft } 5364773647a0SAndy Whitcroft 5365773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5366773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5367773647a0SAndy Whitcroft 5368cf655043SAndy Whitcroft # Check the condition. 5369cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5370773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5371cf655043SAndy Whitcroft if (defined $cond) { 5372773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5373cf655043SAndy Whitcroft } 5374cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5375cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5376cf655043SAndy Whitcroft $allowed = 1; 5377cf655043SAndy Whitcroft } 5378cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5379cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5380cf655043SAndy Whitcroft $allowed = 1; 5381cf655043SAndy Whitcroft } 5382cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5383cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5384cf655043SAndy Whitcroft $allowed = 1; 5385cf655043SAndy Whitcroft } 5386cf655043SAndy Whitcroft # Check the post-context. 5387cf655043SAndy Whitcroft if (defined $chunks[1]) { 5388cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5389cf655043SAndy Whitcroft if (defined $cond) { 5390773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5391cf655043SAndy Whitcroft } 5392cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5393cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5394cf655043SAndy Whitcroft $allowed = 1; 5395cf655043SAndy Whitcroft } 5396cf655043SAndy Whitcroft } 5397cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 5398f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5399e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 5400cf655043SAndy Whitcroft 5401000d1cc1SJoe Perches WARN("BRACES", 5402000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5403f0a594c1SAndy Whitcroft } 5404f0a594c1SAndy Whitcroft } 5405f0a594c1SAndy Whitcroft 5406e4c5babdSJoe Perches# check for single line unbalanced braces 540795330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 540895330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5409e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5410e4c5babdSJoe Perches } 5411e4c5babdSJoe Perches 54120979ae66SJoe Perches# check for unnecessary blank lines around braces 541377b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5414f8e58219SJoe Perches if (CHK("BRACES", 5415f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5416f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5417f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5418f8e58219SJoe Perches } 54190979ae66SJoe Perches } 542077b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5421f8e58219SJoe Perches if (CHK("BRACES", 5422f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5423f8e58219SJoe Perches $fix) { 5424f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5425f8e58219SJoe Perches } 54260979ae66SJoe Perches } 54270979ae66SJoe Perches 54284a0df2efSAndy Whitcroft# no volatiles please 54296c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 54306c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5431000d1cc1SJoe Perches WARN("VOLATILE", 54328c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 54334a0df2efSAndy Whitcroft } 54344a0df2efSAndy Whitcroft 54355e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 54365e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 54375e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 54385e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 543933acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 54405e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 54415e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 54425e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 54435e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 54445e4f6ba5SJoe Perches $fix && 54455e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 54465e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 54475e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 54485e4f6ba5SJoe Perches my $comma_close = ""; 54495e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 54505e4f6ba5SJoe Perches $comma_close = $1; 54515e4f6ba5SJoe Perches } 54525e4f6ba5SJoe Perches 54535e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 54545e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 54555e4f6ba5SJoe Perches my $fixedline = $prevrawline; 54565e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 54575e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 54585e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 54595e4f6ba5SJoe Perches $fixedline = $rawline; 54605e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 54615e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 54625e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 54635e4f6ba5SJoe Perches } 54645e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 54655e4f6ba5SJoe Perches } 54665e4f6ba5SJoe Perches } 54675e4f6ba5SJoe Perches 54685e4f6ba5SJoe Perches# check for missing a space in a string concatenation 54695e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 54705e4f6ba5SJoe Perches WARN('MISSING_SPACE', 54715e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 54725e4f6ba5SJoe Perches } 54735e4f6ba5SJoe Perches 547477cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5475e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5476e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5477e4b7d309SJoe Perches# function declarations 547877cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 547977cb8546SJoe Perches defined($context_function) && 5480e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5481e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 548277cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5483e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 548477cb8546SJoe Perches } 548577cb8546SJoe Perches 54865e4f6ba5SJoe Perches# check for spaces before a quoted newline 54875e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 54885e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 54895e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 54905e4f6ba5SJoe Perches $fix) { 54915e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 54925e4f6ba5SJoe Perches } 54935e4f6ba5SJoe Perches 54945e4f6ba5SJoe Perches } 54955e4f6ba5SJoe Perches 5496f17dba4fSJoe Perches# concatenated string without spaces between elements 549779682c0cSJoe Perches if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { 549879682c0cSJoe Perches if (CHK("CONCATENATED_STRING", 549979682c0cSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr) && 550079682c0cSJoe Perches $fix) { 550179682c0cSJoe Perches while ($line =~ /($String)/g) { 550279682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 550379682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; 550479682c0cSJoe Perches $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; 550579682c0cSJoe Perches } 550679682c0cSJoe Perches } 5507f17dba4fSJoe Perches } 5508f17dba4fSJoe Perches 550990ad30e5SJoe Perches# uncoalesced string fragments 551033acb54aSJoe Perches if ($line =~ /$String\s*"/) { 551179682c0cSJoe Perches if (WARN("STRING_FRAGMENTS", 551279682c0cSJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr) && 551379682c0cSJoe Perches $fix) { 551479682c0cSJoe Perches while ($line =~ /($String)(?=\s*")/g) { 551579682c0cSJoe Perches my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); 551679682c0cSJoe Perches $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; 551779682c0cSJoe Perches } 551879682c0cSJoe Perches } 551990ad30e5SJoe Perches } 552090ad30e5SJoe Perches 5521522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5522522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5523522b837cSAlexey Dobriyan my $show_Z = 1; 55245e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5525522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 55265e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5527522b837cSAlexey Dobriyan # check for %L 5528522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 55295e4f6ba5SJoe Perches WARN("PRINTF_L", 5530522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5531522b837cSAlexey Dobriyan $show_L = 0; 55325e4f6ba5SJoe Perches } 5533522b837cSAlexey Dobriyan # check for %Z 5534522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5535522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5536522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5537522b837cSAlexey Dobriyan $show_Z = 0; 5538522b837cSAlexey Dobriyan } 5539522b837cSAlexey Dobriyan # check for 0x<decimal> 5540522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5541522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 55426e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 55436e300757SJoe Perches } 55445e4f6ba5SJoe Perches } 55455e4f6ba5SJoe Perches 55465e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 55473f7f335dSJoe Perches if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { 55485e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 55495e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 55505e4f6ba5SJoe Perches } 55515e4f6ba5SJoe Perches 555200df344fSAndy Whitcroft# warn about #if 0 5553c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 555460f89010SPrakruthi Deepak Heragu WARN("IF_0", 555560f89010SPrakruthi Deepak Heragu "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); 555660f89010SPrakruthi Deepak Heragu } 555760f89010SPrakruthi Deepak Heragu 555860f89010SPrakruthi Deepak Heragu# warn about #if 1 555960f89010SPrakruthi Deepak Heragu if ($line =~ /^.\s*\#\s*if\s+1\b/) { 556060f89010SPrakruthi Deepak Heragu WARN("IF_1", 556160f89010SPrakruthi Deepak Heragu "Consider removing the #if 1 and its #endif\n" . $herecurr); 55624a0df2efSAndy Whitcroft } 55634a0df2efSAndy Whitcroft 556403df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 556503df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5566100425deSJoe Perches my $tested = quotemeta($1); 5567100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5568100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5569100425deSJoe Perches my $func = $1; 5570100425deSJoe Perches if (WARN('NEEDLESS_IF', 5571100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5572100425deSJoe Perches $fix) { 5573100425deSJoe Perches my $do_fix = 1; 5574100425deSJoe Perches my $leading_tabs = ""; 5575100425deSJoe Perches my $new_leading_tabs = ""; 5576100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5577100425deSJoe Perches $leading_tabs = $1; 5578100425deSJoe Perches } else { 5579100425deSJoe Perches $do_fix = 0; 5580100425deSJoe Perches } 5581100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5582100425deSJoe Perches $new_leading_tabs = $1; 5583100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5584100425deSJoe Perches $do_fix = 0; 5585100425deSJoe Perches } 5586100425deSJoe Perches } else { 5587100425deSJoe Perches $do_fix = 0; 5588100425deSJoe Perches } 5589100425deSJoe Perches if ($do_fix) { 5590100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5591100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5592100425deSJoe Perches } 5593100425deSJoe Perches } 55944c432a8fSGreg Kroah-Hartman } 55954c432a8fSGreg Kroah-Hartman } 5596f0a594c1SAndy Whitcroft 5597ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5598ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5599ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5600ebfdc409SJoe Perches (defined $1 || defined $3) && 5601ebfdc409SJoe Perches $linenr > 3) { 5602ebfdc409SJoe Perches my $testval = $2; 5603ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5604ebfdc409SJoe Perches 5605ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5606ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5607ebfdc409SJoe Perches 5608e29a70f1SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && 5609e29a70f1SJoe Perches $s !~ /\b__GFP_NOWARN\b/ ) { 5610ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5611ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5612ebfdc409SJoe Perches } 5613ebfdc409SJoe Perches } 5614ebfdc409SJoe Perches 5615f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5616dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5617f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5618f78d98f6SJoe Perches my $level = $1; 5619f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5620f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5621f78d98f6SJoe Perches $fix) { 5622f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5623f78d98f6SJoe Perches } 5624f78d98f6SJoe Perches } 5625f78d98f6SJoe Perches 562645c55e92SJoe Perches# check for logging continuations 562745c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 562845c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 562945c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 563045c55e92SJoe Perches } 563145c55e92SJoe Perches 5632abb08a53SJoe Perches# check for mask then right shift without a parentheses 56335b57980dSJoe Perches if ($perl_version_ok && 5634abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5635abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5636abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5637abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5638abb08a53SJoe Perches } 5639abb08a53SJoe Perches 5640b75ac618SJoe Perches# check for pointer comparisons to NULL 56415b57980dSJoe Perches if ($perl_version_ok) { 5642b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5643b75ac618SJoe Perches my $val = $1; 5644b75ac618SJoe Perches my $equal = "!"; 5645b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5646b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5647b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5648b75ac618SJoe Perches $fix) { 5649b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5650b75ac618SJoe Perches } 5651b75ac618SJoe Perches } 5652b75ac618SJoe Perches } 5653b75ac618SJoe Perches 56548716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 56558716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 56568716de38SJoe Perches my $attr = $1; 56578716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 56588716de38SJoe Perches my $ptr = $1; 56598716de38SJoe Perches my $var = $2; 56608716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 56618716de38SJoe Perches ERROR("MISPLACED_INIT", 56628716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 56638716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 56648716de38SJoe Perches WARN("MISPLACED_INIT", 56658716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 56668716de38SJoe Perches $fix) { 5667194f66fcSJoe 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; 56688716de38SJoe Perches } 56698716de38SJoe Perches } 56708716de38SJoe Perches } 56718716de38SJoe Perches 5672e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5673e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5674e970b884SJoe Perches my $attr = $1; 5675e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5676e970b884SJoe Perches my $attr_prefix = $1; 5677e970b884SJoe Perches my $attr_type = $2; 5678e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5679e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5680e970b884SJoe Perches $fix) { 5681194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5682e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5683e970b884SJoe Perches } 5684e970b884SJoe Perches } 5685e970b884SJoe Perches 5686e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5687e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5688e970b884SJoe Perches my $attr = $1; 5689e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5690e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5691e970b884SJoe Perches $fix) { 5692194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5693e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5694e970b884SJoe Perches $lead = rtrim($1); 5695e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5696e970b884SJoe Perches $lead = "${lead}const "; 5697194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5698e970b884SJoe Perches } 5699e970b884SJoe Perches } 5700e970b884SJoe Perches 5701c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5702c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5703c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5704c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5705c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5706c17893c7SJoe Perches $fix) { 5707c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5708c17893c7SJoe Perches } 5709c17893c7SJoe Perches } 5710c17893c7SJoe Perches 5711fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5712fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5713fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5714fbdb8138SJoe Perches my $constant_func = $1; 5715fbdb8138SJoe Perches my $func = $constant_func; 5716fbdb8138SJoe Perches $func =~ s/^__constant_//; 5717fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5718fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5719fbdb8138SJoe Perches $fix) { 5720194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5721fbdb8138SJoe Perches } 5722fbdb8138SJoe Perches } 5723fbdb8138SJoe Perches 57241a15a250SPatrick Pannuto# prefer usleep_range over udelay 572537581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 572643c1d77cSJoe Perches my $delay = $1; 57271a15a250SPatrick Pannuto # ignore udelay's < 10, however 572843c1d77cSJoe Perches if (! ($delay < 10) ) { 5729000d1cc1SJoe Perches CHK("USLEEP_RANGE", 5730458f69efSMauro Carvalho Chehab "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); 573143c1d77cSJoe Perches } 573243c1d77cSJoe Perches if ($delay > 2000) { 573343c1d77cSJoe Perches WARN("LONG_UDELAY", 573443c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 57351a15a250SPatrick Pannuto } 57361a15a250SPatrick Pannuto } 57371a15a250SPatrick Pannuto 573809ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 573909ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 574009ef8725SPatrick Pannuto if ($1 < 20) { 5741000d1cc1SJoe Perches WARN("MSLEEP", 5742458f69efSMauro Carvalho Chehab "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); 574309ef8725SPatrick Pannuto } 574409ef8725SPatrick Pannuto } 574509ef8725SPatrick Pannuto 574636ec1939SJoe Perches# check for comparisons of jiffies 574736ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 574836ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 574936ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 575036ec1939SJoe Perches } 575136ec1939SJoe Perches 57529d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 57539d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 57549d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 57559d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 57569d7a34a5SJoe Perches } 57579d7a34a5SJoe Perches 575800df344fSAndy Whitcroft# warn about #ifdefs in C files 5759c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 576000df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 576100df344fSAndy Whitcroft# print "$herecurr"; 576200df344fSAndy Whitcroft# $clean = 0; 576300df344fSAndy Whitcroft# } 576400df344fSAndy Whitcroft 576522f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5766c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 57673705ce5bSJoe Perches if (ERROR("SPACING", 57683705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 57693705ce5bSJoe Perches $fix) { 5770194f66fcSJoe Perches $fixed[$fixlinenr] =~ 57713705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 57723705ce5bSJoe Perches } 57733705ce5bSJoe Perches 577422f2a2efSAndy Whitcroft } 577522f2a2efSAndy Whitcroft 57764a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5777171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5778171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 57794a0df2efSAndy Whitcroft my $which = $1; 57804a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5781000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5782000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 57834a0df2efSAndy Whitcroft } 57844a0df2efSAndy Whitcroft } 57854a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5786402c2553SMichael S. Tsirkin 5787402c2553SMichael S. Tsirkin my $barriers = qr{ 5788402c2553SMichael S. Tsirkin mb| 5789402c2553SMichael S. Tsirkin rmb| 5790402c2553SMichael S. Tsirkin wmb| 5791402c2553SMichael S. Tsirkin read_barrier_depends 5792402c2553SMichael S. Tsirkin }x; 5793402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5794402c2553SMichael S. Tsirkin mb__before_atomic| 5795402c2553SMichael S. Tsirkin mb__after_atomic| 5796402c2553SMichael S. Tsirkin store_release| 5797402c2553SMichael S. Tsirkin load_acquire| 5798402c2553SMichael S. Tsirkin store_mb| 5799402c2553SMichael S. Tsirkin (?:$barriers) 5800402c2553SMichael S. Tsirkin }x; 5801402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5802402c2553SMichael S. Tsirkin (?:$barriers)| 580343e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 580443e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5805402c2553SMichael S. Tsirkin }x; 5806402c2553SMichael S. Tsirkin 5807402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 58084a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5809c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5810000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 58114a0df2efSAndy Whitcroft } 58124a0df2efSAndy Whitcroft } 58133ad81779SPaul E. McKenney 5814f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5815f4073b0fSMichael S. Tsirkin 5816f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5817f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5818f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5819f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5820f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5821f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5822f4073b0fSMichael S. Tsirkin } 5823f4073b0fSMichael S. Tsirkin 5824cb426e99SJoe Perches# check for waitqueue_active without a comment. 5825cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5826cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5827cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5828cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5829cb426e99SJoe Perches } 5830cb426e99SJoe Perches } 58313ad81779SPaul E. McKenney 583291db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends 583391db2592SPaul E. McKenney if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { 583491db2592SPaul E. McKenney WARN("READ_BARRIER_DEPENDS", 583591db2592SPaul E. McKenney "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); 583691db2592SPaul E. McKenney } 583791db2592SPaul E. McKenney 58384a0df2efSAndy Whitcroft# check of hardware specific defines 5839c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5840000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5841000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 58420a920b5bSAndy Whitcroft } 5843653d4876SAndy Whitcroft 5844596ed45bSJoe Perches# check that the storage class is not after a type 5845596ed45bSJoe Perches if ($line =~ /\b($Type)\s+($Storage)\b/) { 5846000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5847596ed45bSJoe Perches "storage class '$2' should be located before type '$1'\n" . $herecurr); 5848596ed45bSJoe Perches } 5849596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration 5850596ed45bSJoe Perches if ($line =~ /\b$Storage\b/ && 5851596ed45bSJoe Perches $line !~ /^.\s*$Storage/ && 5852596ed45bSJoe Perches $line =~ /^.\s*(.+?)\$Storage\s/ && 5853596ed45bSJoe Perches $1 !~ /[\,\)]\s*$/) { 5854596ed45bSJoe Perches WARN("STORAGE_CLASS", 5855596ed45bSJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr); 5856d4977c78STobias Klauser } 5857d4977c78STobias Klauser 5858de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5859de7d4f0eSAndy Whitcroft# storage class and type. 58609c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 58619c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5862000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5863000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5864de7d4f0eSAndy Whitcroft } 5865de7d4f0eSAndy Whitcroft 58668905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 58672b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 58682b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5869d5e616fcSJoe Perches if (WARN("INLINE", 5870d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5871d5e616fcSJoe Perches $fix) { 5872194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5873d5e616fcSJoe Perches 5874d5e616fcSJoe Perches } 58758905a67cSAndy Whitcroft } 58768905a67cSAndy Whitcroft 58773d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 58782b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 58792b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5880000d1cc1SJoe Perches WARN("PREFER_PACKED", 5881000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 58823d130fd0SJoe Perches } 58833d130fd0SJoe Perches 588439b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 58852b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 58862b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5887000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5888000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 588939b7e287SJoe Perches } 589039b7e287SJoe Perches 5891462811d9SJoe Perches# Check for __attribute__ section, prefer __section 5892462811d9SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5893462811d9SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { 5894462811d9SJoe Perches my $old = substr($rawline, $-[1], $+[1] - $-[1]); 5895462811d9SJoe Perches my $new = substr($old, 1, -1); 5896462811d9SJoe Perches if (WARN("PREFER_SECTION", 5897462811d9SJoe Perches "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && 5898462811d9SJoe Perches $fix) { 5899462811d9SJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; 5900462811d9SJoe Perches } 5901462811d9SJoe Perches } 5902462811d9SJoe Perches 59035f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 59042b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59052b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5906d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5907d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5908d5e616fcSJoe Perches $fix) { 5909194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5910d5e616fcSJoe Perches 5911d5e616fcSJoe Perches } 59125f14d3bdSJoe Perches } 59135f14d3bdSJoe Perches 59146061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 59152b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 59162b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5917d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5918d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5919d5e616fcSJoe Perches $fix) { 5920194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5921d5e616fcSJoe Perches } 59226061d949SJoe Perches } 59236061d949SJoe Perches 5924619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 59255b57980dSJoe Perches if ($perl_version_ok && 5926619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5927619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5928619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5929619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5930619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5931619a908aSJoe Perches } 5932619a908aSJoe Perches 5933fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5934e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5935fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5936e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5937e6176fa4SJoe Perches my $type = $1; 5938e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5939e6176fa4SJoe Perches $type = $1; 5940e6176fa4SJoe Perches my $kernel_type = 'u'; 5941e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5942e6176fa4SJoe Perches $type =~ /(\d+)/; 5943e6176fa4SJoe Perches $kernel_type .= $1; 5944e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5945e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5946e6176fa4SJoe Perches $fix) { 5947e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5948e6176fa4SJoe Perches } 5949e6176fa4SJoe Perches } 5950e6176fa4SJoe Perches } 5951e6176fa4SJoe Perches 5952938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5953938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5954938224b5SJoe Perches my $cast = $1; 5955938224b5SJoe Perches my $const = $2; 5956938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5957938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5958938224b5SJoe Perches $fix) { 5959938224b5SJoe Perches my $suffix = ""; 5960938224b5SJoe Perches my $newconst = $const; 5961938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5962938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5963938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5964938224b5SJoe Perches $suffix .= 'LL'; 5965938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5966938224b5SJoe Perches $suffix .= 'L'; 5967938224b5SJoe Perches } 5968938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5969938224b5SJoe Perches } 5970938224b5SJoe Perches } 5971938224b5SJoe Perches 59728f53a9b8SJoe Perches# check for sizeof(&) 59738f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5974000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5975000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 59768f53a9b8SJoe Perches } 59778f53a9b8SJoe Perches 597866c80b60SJoe Perches# check for sizeof without parenthesis 597966c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5980d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5981d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5982d5e616fcSJoe Perches $fix) { 5983194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5984d5e616fcSJoe Perches } 598566c80b60SJoe Perches } 598666c80b60SJoe Perches 598788982feaSJoe Perches# check for struct spinlock declarations 598888982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 598988982feaSJoe Perches WARN("USE_SPINLOCK_T", 599088982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 599188982feaSJoe Perches } 599288982feaSJoe Perches 5993a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 599406668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5995a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5996caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5997caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5998d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5999d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 6000d5e616fcSJoe Perches $fix) { 6001194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 6002d5e616fcSJoe Perches } 6003a6962d72SJoe Perches } 6004a6962d72SJoe Perches } 6005a6962d72SJoe Perches 60060b523769SJoe Perches# check for vsprintf extension %p<foo> misuses 60075b57980dSJoe Perches if ($perl_version_ok && 60080b523769SJoe Perches defined $stat && 60090b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 60100b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 6011e3c6bc95STobin C. Harding my $stat_real; 6012e3c6bc95STobin C. Harding 60130b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 60140b523769SJoe Perches $lc = $lc + $linenr; 60150b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 6016ffe07513SJoe Perches my $specifier; 6017ffe07513SJoe Perches my $extension; 6018ffe07513SJoe Perches my $bad_specifier = ""; 60190b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 60200b523769SJoe Perches $fmt =~ s/%%//g; 6021e3c6bc95STobin C. Harding 6022e3c6bc95STobin C. Harding while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { 6023e3c6bc95STobin C. Harding $specifier = $1; 6024e3c6bc95STobin C. Harding $extension = $2; 60254462996eSAlexandre Belloni if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) { 6026e3c6bc95STobin C. Harding $bad_specifier = $specifier; 60270b523769SJoe Perches last; 60280b523769SJoe Perches } 6029e3c6bc95STobin C. Harding if ($extension eq "x" && !defined($stat_real)) { 6030e3c6bc95STobin C. Harding if (!defined($stat_real)) { 6031e3c6bc95STobin C. Harding $stat_real = get_stat_real($linenr, $lc); 60320b523769SJoe Perches } 6033e3c6bc95STobin C. Harding WARN("VSPRINTF_SPECIFIER_PX", 6034e3c6bc95STobin 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"); 6035e3c6bc95STobin C. Harding } 6036e3c6bc95STobin C. Harding } 6037e3c6bc95STobin C. Harding if ($bad_specifier ne "") { 60382a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 60391df7338aSSergey Senozhatsky my $ext_type = "Invalid"; 60401df7338aSSergey Senozhatsky my $use = ""; 6041e3c6bc95STobin C. Harding if ($bad_specifier =~ /p[Ff]/) { 60421df7338aSSergey Senozhatsky $ext_type = "Deprecated"; 60431df7338aSSergey Senozhatsky $use = " - use %pS instead"; 6044e3c6bc95STobin C. Harding $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); 60451df7338aSSergey Senozhatsky } 60462a9f9d85STobin C. Harding 60470b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 6048e3c6bc95STobin C. Harding "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); 6049e3c6bc95STobin C. Harding } 60500b523769SJoe Perches } 60510b523769SJoe Perches } 60520b523769SJoe Perches 6053554e165cSAndy Whitcroft# Check for misused memsets 60545b57980dSJoe Perches if ($perl_version_ok && 6055d1fe9c09SJoe Perches defined $stat && 60569e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 6057554e165cSAndy Whitcroft 6058d7c76ba7SJoe Perches my $ms_addr = $2; 6059d1fe9c09SJoe Perches my $ms_val = $7; 6060d1fe9c09SJoe Perches my $ms_size = $12; 6061d7c76ba7SJoe Perches 6062554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 6063554e165cSAndy Whitcroft ERROR("MEMSET", 6064d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 6065554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 6066554e165cSAndy Whitcroft WARN("MEMSET", 6067d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 6068d7c76ba7SJoe Perches } 6069d7c76ba7SJoe Perches } 6070d7c76ba7SJoe Perches 607198a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 60725b57980dSJoe Perches# if ($perl_version_ok && 6073f333195dSJoe Perches# defined $stat && 6074f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6075f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 6076f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 6077f333195dSJoe Perches# $fix) { 6078f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 6079f333195dSJoe Perches# } 6080f333195dSJoe Perches# } 608198a9bba5SJoe Perches 6082b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 60835b57980dSJoe Perches# if ($perl_version_ok && 6084f333195dSJoe Perches# defined $stat && 6085f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6086f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 6087f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 6088f333195dSJoe Perches# } 6089b6117d17SMateusz Kulikowski 60908617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 60918617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 60925b57980dSJoe Perches# if ($perl_version_ok && 6093f333195dSJoe Perches# defined $stat && 6094f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 6095f333195dSJoe Perches# 6096f333195dSJoe Perches# my $ms_val = $7; 6097f333195dSJoe Perches# 6098f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 6099f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 6100f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 6101f333195dSJoe Perches# $fix) { 6102f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 6103f333195dSJoe Perches# } 6104f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 6105f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 6106f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 6107f333195dSJoe Perches# $fix) { 6108f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 6109f333195dSJoe Perches# } 6110f333195dSJoe Perches# } 6111f333195dSJoe Perches# } 61128617cd09SMateusz Kulikowski 6113d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 61145b57980dSJoe Perches if ($perl_version_ok && 6115d1fe9c09SJoe Perches defined $stat && 6116d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 6117d1fe9c09SJoe Perches if (defined $2 || defined $7) { 6118d7c76ba7SJoe Perches my $call = $1; 6119d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 6120d7c76ba7SJoe Perches my $arg1 = $3; 6121d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 6122d1fe9c09SJoe Perches my $arg2 = $8; 6123d7c76ba7SJoe Perches my $cast; 6124d7c76ba7SJoe Perches 6125d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 6126d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 6127d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 6128d7c76ba7SJoe Perches $cast = $cast1; 6129d7c76ba7SJoe Perches } else { 6130d7c76ba7SJoe Perches $cast = $cast2; 6131d7c76ba7SJoe Perches } 6132d7c76ba7SJoe Perches WARN("MINMAX", 6133d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 6134554e165cSAndy Whitcroft } 6135554e165cSAndy Whitcroft } 6136554e165cSAndy Whitcroft 61374a273195SJoe Perches# check usleep_range arguments 61385b57980dSJoe Perches if ($perl_version_ok && 61394a273195SJoe Perches defined $stat && 61404a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 61414a273195SJoe Perches my $min = $1; 61424a273195SJoe Perches my $max = $7; 61434a273195SJoe Perches if ($min eq $max) { 61444a273195SJoe Perches WARN("USLEEP_RANGE", 6145458f69efSMauro Carvalho Chehab "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 61464a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 61474a273195SJoe Perches $min > $max) { 61484a273195SJoe Perches WARN("USLEEP_RANGE", 6149458f69efSMauro Carvalho Chehab "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); 61504a273195SJoe Perches } 61514a273195SJoe Perches } 61524a273195SJoe Perches 6153823b794cSJoe Perches# check for naked sscanf 61545b57980dSJoe Perches if ($perl_version_ok && 6155823b794cSJoe Perches defined $stat && 61566c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 6157823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 6158823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 6159823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 6160823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 6161823b794cSJoe Perches $lc = $lc + $linenr; 61622a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6163823b794cSJoe Perches WARN("NAKED_SSCANF", 6164823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 6165823b794cSJoe Perches } 6166823b794cSJoe Perches 6167afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 61685b57980dSJoe Perches if ($perl_version_ok && 6169afc819abSJoe Perches defined $stat && 6170afc819abSJoe Perches $line =~ /\bsscanf\b/) { 6171afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 6172afc819abSJoe Perches $lc = $lc + $linenr; 61732a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6174afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 6175afc819abSJoe Perches my $format = $6; 6176afc819abSJoe Perches my $count = $format =~ tr@%@%@; 6177afc819abSJoe Perches if ($count == 1 && 6178afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 6179afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 6180afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 6181afc819abSJoe Perches } 6182afc819abSJoe Perches } 6183afc819abSJoe Perches } 6184afc819abSJoe Perches 618570dc8a48SJoe Perches# check for new externs in .h files. 618670dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 618770dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 6188d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 618970dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 619070dc8a48SJoe Perches $fix) { 6191194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 619270dc8a48SJoe Perches } 619370dc8a48SJoe Perches } 619470dc8a48SJoe Perches 6195de7d4f0eSAndy Whitcroft# check for new externs in .c files. 6196171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 6197c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 6198171ae1a4SAndy Whitcroft { 6199c45dcabdSAndy Whitcroft my $function_name = $1; 6200c45dcabdSAndy Whitcroft my $paren_space = $2; 6201171ae1a4SAndy Whitcroft 6202171ae1a4SAndy Whitcroft my $s = $stat; 6203171ae1a4SAndy Whitcroft if (defined $cond) { 6204171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 6205171ae1a4SAndy Whitcroft } 6206c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 6207c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 6208c45dcabdSAndy Whitcroft { 6209000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6210000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6211de7d4f0eSAndy Whitcroft } 6212de7d4f0eSAndy Whitcroft 6213171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 6214000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 6215000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 6216171ae1a4SAndy Whitcroft } 62179c9ba34eSAndy Whitcroft 62189c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 62199c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 62209c9ba34eSAndy Whitcroft { 6221000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 6222000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 6223171ae1a4SAndy Whitcroft } 6224171ae1a4SAndy Whitcroft 6225a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 6226a0ad7596SJoe Perches if (defined $stat && 622725bdda2bSMiles Chen $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && 6228ca0d8929SJoe Perches $1 ne "void") { 6229ca0d8929SJoe Perches my $args = trim($1); 6230ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 6231ca0d8929SJoe Perches my $arg = trim($1); 6232ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 6233ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 6234ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 6235ca0d8929SJoe Perches } 6236ca0d8929SJoe Perches } 6237ca0d8929SJoe Perches } 6238ca0d8929SJoe Perches 6239a0ad7596SJoe Perches# check for function definitions 62405b57980dSJoe Perches if ($perl_version_ok && 6241a0ad7596SJoe Perches defined $stat && 6242a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 6243a0ad7596SJoe Perches $context_function = $1; 6244a0ad7596SJoe Perches 6245a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 6246a0ad7596SJoe Perches my $ok = 0; 6247a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 6248a0ad7596SJoe Perches my $herectx = $here . "\n"; 6249a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6250a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 6251a0ad7596SJoe Perches $herectx .= $rl . "\n"; 6252a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 6253a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 6254a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 6255a0ad7596SJoe Perches } 6256a0ad7596SJoe Perches if (!$ok) { 6257a0ad7596SJoe Perches ERROR("OPEN_BRACE", 6258a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 6259a0ad7596SJoe Perches } 6260a0ad7596SJoe Perches } 6261a0ad7596SJoe Perches 6262de7d4f0eSAndy Whitcroft# checks for new __setup's 6263de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 6264de7d4f0eSAndy Whitcroft my $name = $1; 6265de7d4f0eSAndy Whitcroft 6266de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 6267000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 62688c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 6269de7d4f0eSAndy Whitcroft } 6270653d4876SAndy Whitcroft } 62719c0ca6f9SAndy Whitcroft 6272e29a70f1SJoe Perches# check for pointless casting of alloc functions 6273e29a70f1SJoe Perches if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { 6274000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 6275000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 62769c0ca6f9SAndy Whitcroft } 627713214adfSAndy Whitcroft 6278a640d25cSJoe Perches# alloc style 6279a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 62805b57980dSJoe Perches if ($perl_version_ok && 6281e29a70f1SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 6282a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 6283a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 6284a640d25cSJoe Perches } 6285a640d25cSJoe Perches 628660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 62875b57980dSJoe Perches if ($perl_version_ok && 62881b4a2ed4SJoe Perches defined $stat && 62891b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 629060a55369SJoe Perches my $oldfunc = $3; 629160a55369SJoe Perches my $a1 = $4; 629260a55369SJoe Perches my $a2 = $10; 629360a55369SJoe Perches my $newfunc = "kmalloc_array"; 629460a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 629560a55369SJoe Perches my $r1 = $a1; 629660a55369SJoe Perches my $r2 = $a2; 629760a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 629860a55369SJoe Perches $r1 = $a2; 629960a55369SJoe Perches $r2 = $a1; 630060a55369SJoe Perches } 6301e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 6302e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 63031b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 6304e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6305e3d95a2aSTobin C. Harding 6306e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 63071b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 63081b4a2ed4SJoe Perches $cnt == 1 && 6309e367455aSJoe Perches $fix) { 6310194f66fcSJoe 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; 631160a55369SJoe Perches } 631260a55369SJoe Perches } 631360a55369SJoe Perches } 631460a55369SJoe Perches 6315972fdea2SJoe Perches# check for krealloc arg reuse 63165b57980dSJoe Perches if ($perl_version_ok && 63174cab63ceSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && 63184cab63ceSJoe Perches $1 eq $3) { 6319972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 6320972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6321972fdea2SJoe Perches } 6322972fdea2SJoe Perches 63235ce59ae0SJoe Perches# check for alloc argument mismatch 63245ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 63255ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 63265ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 63275ce59ae0SJoe Perches } 63285ce59ae0SJoe Perches 6329caf2a54fSJoe Perches# check for multiple semicolons 6330caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6331d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6332d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6333d5e616fcSJoe Perches $fix) { 6334194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6335d5e616fcSJoe Perches } 6336d1e2ad07SJoe Perches } 6337d1e2ad07SJoe Perches 6338cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6339cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6340cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 63410ab90191SJoe Perches my $ull = ""; 63420ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 63430ab90191SJoe Perches if (CHK("BIT_MACRO", 63440ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 63450ab90191SJoe Perches $fix) { 63460ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 63470ab90191SJoe Perches } 63480ab90191SJoe Perches } 63490ab90191SJoe Perches 63502d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 63512d632745SJoe 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*$/) { 63522d632745SJoe Perches my $config = $1; 63532d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 63542d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 63552d632745SJoe Perches $fix) { 63562d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 63572d632745SJoe Perches } 63582d632745SJoe Perches } 63592d632745SJoe Perches 6360e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6361c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6362c34c09a8SJoe Perches my $has_break = 0; 6363c34c09a8SJoe Perches my $has_statement = 0; 6364c34c09a8SJoe Perches my $count = 0; 6365c34c09a8SJoe Perches my $prevline = $linenr; 6366e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6367c34c09a8SJoe Perches $prevline--; 6368c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6369c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6370c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6371c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6372c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6373c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6374c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6375c34c09a8SJoe Perches $has_statement = 1; 6376c34c09a8SJoe Perches $count++; 6377258f79d5SHeinrich Schuchardt $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/); 6378c34c09a8SJoe Perches } 6379c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6380c34c09a8SJoe Perches WARN("MISSING_BREAK", 6381224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6382c34c09a8SJoe Perches } 6383c34c09a8SJoe Perches } 6384c34c09a8SJoe Perches 6385d1e2ad07SJoe Perches# check for switch/default statements without a break; 63865b57980dSJoe Perches if ($perl_version_ok && 6387d1e2ad07SJoe Perches defined $stat && 6388d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6389d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6390e3d95a2aSTobin C. Harding my $herectx = get_stat_here($linenr, $cnt, $here); 6391e3d95a2aSTobin C. Harding 6392d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6393d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6394caf2a54fSJoe Perches } 6395caf2a54fSJoe Perches 639613214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6397d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6398d5e616fcSJoe Perches if (WARN("USE_FUNC", 6399d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6400d5e616fcSJoe Perches $fix) { 6401194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6402d5e616fcSJoe Perches } 640313214adfSAndy Whitcroft } 6404773647a0SAndy Whitcroft 640562ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 640662ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 640762ec818fSJoe Perches ERROR("DATE_TIME", 640862ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 640962ec818fSJoe Perches } 641062ec818fSJoe Perches 64112c92488aSJoe Perches# check for use of yield() 64122c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 64132c92488aSJoe Perches WARN("YIELD", 64142c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 64152c92488aSJoe Perches } 64162c92488aSJoe Perches 6417179f8f40SJoe Perches# check for comparisons against true and false 6418179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6419179f8f40SJoe Perches my $lead = $1; 6420179f8f40SJoe Perches my $arg = $2; 6421179f8f40SJoe Perches my $test = $3; 6422179f8f40SJoe Perches my $otype = $4; 6423179f8f40SJoe Perches my $trail = $5; 6424179f8f40SJoe Perches my $op = "!"; 6425179f8f40SJoe Perches 6426179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6427179f8f40SJoe Perches 6428179f8f40SJoe Perches my $type = lc($otype); 6429179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6430179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6431179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6432179f8f40SJoe Perches $op = ""; 6433179f8f40SJoe Perches } 6434179f8f40SJoe Perches 6435179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6436179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6437179f8f40SJoe Perches 6438179f8f40SJoe Perches## maybe suggesting a correct construct would better 6439179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6440179f8f40SJoe Perches 6441179f8f40SJoe Perches } 6442179f8f40SJoe Perches } 6443179f8f40SJoe Perches 64444882720bSThomas Gleixner# check for semaphores initialized locked 64454882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6446000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6447000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6448773647a0SAndy Whitcroft } 64496712d858SJoe Perches 645067d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 645167d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6452000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 645367d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6454773647a0SAndy Whitcroft } 64556712d858SJoe Perches 6456ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6457f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6458000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6459ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6460f3db6639SMichael Ellerman } 64616712d858SJoe Perches 64623d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead 64633d709ab5SPaul E. McKenney if ($line =~ /\bspin_is_locked\(/) { 64643d709ab5SPaul E. McKenney WARN("USE_LOCKDEP", 64653d709ab5SPaul E. McKenney "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 64663d709ab5SPaul E. McKenney } 64673d709ab5SPaul E. McKenney 64689189c7e7SJoe Perches# check for deprecated apis 64699189c7e7SJoe Perches if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 64709189c7e7SJoe Perches my $deprecated_api = $1; 64719189c7e7SJoe Perches my $new_api = $deprecated_apis{$deprecated_api}; 64729189c7e7SJoe Perches WARN("DEPRECATED_API", 64739189c7e7SJoe Perches "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 64749189c7e7SJoe Perches } 64759189c7e7SJoe Perches 64760f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6477d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 64786903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6479d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6480000d1cc1SJoe Perches WARN("CONST_STRUCT", 6481d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 64822b6db5cbSAndy Whitcroft } 6483773647a0SAndy Whitcroft 6484773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6485773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6486773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6487c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6488c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6489171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6490171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6491171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6492773647a0SAndy Whitcroft { 6493000d1cc1SJoe Perches WARN("NR_CPUS", 6494000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6495773647a0SAndy Whitcroft } 64969c9ba34eSAndy Whitcroft 649752ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 649852ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 649952ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 650052ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 650152ea8506SJoe Perches } 650252ea8506SJoe Perches 6503acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 65045b57980dSJoe Perches if ($perl_version_ok && 6505acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6506acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6507acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6508acd9362cSJoe Perches } 6509acd9362cSJoe Perches 6510691d77b6SAndy Whitcroft# whine mightly about in_atomic 6511691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6512691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6513000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6514000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6515f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6516000d1cc1SJoe Perches WARN("IN_ATOMIC", 6517000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6518691d77b6SAndy Whitcroft } 6519691d77b6SAndy Whitcroft } 65201704f47bSPeter Zijlstra 65210f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 65220f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 65230f5225b0SPeter Zijlstra ERROR("LOCKING", 65240f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 65250f5225b0SPeter Zijlstra } 65260f5225b0SPeter Zijlstra 65271704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 65281704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 65291704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 65301704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 65311704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 65321704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6533000d1cc1SJoe Perches ERROR("LOCKDEP", 6534000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 65351704f47bSPeter Zijlstra } 65361704f47bSPeter Zijlstra } 653788f8831cSDave Jones 6538b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6539b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6540000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6541000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 654288f8831cSDave Jones } 65432435880fSJoe Perches 654400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> 654500180468SJoe Perches# and whether or not function naming is typical and if 654600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too 65475b57980dSJoe Perches if ($perl_version_ok && 654800180468SJoe Perches defined $stat && 654900180468SJoe 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*\)/) { 655000180468SJoe Perches my $var = $1; 655100180468SJoe Perches my $perms = $2; 655200180468SJoe Perches my $show = $3; 655300180468SJoe Perches my $store = $4; 655400180468SJoe Perches my $octal_perms = perms_to_octal($perms); 655500180468SJoe Perches if ($show =~ /^${var}_show$/ && 655600180468SJoe Perches $store =~ /^${var}_store$/ && 655700180468SJoe Perches $octal_perms eq "0644") { 655800180468SJoe Perches if (WARN("DEVICE_ATTR_RW", 655900180468SJoe Perches "Use DEVICE_ATTR_RW\n" . $herecurr) && 656000180468SJoe Perches $fix) { 656100180468SJoe 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})/; 656200180468SJoe Perches } 656300180468SJoe Perches } elsif ($show =~ /^${var}_show$/ && 656400180468SJoe Perches $store =~ /^NULL$/ && 656500180468SJoe Perches $octal_perms eq "0444") { 656600180468SJoe Perches if (WARN("DEVICE_ATTR_RO", 656700180468SJoe Perches "Use DEVICE_ATTR_RO\n" . $herecurr) && 656800180468SJoe Perches $fix) { 656900180468SJoe 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})/; 657000180468SJoe Perches } 657100180468SJoe Perches } elsif ($show =~ /^NULL$/ && 657200180468SJoe Perches $store =~ /^${var}_store$/ && 657300180468SJoe Perches $octal_perms eq "0200") { 657400180468SJoe Perches if (WARN("DEVICE_ATTR_WO", 657500180468SJoe Perches "Use DEVICE_ATTR_WO\n" . $herecurr) && 657600180468SJoe Perches $fix) { 657700180468SJoe 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})/; 657800180468SJoe Perches } 657900180468SJoe Perches } elsif ($octal_perms eq "0644" || 658000180468SJoe Perches $octal_perms eq "0444" || 658100180468SJoe Perches $octal_perms eq "0200") { 658200180468SJoe Perches my $newshow = "$show"; 658300180468SJoe Perches $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); 658400180468SJoe Perches my $newstore = $store; 658500180468SJoe Perches $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); 658600180468SJoe Perches my $rename = ""; 658700180468SJoe Perches if ($show ne $newshow) { 658800180468SJoe Perches $rename .= " '$show' to '$newshow'"; 658900180468SJoe Perches } 659000180468SJoe Perches if ($store ne $newstore) { 659100180468SJoe Perches $rename .= " '$store' to '$newstore'"; 659200180468SJoe Perches } 659300180468SJoe Perches WARN("DEVICE_ATTR_FUNCTIONS", 659400180468SJoe Perches "Consider renaming function(s)$rename\n" . $herecurr); 659500180468SJoe Perches } else { 659600180468SJoe Perches WARN("DEVICE_ATTR_PERMS", 659700180468SJoe Perches "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); 659800180468SJoe Perches } 659900180468SJoe Perches } 660000180468SJoe Perches 6601515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6602515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 660373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a 660473121534SJoe Perches# specific definition of not visible in sysfs. 660573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means 660673121534SJoe Perches# use the default permissions 66075b57980dSJoe Perches if ($perl_version_ok && 6608459cf0aeSJoe Perches defined $stat && 6609515a235eSJoe Perches $line =~ /$mode_perms_search/) { 66102435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 66112435880fSJoe Perches my $func = $entry->[0]; 66122435880fSJoe Perches my $arg_pos = $entry->[1]; 66132435880fSJoe Perches 6614459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6615459cf0aeSJoe Perches $lc = $lc + $linenr; 66162a9f9d85STobin C. Harding my $stat_real = get_stat_real($linenr, $lc); 6617459cf0aeSJoe Perches 66182435880fSJoe Perches my $skip_args = ""; 66192435880fSJoe Perches if ($arg_pos > 1) { 66202435880fSJoe Perches $arg_pos--; 66212435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 66222435880fSJoe Perches } 6623f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6624459cf0aeSJoe Perches if ($stat =~ /$test/) { 66252435880fSJoe Perches my $val = $1; 66262435880fSJoe Perches $val = $6 if ($skip_args ne ""); 662773121534SJoe Perches if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && 662873121534SJoe Perches (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 662973121534SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4))) { 66302435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6631459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6632f90774e1SJoe Perches } 6633f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6634c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6635459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 66362435880fSJoe Perches } 6637459cf0aeSJoe Perches } 6638459cf0aeSJoe Perches } 6639459cf0aeSJoe Perches } 6640459cf0aeSJoe Perches 6641459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6642bc22d9a7SJoe Perches while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { 664300180468SJoe Perches my $oval = $1; 664400180468SJoe Perches my $octal = perms_to_octal($oval); 6645f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6646459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6647f90774e1SJoe Perches $fix) { 664800180468SJoe Perches $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; 66492435880fSJoe Perches } 665013214adfSAndy Whitcroft } 66515a6d20ceSBjorn Andersson 66525a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 66535a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 66545a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 66555a6d20ceSBjorn Andersson my $valid_licenses = qr{ 66565a6d20ceSBjorn Andersson GPL| 66575a6d20ceSBjorn Andersson GPL\ v2| 66585a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 66595a6d20ceSBjorn Andersson Dual\ BSD/GPL| 66605a6d20ceSBjorn Andersson Dual\ MIT/GPL| 66615a6d20ceSBjorn Andersson Dual\ MPL/GPL| 66625a6d20ceSBjorn Andersson Proprietary 66635a6d20ceSBjorn Andersson }x; 66645a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 66655a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 66665a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 66675a6d20ceSBjorn Andersson } 66685a6d20ceSBjorn Andersson } 66696a8d76cbSMatteo Croce 66706a8d76cbSMatteo Croce# check for sysctl duplicate constants 66716a8d76cbSMatteo Croce if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { 66726a8d76cbSMatteo Croce WARN("DUPLICATED_SYSCTL_CONST", 66736a8d76cbSMatteo Croce "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); 66746a8d76cbSMatteo Croce } 6675515a235eSJoe Perches } 667613214adfSAndy Whitcroft 667713214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 667813214adfSAndy Whitcroft # so just keep quiet. 667913214adfSAndy Whitcroft if ($#rawlines == -1) { 668013214adfSAndy Whitcroft exit(0); 66810a920b5bSAndy Whitcroft } 66820a920b5bSAndy Whitcroft 66838905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 66848905a67cSAndy Whitcroft # things that appear to be patches. 66858905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 66868905a67cSAndy Whitcroft exit(0); 66878905a67cSAndy Whitcroft } 66888905a67cSAndy Whitcroft 66898905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 66908905a67cSAndy Whitcroft # just keep quiet. 66918905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 66928905a67cSAndy Whitcroft exit(0); 66938905a67cSAndy Whitcroft } 66948905a67cSAndy Whitcroft 6695a08ffbefSStafford Horne if (!$is_patch && $filename !~ /cover-letter\.patch$/) { 6696000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6697000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 66980a920b5bSAndy Whitcroft } 6699cd261496SGeert Uytterhoeven if ($is_patch && $has_commit_log && $chk_signoff) { 6700cd261496SGeert Uytterhoeven if ($signoff == 0) { 6701000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6702000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 6703cd261496SGeert Uytterhoeven } elsif (!$authorsignoff) { 6704cd261496SGeert Uytterhoeven WARN("NO_AUTHOR_SIGN_OFF", 6705cd261496SGeert Uytterhoeven "Missing Signed-off-by: line by nominal patch author '$author'\n"); 6706cd261496SGeert Uytterhoeven } 67070a920b5bSAndy Whitcroft } 67080a920b5bSAndy Whitcroft 6709f0a594c1SAndy Whitcroft print report_dump(); 671013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 671113214adfSAndy Whitcroft print "$filename " if ($summary_file); 67126c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 67136c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 67146c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 67156c72ffaaSAndy Whitcroft } 67168905a67cSAndy Whitcroft 6717d2c0a235SAndy Whitcroft if ($quiet == 0) { 6718ef212196SJoe Perches # If there were any defects found and not already fixing them 6719ef212196SJoe Perches if (!$clean and !$fix) { 6720ef212196SJoe Perches print << "EOM" 6721ef212196SJoe Perches 6722ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6723ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6724ef212196SJoe PerchesEOM 6725ef212196SJoe Perches } 6726d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6727d2c0a235SAndy Whitcroft # then suggest that. 6728d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6729b0781216SMike Frysinger $rpt_cleaners = 0; 6730d8469f16SJoe Perches print << "EOM" 6731d8469f16SJoe Perches 6732d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6733d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6734d8469f16SJoe PerchesEOM 6735d2c0a235SAndy Whitcroft } 6736d2c0a235SAndy Whitcroft } 6737d2c0a235SAndy Whitcroft 6738d752fcc8SJoe Perches if ($clean == 0 && $fix && 6739d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6740d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 67419624b8d6SJoe Perches my $newfile = $filename; 67429624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 67433705ce5bSJoe Perches my $linecount = 0; 67443705ce5bSJoe Perches my $f; 67453705ce5bSJoe Perches 6746d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6747d752fcc8SJoe Perches 67483705ce5bSJoe Perches open($f, '>', $newfile) 67493705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 67503705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 67513705ce5bSJoe Perches $linecount++; 67523705ce5bSJoe Perches if ($file) { 67533705ce5bSJoe Perches if ($linecount > 3) { 67543705ce5bSJoe Perches $fixed_line =~ s/^\+//; 67553705ce5bSJoe Perches print $f $fixed_line . "\n"; 67563705ce5bSJoe Perches } 67573705ce5bSJoe Perches } else { 67583705ce5bSJoe Perches print $f $fixed_line . "\n"; 67593705ce5bSJoe Perches } 67603705ce5bSJoe Perches } 67613705ce5bSJoe Perches close($f); 67623705ce5bSJoe Perches 67633705ce5bSJoe Perches if (!$quiet) { 67643705ce5bSJoe Perches print << "EOM"; 6765d8469f16SJoe Perches 67663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 67673705ce5bSJoe Perches 67683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 67693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 67703705ce5bSJoe Perches 67713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 67723705ce5bSJoe PerchesNo warranties, expressed or implied... 67733705ce5bSJoe PerchesEOM 67743705ce5bSJoe Perches } 67753705ce5bSJoe Perches } 67763705ce5bSJoe Perches 6777d8469f16SJoe Perches if ($quiet == 0) { 6778d8469f16SJoe Perches print "\n"; 6779d8469f16SJoe Perches if ($clean == 1) { 6780d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6781d8469f16SJoe Perches } else { 6782d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 67830a920b5bSAndy Whitcroft } 67840a920b5bSAndy Whitcroft } 67850a920b5bSAndy Whitcroft return $clean; 67860a920b5bSAndy Whitcroft} 6787