10a920b5bSAndy Whitcroft#!/usr/bin/perl -w 2dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 42a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 5015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 60a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2 70a920b5bSAndy Whitcroft 80a920b5bSAndy Whitcroftuse strict; 9c707a81dSJoe Perchesuse POSIX; 1036061e38SJoe Perchesuse File::Basename; 1136061e38SJoe Perchesuse Cwd 'abs_path'; 1257230297SJoe Perchesuse Term::ANSIColor qw(:constants); 130a920b5bSAndy Whitcroft 140a920b5bSAndy Whitcroftmy $P = $0; 1536061e38SJoe Perchesmy $D = dirname(abs_path($P)); 160a920b5bSAndy Whitcroft 17000d1cc1SJoe Perchesmy $V = '0.32'; 180a920b5bSAndy Whitcroft 190a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 200a920b5bSAndy Whitcroft 210a920b5bSAndy Whitcroftmy $quiet = 0; 220a920b5bSAndy Whitcroftmy $tree = 1; 230a920b5bSAndy Whitcroftmy $chk_signoff = 1; 240a920b5bSAndy Whitcroftmy $chk_patch = 1; 25773647a0SAndy Whitcroftmy $tst_only; 266c72ffaaSAndy Whitcroftmy $emacs = 0; 278905a67cSAndy Whitcroftmy $terse = 0; 2834d8815fSJoe Perchesmy $showfile = 0; 296c72ffaaSAndy Whitcroftmy $file = 0; 304a593c34SDu, Changbinmy $git = 0; 310dea9f1eSJoe Perchesmy %git_commits = (); 326c72ffaaSAndy Whitcroftmy $check = 0; 332ac73b4fSJoe Perchesmy $check_orig = 0; 348905a67cSAndy Whitcroftmy $summary = 1; 358905a67cSAndy Whitcroftmy $mailback = 0; 3613214adfSAndy Whitcroftmy $summary_file = 0; 37000d1cc1SJoe Perchesmy $show_types = 0; 383beb42ecSJoe Perchesmy $list_types = 0; 393705ce5bSJoe Perchesmy $fix = 0; 409624b8d6SJoe Perchesmy $fix_inplace = 0; 416c72ffaaSAndy Whitcroftmy $root; 42c2fdda0dSAndy Whitcroftmy %debug; 433445686aSJoe Perchesmy %camelcase = (); 4491bfe484SJoe Perchesmy %use_type = (); 4591bfe484SJoe Perchesmy @use = (); 4691bfe484SJoe Perchesmy %ignore_type = (); 47000d1cc1SJoe Perchesmy @ignore = (); 4877f5b10aSHannes Edermy $help = 0; 49000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 506cd7f386SJoe Perchesmy $max_line_length = 80; 51d62a201fSDave Hansenmy $ignore_perl_version = 0; 52d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 5356193274SVadim Bendeburymy $min_conf_desc_length = 4; 5466b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 55ebfd7d62SJoe Perchesmy $codespell = 0; 56f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 57bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 5875ad8c57SJerome Forissiermy $typedefsfile = ""; 5957230297SJoe Perchesmy $color = 1; 60dadf680dSJoe Perchesmy $allow_c99_comments = 1; 6177f5b10aSHannes Eder 6277f5b10aSHannes Edersub help { 6377f5b10aSHannes Eder my ($exitcode) = @_; 6477f5b10aSHannes Eder 6577f5b10aSHannes Eder print << "EOM"; 6677f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 6777f5b10aSHannes EderVersion: $V 6877f5b10aSHannes Eder 6977f5b10aSHannes EderOptions: 7077f5b10aSHannes Eder -q, --quiet quiet 7177f5b10aSHannes Eder --no-tree run without a kernel tree 7277f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 7377f5b10aSHannes Eder --patch treat FILE as patchfile (default) 7477f5b10aSHannes Eder --emacs emacs compile window format 7577f5b10aSHannes Eder --terse one line per report 7634d8815fSJoe Perches --showfile emit diffed file position, not input file position 774a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 784a593c34SDu, Changbin single git commit with: 794a593c34SDu, Changbin <rev> 804a593c34SDu, Changbin <rev>^ 814a593c34SDu, Changbin <rev>~n 824a593c34SDu, Changbin multiple git commits with: 834a593c34SDu, Changbin <rev1>..<rev2> 844a593c34SDu, Changbin <rev1>...<rev2> 854a593c34SDu, Changbin <rev>-<count> 864a593c34SDu, Changbin git merges are ignored 8777f5b10aSHannes Eder -f, --file treat FILE as regular source file 8877f5b10aSHannes Eder --subjective, --strict enable more subjective tests 893beb42ecSJoe Perches --list-types list the possible message types 9091bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 91000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 923beb42ecSJoe Perches --show-types show the specific message type in the output 936cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 9456193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 9577f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 9677f5b10aSHannes Eder --no-summary suppress the per-file summary 9777f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 9877f5b10aSHannes Eder --summary-file include the filename in summary 9977f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 10077f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 10177f5b10aSHannes Eder is all off) 10277f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 10377f5b10aSHannes Eder literally 1043705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1053705ce5bSJoe Perches If correctable single-line errors exist, create 1063705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1073705ce5bSJoe Perches with potential errors corrected to the preferred 1083705ce5bSJoe Perches checkpatch style 1099624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1109624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1119624b8d6SJoe Perches file. It's your fault if there's no backup or git 112d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 113d62a201fSDave Hansen runtime errors. 114ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 115f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 116ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 11775ad8c57SJerome Forissier --typedefsfile Read additional types from this file 11857230297SJoe Perches --color Use colors when output is STDOUT (default: on) 11977f5b10aSHannes Eder -h, --help, --version display this help and exit 12077f5b10aSHannes Eder 12177f5b10aSHannes EderWhen FILE is - read standard input. 12277f5b10aSHannes EderEOM 12377f5b10aSHannes Eder 12477f5b10aSHannes Eder exit($exitcode); 12577f5b10aSHannes Eder} 12677f5b10aSHannes Eder 1273beb42ecSJoe Perchessub uniq { 1283beb42ecSJoe Perches my %seen; 1293beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1303beb42ecSJoe Perches} 1313beb42ecSJoe Perches 1323beb42ecSJoe Perchessub list_types { 1333beb42ecSJoe Perches my ($exitcode) = @_; 1343beb42ecSJoe Perches 1353beb42ecSJoe Perches my $count = 0; 1363beb42ecSJoe Perches 1373beb42ecSJoe Perches local $/ = undef; 1383beb42ecSJoe Perches 1393beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1403beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1413beb42ecSJoe Perches 1423beb42ecSJoe Perches my $text = <$script>; 1433beb42ecSJoe Perches close($script); 1443beb42ecSJoe Perches 1453beb42ecSJoe Perches my @types = (); 1463beb42ecSJoe Perches for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { 1473beb42ecSJoe Perches push (@types, $_); 1483beb42ecSJoe Perches } 1493beb42ecSJoe Perches @types = sort(uniq(@types)); 1503beb42ecSJoe Perches print("#\tMessage type\n\n"); 1513beb42ecSJoe Perches foreach my $type (@types) { 1523beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1533beb42ecSJoe Perches } 1543beb42ecSJoe Perches 1553beb42ecSJoe Perches exit($exitcode); 1563beb42ecSJoe Perches} 1573beb42ecSJoe Perches 158000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 159000d1cc1SJoe Perchesif (-f $conf) { 160000d1cc1SJoe Perches my @conf_args; 161000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 162000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 163000d1cc1SJoe Perches 164000d1cc1SJoe Perches while (<$conffile>) { 165000d1cc1SJoe Perches my $line = $_; 166000d1cc1SJoe Perches 167000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 168000d1cc1SJoe Perches $line =~ s/^\s*//g; 169000d1cc1SJoe Perches $line =~ s/\s+/ /g; 170000d1cc1SJoe Perches 171000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 172000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 173000d1cc1SJoe Perches 174000d1cc1SJoe Perches my @words = split(" ", $line); 175000d1cc1SJoe Perches foreach my $word (@words) { 176000d1cc1SJoe Perches last if ($word =~ m/^#/); 177000d1cc1SJoe Perches push (@conf_args, $word); 178000d1cc1SJoe Perches } 179000d1cc1SJoe Perches } 180000d1cc1SJoe Perches close($conffile); 181000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 182000d1cc1SJoe Perches} 183000d1cc1SJoe Perches 1840a920b5bSAndy WhitcroftGetOptions( 1856c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 1860a920b5bSAndy Whitcroft 'tree!' => \$tree, 1870a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 1880a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 1896c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 1908905a67cSAndy Whitcroft 'terse!' => \$terse, 19134d8815fSJoe Perches 'showfile!' => \$showfile, 19277f5b10aSHannes Eder 'f|file!' => \$file, 1934a593c34SDu, Changbin 'g|git!' => \$git, 1946c72ffaaSAndy Whitcroft 'subjective!' => \$check, 1956c72ffaaSAndy Whitcroft 'strict!' => \$check, 196000d1cc1SJoe Perches 'ignore=s' => \@ignore, 19791bfe484SJoe Perches 'types=s' => \@use, 198000d1cc1SJoe Perches 'show-types!' => \$show_types, 1993beb42ecSJoe Perches 'list-types!' => \$list_types, 2006cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 20156193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 2026c72ffaaSAndy Whitcroft 'root=s' => \$root, 2038905a67cSAndy Whitcroft 'summary!' => \$summary, 2048905a67cSAndy Whitcroft 'mailback!' => \$mailback, 20513214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2063705ce5bSJoe Perches 'fix!' => \$fix, 2079624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 208d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 209c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 210773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 211ebfd7d62SJoe Perches 'codespell!' => \$codespell, 212ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 21375ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 21457230297SJoe Perches 'color!' => \$color, 21577f5b10aSHannes Eder 'h|help' => \$help, 21677f5b10aSHannes Eder 'version' => \$help 21777f5b10aSHannes Eder) or help(1); 21877f5b10aSHannes Eder 21977f5b10aSHannes Ederhelp(0) if ($help); 2200a920b5bSAndy Whitcroft 2213beb42ecSJoe Percheslist_types(0) if ($list_types); 2223beb42ecSJoe Perches 2239624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2242ac73b4fSJoe Perches$check_orig = $check; 2259624b8d6SJoe Perches 2260a920b5bSAndy Whitcroftmy $exit = 0; 2270a920b5bSAndy Whitcroft 228d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 229d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 230d62a201fSDave Hansen if (!$ignore_perl_version) { 231d62a201fSDave Hansen exit(1); 232d62a201fSDave Hansen } 233d62a201fSDave Hansen} 234d62a201fSDave Hansen 23545107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2360a920b5bSAndy Whitcroftif ($#ARGV < 0) { 23745107ff6SAllen Hubbe push(@ARGV, '-'); 2380a920b5bSAndy Whitcroft} 2390a920b5bSAndy Whitcroft 24091bfe484SJoe Perchessub hash_save_array_words { 24191bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 24291bfe484SJoe Perches 24391bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 24491bfe484SJoe Perches foreach my $word (@array) { 245000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 246000d1cc1SJoe Perches $word =~ s/^\s*//g; 247000d1cc1SJoe Perches $word =~ s/\s+/ /g; 248000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 249000d1cc1SJoe Perches 250000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 251000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 252000d1cc1SJoe Perches 25391bfe484SJoe Perches $hashRef->{$word}++; 254000d1cc1SJoe Perches } 25591bfe484SJoe Perches} 25691bfe484SJoe Perches 25791bfe484SJoe Perchessub hash_show_words { 25891bfe484SJoe Perches my ($hashRef, $prefix) = @_; 25991bfe484SJoe Perches 2603c816e49SJoe Perches if (keys %$hashRef) { 261d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 26258cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 26391bfe484SJoe Perches print " $word"; 26491bfe484SJoe Perches } 265d8469f16SJoe Perches print "\n"; 26691bfe484SJoe Perches } 26791bfe484SJoe Perches} 26891bfe484SJoe Perches 26991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 27091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 271000d1cc1SJoe Perches 272c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 273c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 2747429c690SAndy Whitcroftmy $dbg_type = 0; 275a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 276c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 27721caa13cSAndy Whitcroft ## no critic 27821caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 27921caa13cSAndy Whitcroft die "$@" if ($@); 280c2fdda0dSAndy Whitcroft} 281c2fdda0dSAndy Whitcroft 282d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 283d2c0a235SAndy Whitcroft 2848905a67cSAndy Whitcroftif ($terse) { 2858905a67cSAndy Whitcroft $emacs = 1; 2868905a67cSAndy Whitcroft $quiet++; 2878905a67cSAndy Whitcroft} 2888905a67cSAndy Whitcroft 2896c72ffaaSAndy Whitcroftif ($tree) { 2906c72ffaaSAndy Whitcroft if (defined $root) { 2916c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 2926c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 2936c72ffaaSAndy Whitcroft } 2946c72ffaaSAndy Whitcroft } else { 2956c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 2966c72ffaaSAndy Whitcroft $root = '.'; 2976c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 2986c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 2996c72ffaaSAndy Whitcroft $root = $1; 3006c72ffaaSAndy Whitcroft } 3016c72ffaaSAndy Whitcroft } 3026c72ffaaSAndy Whitcroft 3036c72ffaaSAndy Whitcroft if (!defined $root) { 3040a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3050a920b5bSAndy Whitcroft exit(2); 3060a920b5bSAndy Whitcroft } 3076c72ffaaSAndy Whitcroft} 3086c72ffaaSAndy Whitcroft 3096c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3106c72ffaaSAndy Whitcroft 3112ceb532bSAndy Whitcroftour $Ident = qr{ 3122ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3132ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3142ceb532bSAndy Whitcroft }x; 3156c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3166c72ffaaSAndy Whitcroftour $Sparse = qr{ 3176c72ffaaSAndy Whitcroft __user| 3186c72ffaaSAndy Whitcroft __kernel| 3196c72ffaaSAndy Whitcroft __force| 3206c72ffaaSAndy Whitcroft __iomem| 3216c72ffaaSAndy Whitcroft __must_check| 3226c72ffaaSAndy Whitcroft __init_refok| 323417495edSAndy Whitcroft __kprobes| 324165e72a6SSven Eckelmann __ref| 325ad315455SBoqun Feng __rcu| 326ad315455SBoqun Feng __private 3276c72ffaaSAndy Whitcroft }x; 328e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 329e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 330e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 331e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 332e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3338716de38SJoe Perches 33452131292SWolfram Sang# Notes to $Attribute: 33552131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3366c72ffaaSAndy Whitcroftour $Attribute = qr{ 3376c72ffaaSAndy Whitcroft const| 33803f1df7dSJoe Perches __percpu| 33903f1df7dSJoe Perches __nocast| 34003f1df7dSJoe Perches __safe| 34146d832f5SMichael S. Tsirkin __bitwise| 34203f1df7dSJoe Perches __packed__| 34303f1df7dSJoe Perches __packed2__| 34403f1df7dSJoe Perches __naked| 34503f1df7dSJoe Perches __maybe_unused| 34603f1df7dSJoe Perches __always_unused| 34703f1df7dSJoe Perches __noreturn| 34803f1df7dSJoe Perches __used| 34903f1df7dSJoe Perches __cold| 350e23ef1f3SJoe Perches __pure| 35103f1df7dSJoe Perches __noclone| 35203f1df7dSJoe Perches __deprecated| 3536c72ffaaSAndy Whitcroft __read_mostly| 3546c72ffaaSAndy Whitcroft __kprobes| 3558716de38SJoe Perches $InitAttribute| 35624e1d81aSAndy Whitcroft ____cacheline_aligned| 35724e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 3585fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 3595fe3af11SAndy Whitcroft __weak 3606c72ffaaSAndy Whitcroft }x; 361c45dcabdSAndy Whitcroftour $Modifier; 36291cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 3636c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 3646c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 3656c72ffaaSAndy Whitcroft 36695e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 36795e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 36895e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 36995e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 3702435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 371c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 372326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 373326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 374326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 37574349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 3762435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 377326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 378447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 37923f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 3806c72ffaaSAndy Whitcroftour $Operators = qr{ 3816c72ffaaSAndy Whitcroft <=|>=|==|!=| 3826c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 38323f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 3846c72ffaaSAndy Whitcroft }x; 3856c72ffaaSAndy Whitcroft 38691cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 38791cb5195SJoe Perches 388ab7e23f3SJoe Perchesour $BasicType; 3898905a67cSAndy Whitcroftour $NonptrType; 3901813087dSJoe Perchesour $NonptrTypeMisordered; 3918716de38SJoe Perchesour $NonptrTypeWithAttr; 3928905a67cSAndy Whitcroftour $Type; 3931813087dSJoe Perchesour $TypeMisordered; 3948905a67cSAndy Whitcroftour $Declare; 3951813087dSJoe Perchesour $DeclareMisordered; 3968905a67cSAndy Whitcroft 39715662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 39815662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 399171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 400171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 401171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 402171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 403171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 404171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 405171ae1a4SAndy Whitcroft}x; 406171ae1a4SAndy Whitcroft 40715662b3eSJoe Perchesour $UTF8 = qr{ 40815662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 40915662b3eSJoe Perches | $NON_ASCII_UTF8 41015662b3eSJoe Perches}x; 41115662b3eSJoe Perches 412e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 413021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 414021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 415021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 416021158b4SJoe Perches)}; 417e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 418fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4198ed22cadSAndy Whitcroft atomic_t 4208ed22cadSAndy Whitcroft)}; 421e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 422e6176fa4SJoe Perches $typeC99Typedefs\b| 423e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 424e6176fa4SJoe Perches $typeKernelTypedefs\b 425e6176fa4SJoe Perches)}; 4268ed22cadSAndy Whitcroft 4276d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4286d32f7a3SJoe Perches 429691e669bSJoe Perchesour $logFunctions = qr{(?x: 430758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4317d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 4326e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 433b0531722SJoe Perches panic| 43406668727SJoe Perches MODULE_[A-Z_]+| 43506668727SJoe Perches seq_vprintf|seq_printf|seq_puts 436691e669bSJoe Perches)}; 437691e669bSJoe Perches 43820112475SJoe Perchesour $signature_tags = qr{(?xi: 43920112475SJoe Perches Signed-off-by:| 44020112475SJoe Perches Acked-by:| 44120112475SJoe Perches Tested-by:| 44220112475SJoe Perches Reviewed-by:| 44320112475SJoe Perches Reported-by:| 4448543ae12SMugunthan V N Suggested-by:| 44520112475SJoe Perches To:| 44620112475SJoe Perches Cc: 44720112475SJoe Perches)}; 44820112475SJoe Perches 4491813087dSJoe Perchesour @typeListMisordered = ( 4501813087dSJoe Perches qr{char\s+(?:un)?signed}, 4511813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 4521813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 4531813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 4541813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 4551813087dSJoe Perches qr{short\s+(?:un)?signed}, 4561813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 4571813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 4581813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 4591813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 4601813087dSJoe Perches qr{int\s+(?:un)?signed}, 4611813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 4621813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 4631813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 4641813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 4651813087dSJoe Perches qr{long\s+(?:un)?signed}, 4661813087dSJoe Perches); 4671813087dSJoe Perches 4688905a67cSAndy Whitcroftour @typeList = ( 4698905a67cSAndy Whitcroft qr{void}, 4700c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 4710c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 4720c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 4730c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 4740c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 4750c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 4760c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 4770c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 4780c773d9dSJoe Perches qr{(?:un)?signed}, 4798905a67cSAndy Whitcroft qr{float}, 4808905a67cSAndy Whitcroft qr{double}, 4818905a67cSAndy Whitcroft qr{bool}, 4828905a67cSAndy Whitcroft qr{struct\s+$Ident}, 4838905a67cSAndy Whitcroft qr{union\s+$Ident}, 4848905a67cSAndy Whitcroft qr{enum\s+$Ident}, 4858905a67cSAndy Whitcroft qr{${Ident}_t}, 4868905a67cSAndy Whitcroft qr{${Ident}_handler}, 4878905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 4881813087dSJoe Perches @typeListMisordered, 4898905a67cSAndy Whitcroft); 490938224b5SJoe Perches 491938224b5SJoe Perchesour $C90_int_types = qr{(?x: 492938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 493938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 494938224b5SJoe Perches long\s+long\s+(?:un)?signed| 495938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 496938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 497938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 498938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 499938224b5SJoe Perches 500938224b5SJoe Perches long\s+int\s+(?:un)?signed| 501938224b5SJoe Perches long\s+(?:un)?signed\s+int| 502938224b5SJoe Perches long\s+(?:un)?signed| 503938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 504938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 505938224b5SJoe Perches int\s+long\s+(?:un)?signed| 506938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 507938224b5SJoe Perches 508938224b5SJoe Perches int\s+(?:un)?signed| 509938224b5SJoe Perches (?:(?:un)?signed\s+)?int 510938224b5SJoe Perches)}; 511938224b5SJoe Perches 512485ff23eSAlex Dowadour @typeListFile = (); 5138716de38SJoe Perchesour @typeListWithAttr = ( 5148716de38SJoe Perches @typeList, 5158716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 5168716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 5178716de38SJoe Perches); 5188716de38SJoe Perches 519c45dcabdSAndy Whitcroftour @modifierList = ( 520c45dcabdSAndy Whitcroft qr{fastcall}, 521c45dcabdSAndy Whitcroft); 522485ff23eSAlex Dowadour @modifierListFile = (); 5238905a67cSAndy Whitcroft 5242435880fSJoe Perchesour @mode_permission_funcs = ( 5252435880fSJoe Perches ["module_param", 3], 5262435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 5272435880fSJoe Perches ["module_param_array_named", 5], 5282435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 5292435880fSJoe Perches ["proc_create(?:_data|)", 2], 530459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 531459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 532459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 533459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 534459cf0aeSJoe Perches ["__ATTR", 2], 5352435880fSJoe Perches); 5362435880fSJoe Perches 537515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 538515a235eSJoe Perchesour $mode_perms_search = ""; 539515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 540515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 541515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 542515a235eSJoe Perches} 543515a235eSJoe Perches 544b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 545b392c64fSJoe Perches S_IWUGO | 546b392c64fSJoe Perches S_IWOTH | 547b392c64fSJoe Perches S_IRWXUGO | 548b392c64fSJoe Perches S_IALLUGO | 549b392c64fSJoe Perches 0[0-7][0-7][2367] 550b392c64fSJoe Perches}x; 551b392c64fSJoe Perches 552f90774e1SJoe Perchesour %mode_permission_string_types = ( 553f90774e1SJoe Perches "S_IRWXU" => 0700, 554f90774e1SJoe Perches "S_IRUSR" => 0400, 555f90774e1SJoe Perches "S_IWUSR" => 0200, 556f90774e1SJoe Perches "S_IXUSR" => 0100, 557f90774e1SJoe Perches "S_IRWXG" => 0070, 558f90774e1SJoe Perches "S_IRGRP" => 0040, 559f90774e1SJoe Perches "S_IWGRP" => 0020, 560f90774e1SJoe Perches "S_IXGRP" => 0010, 561f90774e1SJoe Perches "S_IRWXO" => 0007, 562f90774e1SJoe Perches "S_IROTH" => 0004, 563f90774e1SJoe Perches "S_IWOTH" => 0002, 564f90774e1SJoe Perches "S_IXOTH" => 0001, 565f90774e1SJoe Perches "S_IRWXUGO" => 0777, 566f90774e1SJoe Perches "S_IRUGO" => 0444, 567f90774e1SJoe Perches "S_IWUGO" => 0222, 568f90774e1SJoe Perches "S_IXUGO" => 0111, 569f90774e1SJoe Perches); 570f90774e1SJoe Perches 571f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 572f90774e1SJoe Perchesour $mode_perms_string_search = ""; 573f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 574f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 575f90774e1SJoe Perches $mode_perms_string_search .= $entry; 576f90774e1SJoe Perches} 577f90774e1SJoe Perches 5787840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 5797840a94cSWolfram Sang irq| 580cdcee686SSergey Ryazanov memory| 581cdcee686SSergey Ryazanov time| 582cdcee686SSergey Ryazanov reboot 5837840a94cSWolfram Sang)}; 5847840a94cSWolfram Sang# memory.h: ARM has a custom one 5857840a94cSWolfram Sang 58666b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 58766b47b4aSKees Cookmy $misspellings; 58866b47b4aSKees Cookmy %spelling_fix; 58936061e38SJoe Perches 59036061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 59166b47b4aSKees Cook while (<$spelling>) { 59266b47b4aSKees Cook my $line = $_; 59366b47b4aSKees Cook 59466b47b4aSKees Cook $line =~ s/\s*\n?$//g; 59566b47b4aSKees Cook $line =~ s/^\s*//g; 59666b47b4aSKees Cook 59766b47b4aSKees Cook next if ($line =~ m/^\s*#/); 59866b47b4aSKees Cook next if ($line =~ m/^\s*$/); 59966b47b4aSKees Cook 60066b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 60166b47b4aSKees Cook 60266b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 60366b47b4aSKees Cook } 60466b47b4aSKees Cook close($spelling); 60536061e38SJoe Perches} else { 60636061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 60736061e38SJoe Perches} 60866b47b4aSKees Cook 609ebfd7d62SJoe Perchesif ($codespell) { 610ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 611ebfd7d62SJoe Perches while (<$spelling>) { 612ebfd7d62SJoe Perches my $line = $_; 613ebfd7d62SJoe Perches 614ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 615ebfd7d62SJoe Perches $line =~ s/^\s*//g; 616ebfd7d62SJoe Perches 617ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 618ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 619ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 620ebfd7d62SJoe Perches 621ebfd7d62SJoe Perches $line =~ s/,.*$//; 622ebfd7d62SJoe Perches 623ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 624ebfd7d62SJoe Perches 625ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 626ebfd7d62SJoe Perches } 627ebfd7d62SJoe Perches close($spelling); 628ebfd7d62SJoe Perches } else { 629ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 630ebfd7d62SJoe Perches } 631ebfd7d62SJoe Perches} 632ebfd7d62SJoe Perches 633ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 634ebfd7d62SJoe Perches 63575ad8c57SJerome Forissiersub read_words { 63675ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 63775ad8c57SJerome Forissier 63875ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 63975ad8c57SJerome Forissier while (<$words>) { 640bf1fa1daSJoe Perches my $line = $_; 641bf1fa1daSJoe Perches 642bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 643bf1fa1daSJoe Perches $line =~ s/^\s*//g; 644bf1fa1daSJoe Perches 645bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 646bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 647bf1fa1daSJoe Perches if ($line =~ /\s/) { 64875ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 649bf1fa1daSJoe Perches next; 650bf1fa1daSJoe Perches } 651bf1fa1daSJoe Perches 65275ad8c57SJerome Forissier $$wordsRef .= '|' if ($$wordsRef ne ""); 65375ad8c57SJerome Forissier $$wordsRef .= $line; 654bf1fa1daSJoe Perches } 65575ad8c57SJerome Forissier close($file); 65675ad8c57SJerome Forissier return 1; 657bf1fa1daSJoe Perches } 658bf1fa1daSJoe Perches 65975ad8c57SJerome Forissier return 0; 66075ad8c57SJerome Forissier} 66175ad8c57SJerome Forissier 66275ad8c57SJerome Forissiermy $const_structs = ""; 66375ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile) 66475ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 66575ad8c57SJerome Forissier 66675ad8c57SJerome Forissiermy $typeOtherTypedefs = ""; 66775ad8c57SJerome Forissierif (length($typedefsfile)) { 66875ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 66975ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 67075ad8c57SJerome Forissier} 67175ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); 67275ad8c57SJerome Forissier 6738905a67cSAndy Whitcroftsub build_types { 674485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 675485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 6761813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 6778716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 678c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 679ab7e23f3SJoe Perches $BasicType = qr{ 680ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 681ab7e23f3SJoe Perches (?:${all}\b) 682ab7e23f3SJoe Perches }x; 6838905a67cSAndy Whitcroft $NonptrType = qr{ 684d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 685cf655043SAndy Whitcroft (?: 6866b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 6878ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 688c45dcabdSAndy Whitcroft (?:${all}\b) 689cf655043SAndy Whitcroft ) 690c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 6918905a67cSAndy Whitcroft }x; 6921813087dSJoe Perches $NonptrTypeMisordered = qr{ 6931813087dSJoe Perches (?:$Modifier\s+|const\s+)* 6941813087dSJoe Perches (?: 6951813087dSJoe Perches (?:${Misordered}\b) 6961813087dSJoe Perches ) 6971813087dSJoe Perches (?:\s+$Modifier|\s+const)* 6981813087dSJoe Perches }x; 6998716de38SJoe Perches $NonptrTypeWithAttr = qr{ 7008716de38SJoe Perches (?:$Modifier\s+|const\s+)* 7018716de38SJoe Perches (?: 7028716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 7038716de38SJoe Perches (?:$typeTypedefs\b)| 7048716de38SJoe Perches (?:${allWithAttr}\b) 7058716de38SJoe Perches ) 7068716de38SJoe Perches (?:\s+$Modifier|\s+const)* 7078716de38SJoe Perches }x; 7088905a67cSAndy Whitcroft $Type = qr{ 709c45dcabdSAndy Whitcroft $NonptrType 7101574a29fSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 711c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 7128905a67cSAndy Whitcroft }x; 7131813087dSJoe Perches $TypeMisordered = qr{ 7141813087dSJoe Perches $NonptrTypeMisordered 7151813087dSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 7161813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 7171813087dSJoe Perches }x; 71891cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 7191813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 7208905a67cSAndy Whitcroft} 7218905a67cSAndy Whitcroftbuild_types(); 7226c72ffaaSAndy Whitcroft 7237d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 724d1fe9c09SJoe Perches 725d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 726d1fe9c09SJoe Perches# requires at least perl version v5.10.0 727d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 728d1fe9c09SJoe Perches 729d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 7302435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 731c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 7327d2367afSJoe Perches 733f8422308SJoe Perchesour $declaration_macros = qr{(?x: 7343e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 735f8422308SJoe Perches (?:$Storage\s+)?LIST_HEAD\s*\(| 736f8422308SJoe Perches (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( 737f8422308SJoe Perches)}; 738f8422308SJoe Perches 7397d2367afSJoe Perchessub deparenthesize { 7407d2367afSJoe Perches my ($string) = @_; 7417d2367afSJoe Perches return "" if (!defined($string)); 7425b9553abSJoe Perches 7435b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 7445b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 7455b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 7465b9553abSJoe Perches } 7475b9553abSJoe Perches 7487d2367afSJoe Perches $string =~ s@\s+@ @g; 7495b9553abSJoe Perches 7507d2367afSJoe Perches return $string; 7517d2367afSJoe Perches} 7527d2367afSJoe Perches 7533445686aSJoe Perchessub seed_camelcase_file { 7543445686aSJoe Perches my ($file) = @_; 7553445686aSJoe Perches 7563445686aSJoe Perches return if (!(-f $file)); 7573445686aSJoe Perches 7583445686aSJoe Perches local $/; 7593445686aSJoe Perches 7603445686aSJoe Perches open(my $include_file, '<', "$file") 7613445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 7623445686aSJoe Perches my $text = <$include_file>; 7633445686aSJoe Perches close($include_file); 7643445686aSJoe Perches 7653445686aSJoe Perches my @lines = split('\n', $text); 7663445686aSJoe Perches 7673445686aSJoe Perches foreach my $line (@lines) { 7683445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 7693445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 7703445686aSJoe Perches $camelcase{$1} = 1; 77111ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 77211ea516aSJoe Perches $camelcase{$1} = 1; 77311ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 7743445686aSJoe Perches $camelcase{$1} = 1; 7753445686aSJoe Perches } 7763445686aSJoe Perches } 7773445686aSJoe Perches} 7783445686aSJoe Perches 77985b0ee18SJoe Perchessub is_maintained_obsolete { 78085b0ee18SJoe Perches my ($filename) = @_; 78185b0ee18SJoe Perches 782f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 78385b0ee18SJoe Perches 7840616efa4SJoe Perches my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 78585b0ee18SJoe Perches 78685b0ee18SJoe Perches return $status =~ /obsolete/i; 78785b0ee18SJoe Perches} 78885b0ee18SJoe Perches 7893445686aSJoe Perchesmy $camelcase_seeded = 0; 7903445686aSJoe Perchessub seed_camelcase_includes { 7913445686aSJoe Perches return if ($camelcase_seeded); 7923445686aSJoe Perches 7933445686aSJoe Perches my $files; 794c707a81dSJoe Perches my $camelcase_cache = ""; 795c707a81dSJoe Perches my @include_files = (); 796c707a81dSJoe Perches 797c707a81dSJoe Perches $camelcase_seeded = 1; 798351b2a1fSJoe Perches 7993645e328SRichard Genoud if (-e ".git") { 800351b2a1fSJoe Perches my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; 801351b2a1fSJoe Perches chomp $git_last_include_commit; 802c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 803c707a81dSJoe Perches } else { 804c707a81dSJoe Perches my $last_mod_date = 0; 805c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 806c707a81dSJoe Perches @include_files = split('\n', $files); 807c707a81dSJoe Perches foreach my $file (@include_files) { 808c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 809c707a81dSJoe Perches localtime((stat $file)[9])); 810c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 811c707a81dSJoe Perches } 812c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 813c707a81dSJoe Perches } 814c707a81dSJoe Perches 815c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 816c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 817c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 818351b2a1fSJoe Perches while (<$camelcase_file>) { 819351b2a1fSJoe Perches chomp; 820351b2a1fSJoe Perches $camelcase{$_} = 1; 821351b2a1fSJoe Perches } 822351b2a1fSJoe Perches close($camelcase_file); 823351b2a1fSJoe Perches 824351b2a1fSJoe Perches return; 825351b2a1fSJoe Perches } 826c707a81dSJoe Perches 8273645e328SRichard Genoud if (-e ".git") { 828c707a81dSJoe Perches $files = `git ls-files "include/*.h"`; 829c707a81dSJoe Perches @include_files = split('\n', $files); 8303445686aSJoe Perches } 831c707a81dSJoe Perches 8323445686aSJoe Perches foreach my $file (@include_files) { 8333445686aSJoe Perches seed_camelcase_file($file); 8343445686aSJoe Perches } 835351b2a1fSJoe Perches 836c707a81dSJoe Perches if ($camelcase_cache ne "") { 837351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 838c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 839c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 840351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 841351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 842351b2a1fSJoe Perches } 843351b2a1fSJoe Perches close($camelcase_file); 844351b2a1fSJoe Perches } 8453445686aSJoe Perches} 8463445686aSJoe Perches 847d311cd44SJoe Perchessub git_commit_info { 848d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 849d311cd44SJoe Perches 850d311cd44SJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 851d311cd44SJoe Perches 852d311cd44SJoe Perches my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; 853d311cd44SJoe Perches $output =~ s/^\s*//gm; 854d311cd44SJoe Perches my @lines = split("\n", $output); 855d311cd44SJoe Perches 8560d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 8570d7835fcSJoe Perches 858d311cd44SJoe Perches if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { 859d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 860d311cd44SJoe Perches# all matching commit ids, but it's very slow... 861d311cd44SJoe Perches# 862d311cd44SJoe Perches# echo "checking commits $1..." 863d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 864d311cd44SJoe Perches# while read line ; do 865d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 866d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 867d311cd44SJoe Perches# done 868d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 869d311cd44SJoe Perches } else { 870d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 871d311cd44SJoe Perches $desc = substr($lines[0], 41); 872d311cd44SJoe Perches } 873d311cd44SJoe Perches 874d311cd44SJoe Perches return ($id, $desc); 875d311cd44SJoe Perches} 876d311cd44SJoe Perches 8776c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 8780a920b5bSAndy Whitcroft 87900df344fSAndy Whitcroftmy @rawlines = (); 880c2fdda0dSAndy Whitcroftmy @lines = (); 8813705ce5bSJoe Perchesmy @fixed = (); 882d752fcc8SJoe Perchesmy @fixed_inserted = (); 883d752fcc8SJoe Perchesmy @fixed_deleted = (); 884194f66fcSJoe Perchesmy $fixlinenr = -1; 885194f66fcSJoe Perches 8864a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 8874a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 8884a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git"); 8894a593c34SDu, Changbin 8904a593c34SDu, Changbinif ($git) { 8914a593c34SDu, Changbin my @commits = (); 8920dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 8934a593c34SDu, Changbin my $git_range; 89428898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 89528898fd1SJoe Perches $git_range = "-$2 $1"; 8964a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 8974a593c34SDu, Changbin $git_range = "$commit_expr"; 8984a593c34SDu, Changbin } else { 8990dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 9000dea9f1eSJoe Perches } 9010dea9f1eSJoe Perches my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 9020dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 90328898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 90428898fd1SJoe Perches next if (!defined($1) || !defined($2)); 9050dea9f1eSJoe Perches my $sha1 = $1; 9060dea9f1eSJoe Perches my $subject = $2; 9070dea9f1eSJoe Perches unshift(@commits, $sha1); 9080dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 9094a593c34SDu, Changbin } 9104a593c34SDu, Changbin } 9114a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 9124a593c34SDu, Changbin @ARGV = @commits; 9134a593c34SDu, Changbin} 9144a593c34SDu, Changbin 915c2fdda0dSAndy Whitcroftmy $vname; 9166c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 91721caa13cSAndy Whitcroft my $FILE; 9184a593c34SDu, Changbin if ($git) { 9194a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 9204a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 9214a593c34SDu, Changbin } elsif ($file) { 92221caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 9236c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 92421caa13cSAndy Whitcroft } elsif ($filename eq '-') { 92521caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 9266c72ffaaSAndy Whitcroft } else { 92721caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 9286c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 9296c72ffaaSAndy Whitcroft } 930c2fdda0dSAndy Whitcroft if ($filename eq '-') { 931c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 9324a593c34SDu, Changbin } elsif ($git) { 9330dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 934c2fdda0dSAndy Whitcroft } else { 935c2fdda0dSAndy Whitcroft $vname = $filename; 936c2fdda0dSAndy Whitcroft } 93721caa13cSAndy Whitcroft while (<$FILE>) { 9380a920b5bSAndy Whitcroft chomp; 93900df344fSAndy Whitcroft push(@rawlines, $_); 9406c72ffaaSAndy Whitcroft } 94121caa13cSAndy Whitcroft close($FILE); 942d8469f16SJoe Perches 943d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 944d8469f16SJoe Perches print '-' x length($vname) . "\n"; 945d8469f16SJoe Perches print "$vname\n"; 946d8469f16SJoe Perches print '-' x length($vname) . "\n"; 947d8469f16SJoe Perches } 948d8469f16SJoe Perches 949c2fdda0dSAndy Whitcroft if (!process($filename)) { 9500a920b5bSAndy Whitcroft $exit = 1; 9510a920b5bSAndy Whitcroft } 95200df344fSAndy Whitcroft @rawlines = (); 95313214adfSAndy Whitcroft @lines = (); 9543705ce5bSJoe Perches @fixed = (); 955d752fcc8SJoe Perches @fixed_inserted = (); 956d752fcc8SJoe Perches @fixed_deleted = (); 957194f66fcSJoe Perches $fixlinenr = -1; 958485ff23eSAlex Dowad @modifierListFile = (); 959485ff23eSAlex Dowad @typeListFile = (); 960485ff23eSAlex Dowad build_types(); 9610a920b5bSAndy Whitcroft} 9620a920b5bSAndy Whitcroft 963d8469f16SJoe Perchesif (!$quiet) { 9643c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 9653c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 9663c816e49SJoe Perches 967d8469f16SJoe Perches if ($^V lt 5.10.0) { 968d8469f16SJoe Perches print << "EOM" 969d8469f16SJoe Perches 970d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 971d8469f16SJoe Perches An upgrade to at least perl v5.10.0 is suggested. 972d8469f16SJoe PerchesEOM 973d8469f16SJoe Perches } 974d8469f16SJoe Perches if ($exit) { 975d8469f16SJoe Perches print << "EOM" 976d8469f16SJoe Perches 977d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 978d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 979d8469f16SJoe PerchesEOM 980d8469f16SJoe Perches } 981d8469f16SJoe Perches} 982d8469f16SJoe Perches 9830a920b5bSAndy Whitcroftexit($exit); 9840a920b5bSAndy Whitcroft 9850a920b5bSAndy Whitcroftsub top_of_kernel_tree { 9866c72ffaaSAndy Whitcroft my ($root) = @_; 9876c72ffaaSAndy Whitcroft 9886c72ffaaSAndy Whitcroft my @tree_check = ( 9896c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 9906c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 9916c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 9926c72ffaaSAndy Whitcroft ); 9936c72ffaaSAndy Whitcroft 9946c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 9956c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 9960a920b5bSAndy Whitcroft return 0; 9970a920b5bSAndy Whitcroft } 9986c72ffaaSAndy Whitcroft } 9996c72ffaaSAndy Whitcroft return 1; 10006c72ffaaSAndy Whitcroft} 10010a920b5bSAndy Whitcroft 100220112475SJoe Perchessub parse_email { 100320112475SJoe Perches my ($formatted_email) = @_; 100420112475SJoe Perches 100520112475SJoe Perches my $name = ""; 100620112475SJoe Perches my $address = ""; 100720112475SJoe Perches my $comment = ""; 100820112475SJoe Perches 100920112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 101020112475SJoe Perches $name = $1; 101120112475SJoe Perches $address = $2; 101220112475SJoe Perches $comment = $3 if defined $3; 101320112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 101420112475SJoe Perches $address = $1; 101520112475SJoe Perches $comment = $2 if defined $2; 101620112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 101720112475SJoe Perches $address = $1; 101820112475SJoe Perches $comment = $2 if defined $2; 101920112475SJoe Perches $formatted_email =~ s/$address.*$//; 102020112475SJoe Perches $name = $formatted_email; 10213705ce5bSJoe Perches $name = trim($name); 102220112475SJoe Perches $name =~ s/^\"|\"$//g; 102320112475SJoe Perches # If there's a name left after stripping spaces and 102420112475SJoe Perches # leading quotes, and the address doesn't have both 102520112475SJoe Perches # leading and trailing angle brackets, the address 102620112475SJoe Perches # is invalid. ie: 102720112475SJoe Perches # "joe smith [email protected]" bad 102820112475SJoe Perches # "joe smith <[email protected]" bad 102920112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 103020112475SJoe Perches $name = ""; 103120112475SJoe Perches $address = ""; 103220112475SJoe Perches $comment = ""; 103320112475SJoe Perches } 103420112475SJoe Perches } 103520112475SJoe Perches 10363705ce5bSJoe Perches $name = trim($name); 103720112475SJoe Perches $name =~ s/^\"|\"$//g; 10383705ce5bSJoe Perches $address = trim($address); 103920112475SJoe Perches $address =~ s/^\<|\>$//g; 104020112475SJoe Perches 104120112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 104220112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 104320112475SJoe Perches $name = "\"$name\""; 104420112475SJoe Perches } 104520112475SJoe Perches 104620112475SJoe Perches return ($name, $address, $comment); 104720112475SJoe Perches} 104820112475SJoe Perches 104920112475SJoe Perchessub format_email { 105020112475SJoe Perches my ($name, $address) = @_; 105120112475SJoe Perches 105220112475SJoe Perches my $formatted_email; 105320112475SJoe Perches 10543705ce5bSJoe Perches $name = trim($name); 105520112475SJoe Perches $name =~ s/^\"|\"$//g; 10563705ce5bSJoe Perches $address = trim($address); 105720112475SJoe Perches 105820112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 105920112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 106020112475SJoe Perches $name = "\"$name\""; 106120112475SJoe Perches } 106220112475SJoe Perches 106320112475SJoe Perches if ("$name" eq "") { 106420112475SJoe Perches $formatted_email = "$address"; 106520112475SJoe Perches } else { 106620112475SJoe Perches $formatted_email = "$name <$address>"; 106720112475SJoe Perches } 106820112475SJoe Perches 106920112475SJoe Perches return $formatted_email; 107020112475SJoe Perches} 107120112475SJoe Perches 1072d311cd44SJoe Perchessub which { 1073d311cd44SJoe Perches my ($bin) = @_; 1074d311cd44SJoe Perches 1075d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1076d311cd44SJoe Perches if (-e "$path/$bin") { 1077d311cd44SJoe Perches return "$path/$bin"; 1078d311cd44SJoe Perches } 1079d311cd44SJoe Perches } 1080d311cd44SJoe Perches 1081d311cd44SJoe Perches return ""; 1082d311cd44SJoe Perches} 1083d311cd44SJoe Perches 1084000d1cc1SJoe Perchessub which_conf { 1085000d1cc1SJoe Perches my ($conf) = @_; 1086000d1cc1SJoe Perches 1087000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1088000d1cc1SJoe Perches if (-e "$path/$conf") { 1089000d1cc1SJoe Perches return "$path/$conf"; 1090000d1cc1SJoe Perches } 1091000d1cc1SJoe Perches } 1092000d1cc1SJoe Perches 1093000d1cc1SJoe Perches return ""; 1094000d1cc1SJoe Perches} 1095000d1cc1SJoe Perches 10960a920b5bSAndy Whitcroftsub expand_tabs { 10970a920b5bSAndy Whitcroft my ($str) = @_; 10980a920b5bSAndy Whitcroft 10990a920b5bSAndy Whitcroft my $res = ''; 11000a920b5bSAndy Whitcroft my $n = 0; 11010a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 11020a920b5bSAndy Whitcroft if ($c eq "\t") { 11030a920b5bSAndy Whitcroft $res .= ' '; 11040a920b5bSAndy Whitcroft $n++; 11050a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 11060a920b5bSAndy Whitcroft $res .= ' '; 11070a920b5bSAndy Whitcroft } 11080a920b5bSAndy Whitcroft next; 11090a920b5bSAndy Whitcroft } 11100a920b5bSAndy Whitcroft $res .= $c; 11110a920b5bSAndy Whitcroft $n++; 11120a920b5bSAndy Whitcroft } 11130a920b5bSAndy Whitcroft 11140a920b5bSAndy Whitcroft return $res; 11150a920b5bSAndy Whitcroft} 11166c72ffaaSAndy Whitcroftsub copy_spacing { 1117773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 11186c72ffaaSAndy Whitcroft return $res; 11196c72ffaaSAndy Whitcroft} 11200a920b5bSAndy Whitcroft 11214a0df2efSAndy Whitcroftsub line_stats { 11224a0df2efSAndy Whitcroft my ($line) = @_; 11234a0df2efSAndy Whitcroft 11244a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 11254a0df2efSAndy Whitcroft $line =~ s/^.//; 11264a0df2efSAndy Whitcroft $line = expand_tabs($line); 11274a0df2efSAndy Whitcroft 11284a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 11294a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 11304a0df2efSAndy Whitcroft 11314a0df2efSAndy Whitcroft return (length($line), length($white)); 11324a0df2efSAndy Whitcroft} 11334a0df2efSAndy Whitcroft 1134773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1135773647a0SAndy Whitcroft 1136773647a0SAndy Whitcroftsub sanitise_line_reset { 1137773647a0SAndy Whitcroft my ($in_comment) = @_; 1138773647a0SAndy Whitcroft 1139773647a0SAndy Whitcroft if ($in_comment) { 1140773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1141773647a0SAndy Whitcroft } else { 1142773647a0SAndy Whitcroft $sanitise_quote = ''; 1143773647a0SAndy Whitcroft } 1144773647a0SAndy Whitcroft} 114500df344fSAndy Whitcroftsub sanitise_line { 114600df344fSAndy Whitcroft my ($line) = @_; 114700df344fSAndy Whitcroft 114800df344fSAndy Whitcroft my $res = ''; 114900df344fSAndy Whitcroft my $l = ''; 115000df344fSAndy Whitcroft 1151c2fdda0dSAndy Whitcroft my $qlen = 0; 1152773647a0SAndy Whitcroft my $off = 0; 1153773647a0SAndy Whitcroft my $c; 115400df344fSAndy Whitcroft 1155773647a0SAndy Whitcroft # Always copy over the diff marker. 1156773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1157773647a0SAndy Whitcroft 1158773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1159773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1160773647a0SAndy Whitcroft 1161773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 1162773647a0SAndy Whitcroft # and end, all to $;. 1163773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1164773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1165773647a0SAndy Whitcroft 1166773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1167773647a0SAndy Whitcroft $off++; 116800df344fSAndy Whitcroft next; 1169773647a0SAndy Whitcroft } 117081bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1171773647a0SAndy Whitcroft $sanitise_quote = ''; 1172773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1173773647a0SAndy Whitcroft $off++; 1174773647a0SAndy Whitcroft next; 1175773647a0SAndy Whitcroft } 1176113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1177113f04a8SDaniel Walker $sanitise_quote = '//'; 1178113f04a8SDaniel Walker 1179113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1180113f04a8SDaniel Walker $off++; 1181113f04a8SDaniel Walker next; 1182113f04a8SDaniel Walker } 1183773647a0SAndy Whitcroft 1184773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1185773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1186773647a0SAndy Whitcroft $c eq "\\") { 1187773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1188773647a0SAndy Whitcroft $off++; 1189773647a0SAndy Whitcroft next; 1190773647a0SAndy Whitcroft } 1191773647a0SAndy Whitcroft # Regular quotes. 1192773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1193773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1194773647a0SAndy Whitcroft $sanitise_quote = $c; 1195773647a0SAndy Whitcroft 1196773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1197773647a0SAndy Whitcroft next; 1198773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1199773647a0SAndy Whitcroft $sanitise_quote = ''; 120000df344fSAndy Whitcroft } 120100df344fSAndy Whitcroft } 1202773647a0SAndy Whitcroft 1203fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1204773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1205773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1206113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1207113f04a8SDaniel Walker substr($res, $off, 1, $;); 1208773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1209773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 121000df344fSAndy Whitcroft } else { 1211773647a0SAndy Whitcroft substr($res, $off, 1, $c); 121200df344fSAndy Whitcroft } 1213c2fdda0dSAndy Whitcroft } 1214c2fdda0dSAndy Whitcroft 1215113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1216113f04a8SDaniel Walker $sanitise_quote = ''; 1217113f04a8SDaniel Walker } 1218113f04a8SDaniel Walker 1219c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1220c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1221c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1222c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1223c2fdda0dSAndy Whitcroft 1224c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1225c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1226c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1227c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1228c2fdda0dSAndy Whitcroft } 1229c2fdda0dSAndy Whitcroft 1230dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1231dadf680dSJoe Perches my $match = $1; 1232dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1233dadf680dSJoe Perches } 1234dadf680dSJoe Perches 123500df344fSAndy Whitcroft return $res; 123600df344fSAndy Whitcroft} 123700df344fSAndy Whitcroft 1238a6962d72SJoe Perchessub get_quoted_string { 1239a6962d72SJoe Perches my ($line, $rawline) = @_; 1240a6962d72SJoe Perches 124133acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1242a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1243a6962d72SJoe Perches} 1244a6962d72SJoe Perches 12458905a67cSAndy Whitcroftsub ctx_statement_block { 12468905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 12478905a67cSAndy Whitcroft my $line = $linenr - 1; 12488905a67cSAndy Whitcroft my $blk = ''; 12498905a67cSAndy Whitcroft my $soff = $off; 12508905a67cSAndy Whitcroft my $coff = $off - 1; 1251773647a0SAndy Whitcroft my $coff_set = 0; 12528905a67cSAndy Whitcroft 125313214adfSAndy Whitcroft my $loff = 0; 125413214adfSAndy Whitcroft 12558905a67cSAndy Whitcroft my $type = ''; 12568905a67cSAndy Whitcroft my $level = 0; 1257a2750645SAndy Whitcroft my @stack = (); 1258cf655043SAndy Whitcroft my $p; 12598905a67cSAndy Whitcroft my $c; 12608905a67cSAndy Whitcroft my $len = 0; 126113214adfSAndy Whitcroft 126213214adfSAndy Whitcroft my $remainder; 12638905a67cSAndy Whitcroft while (1) { 1264a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1265a2750645SAndy Whitcroft 1266773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 12678905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 12688905a67cSAndy Whitcroft # context. 12698905a67cSAndy Whitcroft if ($off >= $len) { 12708905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1271dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1272c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 12738905a67cSAndy Whitcroft $remain--; 127413214adfSAndy Whitcroft $loff = $len; 1275c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 12768905a67cSAndy Whitcroft $len = length($blk); 12778905a67cSAndy Whitcroft $line++; 12788905a67cSAndy Whitcroft last; 12798905a67cSAndy Whitcroft } 12808905a67cSAndy Whitcroft # Bail if there is no further context. 12818905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 128213214adfSAndy Whitcroft if ($off >= $len) { 12838905a67cSAndy Whitcroft last; 12848905a67cSAndy Whitcroft } 1285f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1286f74bd194SAndy Whitcroft $level++; 1287f74bd194SAndy Whitcroft $type = '#'; 1288f74bd194SAndy Whitcroft } 12898905a67cSAndy Whitcroft } 1290cf655043SAndy Whitcroft $p = $c; 12918905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 129213214adfSAndy Whitcroft $remainder = substr($blk, $off); 12938905a67cSAndy Whitcroft 1294773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 12954635f4fbSAndy Whitcroft 12964635f4fbSAndy Whitcroft # Handle nested #if/#else. 12974635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 12984635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 12994635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 13004635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 13014635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 13024635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 13034635f4fbSAndy Whitcroft } 13044635f4fbSAndy Whitcroft 13058905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 13068905a67cSAndy Whitcroft # outermost level. 13078905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 13088905a67cSAndy Whitcroft last; 13098905a67cSAndy Whitcroft } 13108905a67cSAndy Whitcroft 131113214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1312773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1313773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1314773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1315773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1316773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1317773647a0SAndy Whitcroft $coff_set = 1; 1318773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1319773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 132013214adfSAndy Whitcroft } 132113214adfSAndy Whitcroft 13228905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 13238905a67cSAndy Whitcroft $level++; 13248905a67cSAndy Whitcroft $type = '('; 13258905a67cSAndy Whitcroft } 13268905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 13278905a67cSAndy Whitcroft $level--; 13288905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 13298905a67cSAndy Whitcroft 13308905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 13318905a67cSAndy Whitcroft $coff = $off; 1332773647a0SAndy Whitcroft $coff_set = 1; 1333773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 13348905a67cSAndy Whitcroft } 13358905a67cSAndy Whitcroft } 13368905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 13378905a67cSAndy Whitcroft $level++; 13388905a67cSAndy Whitcroft $type = '{'; 13398905a67cSAndy Whitcroft } 13408905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 13418905a67cSAndy Whitcroft $level--; 13428905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 13438905a67cSAndy Whitcroft 13448905a67cSAndy Whitcroft if ($level == 0) { 1345b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1346b998e001SPatrick Pannuto $off++; 1347b998e001SPatrick Pannuto } 13488905a67cSAndy Whitcroft last; 13498905a67cSAndy Whitcroft } 13508905a67cSAndy Whitcroft } 1351f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1352f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1353f74bd194SAndy Whitcroft $level--; 1354f74bd194SAndy Whitcroft $type = ''; 1355f74bd194SAndy Whitcroft $off++; 1356f74bd194SAndy Whitcroft last; 1357f74bd194SAndy Whitcroft } 13588905a67cSAndy Whitcroft $off++; 13598905a67cSAndy Whitcroft } 1360a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 136113214adfSAndy Whitcroft if ($off == $len) { 1362a3bb97a7SAndy Whitcroft $loff = $len + 1; 136313214adfSAndy Whitcroft $line++; 136413214adfSAndy Whitcroft $remain--; 136513214adfSAndy Whitcroft } 13668905a67cSAndy Whitcroft 13678905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 13688905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 13698905a67cSAndy Whitcroft 13708905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 13718905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 13728905a67cSAndy Whitcroft 1373773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 137413214adfSAndy Whitcroft 137513214adfSAndy Whitcroft return ($statement, $condition, 137613214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 137713214adfSAndy Whitcroft} 137813214adfSAndy Whitcroft 1379cf655043SAndy Whitcroftsub statement_lines { 1380cf655043SAndy Whitcroft my ($stmt) = @_; 1381cf655043SAndy Whitcroft 1382cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1383cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1384cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1385cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1386cf655043SAndy Whitcroft 1387cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1388cf655043SAndy Whitcroft 1389cf655043SAndy Whitcroft return $#stmt_lines + 2; 1390cf655043SAndy Whitcroft} 1391cf655043SAndy Whitcroft 1392cf655043SAndy Whitcroftsub statement_rawlines { 1393cf655043SAndy Whitcroft my ($stmt) = @_; 1394cf655043SAndy Whitcroft 1395cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1396cf655043SAndy Whitcroft 1397cf655043SAndy Whitcroft return $#stmt_lines + 2; 1398cf655043SAndy Whitcroft} 1399cf655043SAndy Whitcroft 1400cf655043SAndy Whitcroftsub statement_block_size { 1401cf655043SAndy Whitcroft my ($stmt) = @_; 1402cf655043SAndy Whitcroft 1403cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1404cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1405cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1406cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1407cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1408cf655043SAndy Whitcroft 1409cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1410cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1411cf655043SAndy Whitcroft 1412cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1413cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1414cf655043SAndy Whitcroft 1415cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1416cf655043SAndy Whitcroft return $stmt_lines; 1417cf655043SAndy Whitcroft } else { 1418cf655043SAndy Whitcroft return $stmt_statements; 1419cf655043SAndy Whitcroft } 1420cf655043SAndy Whitcroft} 1421cf655043SAndy Whitcroft 142213214adfSAndy Whitcroftsub ctx_statement_full { 142313214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 142413214adfSAndy Whitcroft my ($statement, $condition, $level); 142513214adfSAndy Whitcroft 142613214adfSAndy Whitcroft my (@chunks); 142713214adfSAndy Whitcroft 1428cf655043SAndy Whitcroft # Grab the first conditional/block pair. 142913214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 143013214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1431773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 143213214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1433cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1434cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1435cf655043SAndy Whitcroft } 1436cf655043SAndy Whitcroft 1437cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1438cf655043SAndy Whitcroft # could continue the statement. 1439cf655043SAndy Whitcroft for (;;) { 144013214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 144113214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1442cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1443773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1444cf655043SAndy Whitcroft #print "C: push\n"; 1445cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 144613214adfSAndy Whitcroft } 144713214adfSAndy Whitcroft 144813214adfSAndy Whitcroft return ($level, $linenr, @chunks); 14498905a67cSAndy Whitcroft} 14508905a67cSAndy Whitcroft 14514a0df2efSAndy Whitcroftsub ctx_block_get { 1452f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 14534a0df2efSAndy Whitcroft my $line; 14544a0df2efSAndy Whitcroft my $start = $linenr - 1; 14554a0df2efSAndy Whitcroft my $blk = ''; 14564a0df2efSAndy Whitcroft my @o; 14574a0df2efSAndy Whitcroft my @c; 14584a0df2efSAndy Whitcroft my @res = (); 14594a0df2efSAndy Whitcroft 1460f0a594c1SAndy Whitcroft my $level = 0; 14614635f4fbSAndy Whitcroft my @stack = ($level); 146200df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 146300df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 146400df344fSAndy Whitcroft $remain--; 146500df344fSAndy Whitcroft 146600df344fSAndy Whitcroft $blk .= $rawlines[$line]; 14674635f4fbSAndy Whitcroft 14684635f4fbSAndy Whitcroft # Handle nested #if/#else. 146901464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 14704635f4fbSAndy Whitcroft push(@stack, $level); 147101464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 14724635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 147301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 14744635f4fbSAndy Whitcroft $level = pop(@stack); 14754635f4fbSAndy Whitcroft } 14764635f4fbSAndy Whitcroft 147701464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1478f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1479f0a594c1SAndy Whitcroft if ($off > 0) { 1480f0a594c1SAndy Whitcroft $off--; 1481f0a594c1SAndy Whitcroft next; 1482f0a594c1SAndy Whitcroft } 14834a0df2efSAndy Whitcroft 1484f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1485f0a594c1SAndy Whitcroft $level--; 1486f0a594c1SAndy Whitcroft last if ($level == 0); 1487f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1488f0a594c1SAndy Whitcroft $level++; 1489f0a594c1SAndy Whitcroft } 1490f0a594c1SAndy Whitcroft } 14914a0df2efSAndy Whitcroft 1492f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 149300df344fSAndy Whitcroft push(@res, $rawlines[$line]); 14944a0df2efSAndy Whitcroft } 14954a0df2efSAndy Whitcroft 1496f0a594c1SAndy Whitcroft last if ($level == 0); 14974a0df2efSAndy Whitcroft } 14984a0df2efSAndy Whitcroft 1499f0a594c1SAndy Whitcroft return ($level, @res); 15004a0df2efSAndy Whitcroft} 15014a0df2efSAndy Whitcroftsub ctx_block_outer { 15024a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15034a0df2efSAndy Whitcroft 1504f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1505f0a594c1SAndy Whitcroft return @r; 15064a0df2efSAndy Whitcroft} 15074a0df2efSAndy Whitcroftsub ctx_block { 15084a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15094a0df2efSAndy Whitcroft 1510f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1511f0a594c1SAndy Whitcroft return @r; 1512653d4876SAndy Whitcroft} 1513653d4876SAndy Whitcroftsub ctx_statement { 1514f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1515f0a594c1SAndy Whitcroft 1516f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1517f0a594c1SAndy Whitcroft return @r; 1518f0a594c1SAndy Whitcroft} 1519f0a594c1SAndy Whitcroftsub ctx_block_level { 1520653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1521653d4876SAndy Whitcroft 1522f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 15234a0df2efSAndy Whitcroft} 15249c0ca6f9SAndy Whitcroftsub ctx_statement_level { 15259c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 15269c0ca6f9SAndy Whitcroft 15279c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 15289c0ca6f9SAndy Whitcroft} 15294a0df2efSAndy Whitcroft 15304a0df2efSAndy Whitcroftsub ctx_locate_comment { 15314a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15324a0df2efSAndy Whitcroft 15334a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1534beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 15354a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 15364a0df2efSAndy Whitcroft 15374a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 15384a0df2efSAndy Whitcroft # comment. 15394a0df2efSAndy Whitcroft my $in_comment = 0; 15404a0df2efSAndy Whitcroft $current_comment = ''; 15414a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 154200df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 154300df344fSAndy Whitcroft #warn " $line\n"; 15444a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 15454a0df2efSAndy Whitcroft $in_comment = 1; 15464a0df2efSAndy Whitcroft } 15474a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 15484a0df2efSAndy Whitcroft $in_comment = 1; 15494a0df2efSAndy Whitcroft } 15504a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 15514a0df2efSAndy Whitcroft $current_comment = ''; 15524a0df2efSAndy Whitcroft } 15534a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 15544a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 15554a0df2efSAndy Whitcroft $in_comment = 0; 15564a0df2efSAndy Whitcroft } 15574a0df2efSAndy Whitcroft } 15584a0df2efSAndy Whitcroft 15594a0df2efSAndy Whitcroft chomp($current_comment); 15604a0df2efSAndy Whitcroft return($current_comment); 15614a0df2efSAndy Whitcroft} 15624a0df2efSAndy Whitcroftsub ctx_has_comment { 15634a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15644a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 15654a0df2efSAndy Whitcroft 156600df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 15674a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 15684a0df2efSAndy Whitcroft 15694a0df2efSAndy Whitcroft return ($cmt ne ''); 15704a0df2efSAndy Whitcroft} 15714a0df2efSAndy Whitcroft 15724d001e4dSAndy Whitcroftsub raw_line { 15734d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 15744d001e4dSAndy Whitcroft 15754d001e4dSAndy Whitcroft my $offset = $linenr - 1; 15764d001e4dSAndy Whitcroft $cnt++; 15774d001e4dSAndy Whitcroft 15784d001e4dSAndy Whitcroft my $line; 15794d001e4dSAndy Whitcroft while ($cnt) { 15804d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 15814d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 15824d001e4dSAndy Whitcroft $cnt--; 15834d001e4dSAndy Whitcroft } 15844d001e4dSAndy Whitcroft 15854d001e4dSAndy Whitcroft return $line; 15864d001e4dSAndy Whitcroft} 15874d001e4dSAndy Whitcroft 15880a920b5bSAndy Whitcroftsub cat_vet { 15890a920b5bSAndy Whitcroft my ($vet) = @_; 15909c0ca6f9SAndy Whitcroft my ($res, $coded); 15910a920b5bSAndy Whitcroft 15929c0ca6f9SAndy Whitcroft $res = ''; 15936c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 15946c72ffaaSAndy Whitcroft $res .= $1; 15956c72ffaaSAndy Whitcroft if ($2 ne '') { 15969c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 15976c72ffaaSAndy Whitcroft $res .= $coded; 15986c72ffaaSAndy Whitcroft } 15999c0ca6f9SAndy Whitcroft } 16009c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 16010a920b5bSAndy Whitcroft 16029c0ca6f9SAndy Whitcroft return $res; 16030a920b5bSAndy Whitcroft} 16040a920b5bSAndy Whitcroft 1605c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1606cf655043SAndy Whitcroftmy $av_pending; 1607c2fdda0dSAndy Whitcroftmy @av_paren_type; 16081f65f947SAndy Whitcroftmy $av_pend_colon; 1609c2fdda0dSAndy Whitcroft 1610c2fdda0dSAndy Whitcroftsub annotate_reset { 1611c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1612cf655043SAndy Whitcroft $av_pending = '_'; 1613cf655043SAndy Whitcroft @av_paren_type = ('E'); 16141f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1615c2fdda0dSAndy Whitcroft} 1616c2fdda0dSAndy Whitcroft 16176c72ffaaSAndy Whitcroftsub annotate_values { 16186c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 16196c72ffaaSAndy Whitcroft 16206c72ffaaSAndy Whitcroft my $res; 16211f65f947SAndy Whitcroft my $var = '_' x length($stream); 16226c72ffaaSAndy Whitcroft my $cur = $stream; 16236c72ffaaSAndy Whitcroft 1624c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 16256c72ffaaSAndy Whitcroft 16266c72ffaaSAndy Whitcroft while (length($cur)) { 1627773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1628cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1629171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 16306c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1631c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1632c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1633cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1634c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 16356c72ffaaSAndy Whitcroft } 16366c72ffaaSAndy Whitcroft 1637c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 16389446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 16399446ef56SAndy Whitcroft push(@av_paren_type, $type); 1640addcdceaSAndy Whitcroft $type = 'c'; 16419446ef56SAndy Whitcroft 1642e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1643c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 16446c72ffaaSAndy Whitcroft $type = 'T'; 16456c72ffaaSAndy Whitcroft 1646389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1647389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1648389a2fe5SAndy Whitcroft $type = 'T'; 1649389a2fe5SAndy Whitcroft 1650c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1651171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1652c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1653171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1654171ae1a4SAndy Whitcroft if ($2 ne '') { 1655cf655043SAndy Whitcroft $av_pending = 'N'; 1656171ae1a4SAndy Whitcroft } 1657171ae1a4SAndy Whitcroft $type = 'E'; 1658171ae1a4SAndy Whitcroft 1659c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1660171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1661171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1662171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 16636c72ffaaSAndy Whitcroft 1664c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1665cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1666c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1667cf655043SAndy Whitcroft 1668cf655043SAndy Whitcroft push(@av_paren_type, $type); 1669cf655043SAndy Whitcroft push(@av_paren_type, $type); 1670171ae1a4SAndy Whitcroft $type = 'E'; 1671cf655043SAndy Whitcroft 1672c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1673cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1674cf655043SAndy Whitcroft $av_preprocessor = 1; 1675cf655043SAndy Whitcroft 1676cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1677cf655043SAndy Whitcroft 1678171ae1a4SAndy Whitcroft $type = 'E'; 1679cf655043SAndy Whitcroft 1680c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1681cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1682cf655043SAndy Whitcroft 1683cf655043SAndy Whitcroft $av_preprocessor = 1; 1684cf655043SAndy Whitcroft 1685cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1686cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1687cf655043SAndy Whitcroft pop(@av_paren_type); 1688cf655043SAndy Whitcroft push(@av_paren_type, $type); 1689171ae1a4SAndy Whitcroft $type = 'E'; 16906c72ffaaSAndy Whitcroft 16916c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1692c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 16936c72ffaaSAndy Whitcroft 1694171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1695171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1696171ae1a4SAndy Whitcroft $av_pending = $type; 1697171ae1a4SAndy Whitcroft $type = 'N'; 1698171ae1a4SAndy Whitcroft 16996c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1700c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 17016c72ffaaSAndy Whitcroft if (defined $2) { 1702cf655043SAndy Whitcroft $av_pending = 'V'; 17036c72ffaaSAndy Whitcroft } 17046c72ffaaSAndy Whitcroft $type = 'N'; 17056c72ffaaSAndy Whitcroft 170614b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1707c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 170814b111c1SAndy Whitcroft $av_pending = 'E'; 17096c72ffaaSAndy Whitcroft $type = 'N'; 17106c72ffaaSAndy Whitcroft 17111f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 17121f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 17131f65f947SAndy Whitcroft $av_pend_colon = 'C'; 17141f65f947SAndy Whitcroft $type = 'N'; 17151f65f947SAndy Whitcroft 171614b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1717c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 17186c72ffaaSAndy Whitcroft $type = 'N'; 17196c72ffaaSAndy Whitcroft 17206c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1721c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1722cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1723cf655043SAndy Whitcroft $av_pending = '_'; 17246c72ffaaSAndy Whitcroft $type = 'N'; 17256c72ffaaSAndy Whitcroft 17266c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1727cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1728cf655043SAndy Whitcroft if ($new_type ne '_') { 1729cf655043SAndy Whitcroft $type = $new_type; 1730c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1731c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 17326c72ffaaSAndy Whitcroft } else { 1733c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 17346c72ffaaSAndy Whitcroft } 17356c72ffaaSAndy Whitcroft 1736c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1737c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1738c8cb2ca3SAndy Whitcroft $type = 'V'; 1739cf655043SAndy Whitcroft $av_pending = 'V'; 17406c72ffaaSAndy Whitcroft 17418e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 17428e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 17431f65f947SAndy Whitcroft $av_pend_colon = 'B'; 17448e761b04SAndy Whitcroft } elsif ($type eq 'E') { 17458e761b04SAndy Whitcroft $av_pend_colon = 'L'; 17461f65f947SAndy Whitcroft } 17471f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 17481f65f947SAndy Whitcroft $type = 'V'; 17491f65f947SAndy Whitcroft 17506c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1751c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 17526c72ffaaSAndy Whitcroft $type = 'V'; 17536c72ffaaSAndy Whitcroft 17546c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1755c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 17566c72ffaaSAndy Whitcroft $type = 'N'; 17576c72ffaaSAndy Whitcroft 1758cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1759c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 176013214adfSAndy Whitcroft $type = 'E'; 17611f65f947SAndy Whitcroft $av_pend_colon = 'O'; 176213214adfSAndy Whitcroft 17638e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 17648e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 17658e761b04SAndy Whitcroft $type = 'C'; 17668e761b04SAndy Whitcroft 17671f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 17681f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 17691f65f947SAndy Whitcroft $type = 'N'; 17701f65f947SAndy Whitcroft 17711f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 17721f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 17731f65f947SAndy Whitcroft 17741f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 17751f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 17761f65f947SAndy Whitcroft $type = 'E'; 17771f65f947SAndy Whitcroft } else { 17781f65f947SAndy Whitcroft $type = 'N'; 17791f65f947SAndy Whitcroft } 17801f65f947SAndy Whitcroft $av_pend_colon = 'O'; 17811f65f947SAndy Whitcroft 17828e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 178313214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 17846c72ffaaSAndy Whitcroft $type = 'N'; 17856c72ffaaSAndy Whitcroft 17860d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 178774048ed8SAndy Whitcroft my $variant; 178874048ed8SAndy Whitcroft 178974048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 179074048ed8SAndy Whitcroft if ($type eq 'V') { 179174048ed8SAndy Whitcroft $variant = 'B'; 179274048ed8SAndy Whitcroft } else { 179374048ed8SAndy Whitcroft $variant = 'U'; 179474048ed8SAndy Whitcroft } 179574048ed8SAndy Whitcroft 179674048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 179774048ed8SAndy Whitcroft $type = 'N'; 179874048ed8SAndy Whitcroft 17996c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1800c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 18016c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 18026c72ffaaSAndy Whitcroft $type = 'N'; 18036c72ffaaSAndy Whitcroft } 18046c72ffaaSAndy Whitcroft 18056c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1806c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 18076c72ffaaSAndy Whitcroft } 18086c72ffaaSAndy Whitcroft if (defined $1) { 18096c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 18106c72ffaaSAndy Whitcroft $res .= $type x length($1); 18116c72ffaaSAndy Whitcroft } 18126c72ffaaSAndy Whitcroft } 18136c72ffaaSAndy Whitcroft 18141f65f947SAndy Whitcroft return ($res, $var); 18156c72ffaaSAndy Whitcroft} 18166c72ffaaSAndy Whitcroft 18178905a67cSAndy Whitcroftsub possible { 181813214adfSAndy Whitcroft my ($possible, $line) = @_; 18199a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 18200776e594SAndy Whitcroft ^(?: 18210776e594SAndy Whitcroft $Modifier| 18220776e594SAndy Whitcroft $Storage| 18230776e594SAndy Whitcroft $Type| 18249a974fdbSAndy Whitcroft DEFINE_\S+ 18259a974fdbSAndy Whitcroft )$| 18269a974fdbSAndy Whitcroft ^(?: 18270776e594SAndy Whitcroft goto| 18280776e594SAndy Whitcroft return| 18290776e594SAndy Whitcroft case| 18300776e594SAndy Whitcroft else| 18310776e594SAndy Whitcroft asm|__asm__| 183289a88353SAndy Whitcroft do| 183389a88353SAndy Whitcroft \#| 183489a88353SAndy Whitcroft \#\#| 18359a974fdbSAndy Whitcroft )(?:\s|$)| 18360776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 18379a974fdbSAndy Whitcroft )}x; 18389a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 18399a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1840c45dcabdSAndy Whitcroft # Check for modifiers. 1841c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1842c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1843c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1844c45dcabdSAndy Whitcroft 1845c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1846c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1847d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 18489a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1849d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1850485ff23eSAlex Dowad push(@modifierListFile, $modifier); 1851d2506586SAndy Whitcroft } 18529a974fdbSAndy Whitcroft } 1853c45dcabdSAndy Whitcroft 1854c45dcabdSAndy Whitcroft } else { 185513214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1856485ff23eSAlex Dowad push(@typeListFile, $possible); 1857c45dcabdSAndy Whitcroft } 18588905a67cSAndy Whitcroft build_types(); 18590776e594SAndy Whitcroft } else { 18600776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 18618905a67cSAndy Whitcroft } 18628905a67cSAndy Whitcroft} 18638905a67cSAndy Whitcroft 18646c72ffaaSAndy Whitcroftmy $prefix = ''; 18656c72ffaaSAndy Whitcroft 1866000d1cc1SJoe Perchessub show_type { 1867cbec18afSJoe Perches my ($type) = @_; 186891bfe484SJoe Perches 1869522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 1870522b837cSAlexey Dobriyan 1871cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 1872cbec18afSJoe Perches 1873cbec18afSJoe Perches return !defined $ignore_type{$type}; 1874000d1cc1SJoe Perches} 1875000d1cc1SJoe Perches 1876f0a594c1SAndy Whitcroftsub report { 1877cbec18afSJoe Perches my ($level, $type, $msg) = @_; 1878cbec18afSJoe Perches 1879cbec18afSJoe Perches if (!show_type($type) || 1880cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 1881773647a0SAndy Whitcroft return 0; 1882773647a0SAndy Whitcroft } 188357230297SJoe Perches my $output = ''; 188457230297SJoe Perches if (-t STDOUT && $color) { 188557230297SJoe Perches if ($level eq 'ERROR') { 188657230297SJoe Perches $output .= RED; 188757230297SJoe Perches } elsif ($level eq 'WARNING') { 188857230297SJoe Perches $output .= YELLOW; 1889000d1cc1SJoe Perches } else { 189057230297SJoe Perches $output .= GREEN; 1891000d1cc1SJoe Perches } 189257230297SJoe Perches } 189357230297SJoe Perches $output .= $prefix . $level . ':'; 189457230297SJoe Perches if ($show_types) { 189557230297SJoe Perches $output .= BLUE if (-t STDOUT && $color); 189657230297SJoe Perches $output .= "$type:"; 189757230297SJoe Perches } 189857230297SJoe Perches $output .= RESET if (-t STDOUT && $color); 189957230297SJoe Perches $output .= ' ' . $msg . "\n"; 190034d8815fSJoe Perches 190134d8815fSJoe Perches if ($showfile) { 190234d8815fSJoe Perches my @lines = split("\n", $output, -1); 190334d8815fSJoe Perches splice(@lines, 1, 1); 190434d8815fSJoe Perches $output = join("\n", @lines); 190534d8815fSJoe Perches } 190657230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 19078905a67cSAndy Whitcroft 190857230297SJoe Perches push(our @report, $output); 1909773647a0SAndy Whitcroft 1910773647a0SAndy Whitcroft return 1; 1911f0a594c1SAndy Whitcroft} 1912cbec18afSJoe Perches 1913f0a594c1SAndy Whitcroftsub report_dump { 191413214adfSAndy Whitcroft our @report; 1915f0a594c1SAndy Whitcroft} 1916000d1cc1SJoe Perches 1917d752fcc8SJoe Perchessub fixup_current_range { 1918d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 1919d752fcc8SJoe Perches 1920d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 1921d752fcc8SJoe Perches my $o = $1; 1922d752fcc8SJoe Perches my $l = $2; 1923d752fcc8SJoe Perches my $no = $o + $offset; 1924d752fcc8SJoe Perches my $nl = $l + $length; 1925d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 1926d752fcc8SJoe Perches } 1927d752fcc8SJoe Perches} 1928d752fcc8SJoe Perches 1929d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 1930d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 1931d752fcc8SJoe Perches 1932d752fcc8SJoe Perches my $range_last_linenr = 0; 1933d752fcc8SJoe Perches my $delta_offset = 0; 1934d752fcc8SJoe Perches 1935d752fcc8SJoe Perches my $old_linenr = 0; 1936d752fcc8SJoe Perches my $new_linenr = 0; 1937d752fcc8SJoe Perches 1938d752fcc8SJoe Perches my $next_insert = 0; 1939d752fcc8SJoe Perches my $next_delete = 0; 1940d752fcc8SJoe Perches 1941d752fcc8SJoe Perches my @lines = (); 1942d752fcc8SJoe Perches 1943d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 1944d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 1945d752fcc8SJoe Perches 1946d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 1947d752fcc8SJoe Perches my $save_line = 1; 1948d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 1949323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 1950d752fcc8SJoe Perches $delta_offset = 0; 1951d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 1952d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 1953d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 1954d752fcc8SJoe Perches } 1955d752fcc8SJoe Perches 1956d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 1957d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 1958d752fcc8SJoe Perches $save_line = 0; 1959d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 1960d752fcc8SJoe Perches } 1961d752fcc8SJoe Perches 1962d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 1963d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 1964d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 1965d752fcc8SJoe Perches $new_linenr++; 1966d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 1967d752fcc8SJoe Perches } 1968d752fcc8SJoe Perches 1969d752fcc8SJoe Perches if ($save_line) { 1970d752fcc8SJoe Perches push(@lines, $line); 1971d752fcc8SJoe Perches $new_linenr++; 1972d752fcc8SJoe Perches } 1973d752fcc8SJoe Perches 1974d752fcc8SJoe Perches $old_linenr++; 1975d752fcc8SJoe Perches } 1976d752fcc8SJoe Perches 1977d752fcc8SJoe Perches return @lines; 1978d752fcc8SJoe Perches} 1979d752fcc8SJoe Perches 1980f2d7e4d4SJoe Perchessub fix_insert_line { 1981f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1982f2d7e4d4SJoe Perches 1983f2d7e4d4SJoe Perches my $inserted = { 1984f2d7e4d4SJoe Perches LINENR => $linenr, 1985f2d7e4d4SJoe Perches LINE => $line, 1986f2d7e4d4SJoe Perches }; 1987f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 1988f2d7e4d4SJoe Perches} 1989f2d7e4d4SJoe Perches 1990f2d7e4d4SJoe Perchessub fix_delete_line { 1991f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1992f2d7e4d4SJoe Perches 1993f2d7e4d4SJoe Perches my $deleted = { 1994f2d7e4d4SJoe Perches LINENR => $linenr, 1995f2d7e4d4SJoe Perches LINE => $line, 1996f2d7e4d4SJoe Perches }; 1997f2d7e4d4SJoe Perches 1998f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 1999f2d7e4d4SJoe Perches} 2000f2d7e4d4SJoe Perches 2001de7d4f0eSAndy Whitcroftsub ERROR { 2002cbec18afSJoe Perches my ($type, $msg) = @_; 2003cbec18afSJoe Perches 2004cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2005de7d4f0eSAndy Whitcroft our $clean = 0; 20066c72ffaaSAndy Whitcroft our $cnt_error++; 20073705ce5bSJoe Perches return 1; 2008de7d4f0eSAndy Whitcroft } 20093705ce5bSJoe Perches return 0; 2010773647a0SAndy Whitcroft} 2011de7d4f0eSAndy Whitcroftsub WARN { 2012cbec18afSJoe Perches my ($type, $msg) = @_; 2013cbec18afSJoe Perches 2014cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2015de7d4f0eSAndy Whitcroft our $clean = 0; 20166c72ffaaSAndy Whitcroft our $cnt_warn++; 20173705ce5bSJoe Perches return 1; 2018de7d4f0eSAndy Whitcroft } 20193705ce5bSJoe Perches return 0; 2020773647a0SAndy Whitcroft} 2021de7d4f0eSAndy Whitcroftsub CHK { 2022cbec18afSJoe Perches my ($type, $msg) = @_; 2023cbec18afSJoe Perches 2024cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2025de7d4f0eSAndy Whitcroft our $clean = 0; 20266c72ffaaSAndy Whitcroft our $cnt_chk++; 20273705ce5bSJoe Perches return 1; 20286c72ffaaSAndy Whitcroft } 20293705ce5bSJoe Perches return 0; 2030de7d4f0eSAndy Whitcroft} 2031de7d4f0eSAndy Whitcroft 20326ecd9674SAndy Whitcroftsub check_absolute_file { 20336ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 20346ecd9674SAndy Whitcroft my $file = $absolute; 20356ecd9674SAndy Whitcroft 20366ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 20376ecd9674SAndy Whitcroft 20386ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 20396ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 20406ecd9674SAndy Whitcroft if (-f "$root/$file") { 20416ecd9674SAndy Whitcroft ##print "file<$file>\n"; 20426ecd9674SAndy Whitcroft last; 20436ecd9674SAndy Whitcroft } 20446ecd9674SAndy Whitcroft } 20456ecd9674SAndy Whitcroft if (! -f _) { 20466ecd9674SAndy Whitcroft return 0; 20476ecd9674SAndy Whitcroft } 20486ecd9674SAndy Whitcroft 20496ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 20506ecd9674SAndy Whitcroft my $prefix = $absolute; 20516ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 20526ecd9674SAndy Whitcroft 20536ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 20546ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2055000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2056000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 20576ecd9674SAndy Whitcroft } 20586ecd9674SAndy Whitcroft} 20596ecd9674SAndy Whitcroft 20603705ce5bSJoe Perchessub trim { 20613705ce5bSJoe Perches my ($string) = @_; 20623705ce5bSJoe Perches 2063b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2064b34c648bSJoe Perches 2065b34c648bSJoe Perches return $string; 2066b34c648bSJoe Perches} 2067b34c648bSJoe Perches 2068b34c648bSJoe Perchessub ltrim { 2069b34c648bSJoe Perches my ($string) = @_; 2070b34c648bSJoe Perches 2071b34c648bSJoe Perches $string =~ s/^\s+//; 2072b34c648bSJoe Perches 2073b34c648bSJoe Perches return $string; 2074b34c648bSJoe Perches} 2075b34c648bSJoe Perches 2076b34c648bSJoe Perchessub rtrim { 2077b34c648bSJoe Perches my ($string) = @_; 2078b34c648bSJoe Perches 2079b34c648bSJoe Perches $string =~ s/\s+$//; 20803705ce5bSJoe Perches 20813705ce5bSJoe Perches return $string; 20823705ce5bSJoe Perches} 20833705ce5bSJoe Perches 208452ea8506SJoe Perchessub string_find_replace { 208552ea8506SJoe Perches my ($string, $find, $replace) = @_; 208652ea8506SJoe Perches 208752ea8506SJoe Perches $string =~ s/$find/$replace/g; 208852ea8506SJoe Perches 208952ea8506SJoe Perches return $string; 209052ea8506SJoe Perches} 209152ea8506SJoe Perches 20923705ce5bSJoe Perchessub tabify { 20933705ce5bSJoe Perches my ($leading) = @_; 20943705ce5bSJoe Perches 20953705ce5bSJoe Perches my $source_indent = 8; 20963705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 20973705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 20983705ce5bSJoe Perches 20993705ce5bSJoe Perches #convert leading spaces to tabs 21003705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 21013705ce5bSJoe Perches #Remove spaces before a tab 21023705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 21033705ce5bSJoe Perches 21043705ce5bSJoe Perches return "$leading"; 21053705ce5bSJoe Perches} 21063705ce5bSJoe Perches 2107d1fe9c09SJoe Perchessub pos_last_openparen { 2108d1fe9c09SJoe Perches my ($line) = @_; 2109d1fe9c09SJoe Perches 2110d1fe9c09SJoe Perches my $pos = 0; 2111d1fe9c09SJoe Perches 2112d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2113d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2114d1fe9c09SJoe Perches 2115d1fe9c09SJoe Perches my $last_openparen = 0; 2116d1fe9c09SJoe Perches 2117d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2118d1fe9c09SJoe Perches return -1; 2119d1fe9c09SJoe Perches } 2120d1fe9c09SJoe Perches 2121d1fe9c09SJoe Perches my $len = length($line); 2122d1fe9c09SJoe Perches 2123d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2124d1fe9c09SJoe Perches my $string = substr($line, $pos); 2125d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2126d1fe9c09SJoe Perches $pos += length($1) - 1; 2127d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2128d1fe9c09SJoe Perches $last_openparen = $pos; 2129d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2130d1fe9c09SJoe Perches last; 2131d1fe9c09SJoe Perches } 2132d1fe9c09SJoe Perches } 2133d1fe9c09SJoe Perches 213491cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2135d1fe9c09SJoe Perches} 2136d1fe9c09SJoe Perches 21370a920b5bSAndy Whitcroftsub process { 21380a920b5bSAndy Whitcroft my $filename = shift; 21390a920b5bSAndy Whitcroft 21400a920b5bSAndy Whitcroft my $linenr=0; 21410a920b5bSAndy Whitcroft my $prevline=""; 2142c2fdda0dSAndy Whitcroft my $prevrawline=""; 21430a920b5bSAndy Whitcroft my $stashline=""; 2144c2fdda0dSAndy Whitcroft my $stashrawline=""; 21450a920b5bSAndy Whitcroft 21464a0df2efSAndy Whitcroft my $length; 21470a920b5bSAndy Whitcroft my $indent; 21480a920b5bSAndy Whitcroft my $previndent=0; 21490a920b5bSAndy Whitcroft my $stashindent=0; 21500a920b5bSAndy Whitcroft 2151de7d4f0eSAndy Whitcroft our $clean = 1; 21520a920b5bSAndy Whitcroft my $signoff = 0; 21530a920b5bSAndy Whitcroft my $is_patch = 0; 215429ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 215515662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 2156ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2157bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 21582a076f40SJoe Perches my $commit_log_long_line = 0; 2159e518e9a5SJoe Perches my $commit_log_has_diff = 0; 216013f1937eSJoe Perches my $reported_maintainer_file = 0; 2161fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2162fa64205dSPasi Savanainen 2163365dd4eaSJoe Perches my $last_blank_line = 0; 21645e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2165365dd4eaSJoe Perches 216613214adfSAndy Whitcroft our @report = (); 21676c72ffaaSAndy Whitcroft our $cnt_lines = 0; 21686c72ffaaSAndy Whitcroft our $cnt_error = 0; 21696c72ffaaSAndy Whitcroft our $cnt_warn = 0; 21706c72ffaaSAndy Whitcroft our $cnt_chk = 0; 21716c72ffaaSAndy Whitcroft 21720a920b5bSAndy Whitcroft # Trace the real file/line as we go. 21730a920b5bSAndy Whitcroft my $realfile = ''; 21740a920b5bSAndy Whitcroft my $realline = 0; 21750a920b5bSAndy Whitcroft my $realcnt = 0; 21760a920b5bSAndy Whitcroft my $here = ''; 217777cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 21780a920b5bSAndy Whitcroft my $in_comment = 0; 2179c2fdda0dSAndy Whitcroft my $comment_edge = 0; 21800a920b5bSAndy Whitcroft my $first_line = 0; 21811e855726SWolfram Sang my $p1_prefix = ''; 21820a920b5bSAndy Whitcroft 218313214adfSAndy Whitcroft my $prev_values = 'E'; 218413214adfSAndy Whitcroft 218513214adfSAndy Whitcroft # suppression flags 2186773647a0SAndy Whitcroft my %suppress_ifbraces; 2187170d3a22SAndy Whitcroft my %suppress_whiletrailers; 21882b474a1aSAndy Whitcroft my %suppress_export; 21893e469cdcSAndy Whitcroft my $suppress_statement = 0; 2190653d4876SAndy Whitcroft 21917e51f197SJoe Perches my %signatures = (); 2192323c1260SJoe Perches 2193c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2194de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2195c2fdda0dSAndy Whitcroft # 2196de7d4f0eSAndy Whitcroft my @setup_docs = (); 2197de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2198773647a0SAndy Whitcroft 2199d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2200d8b07710SJoe Perches 2201773647a0SAndy Whitcroft sanitise_line_reset(); 2202c2fdda0dSAndy Whitcroft my $line; 2203c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2204773647a0SAndy Whitcroft $linenr++; 2205773647a0SAndy Whitcroft $line = $rawline; 2206c2fdda0dSAndy Whitcroft 22073705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 22083705ce5bSJoe Perches 2209773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2210de7d4f0eSAndy Whitcroft $setup_docs = 0; 22118c27ceffSMauro Carvalho Chehab if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2212de7d4f0eSAndy Whitcroft $setup_docs = 1; 2213de7d4f0eSAndy Whitcroft } 2214773647a0SAndy Whitcroft #next; 2215de7d4f0eSAndy Whitcroft } 2216*74fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2217773647a0SAndy Whitcroft $realline=$1-1; 2218773647a0SAndy Whitcroft if (defined $2) { 2219773647a0SAndy Whitcroft $realcnt=$3+1; 2220773647a0SAndy Whitcroft } else { 2221773647a0SAndy Whitcroft $realcnt=1+1; 2222773647a0SAndy Whitcroft } 2223c45dcabdSAndy Whitcroft $in_comment = 0; 2224773647a0SAndy Whitcroft 2225773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2226773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2227773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2228773647a0SAndy Whitcroft # at context start. 2229773647a0SAndy Whitcroft my $edge; 223001fa9147SAndy Whitcroft my $cnt = $realcnt; 223101fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 223201fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 223301fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 223401fa9147SAndy Whitcroft $cnt--; 223501fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2236721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2237fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2238fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2239fae17daeSAndy Whitcroft ($edge) = $1; 2240fae17daeSAndy Whitcroft last; 2241fae17daeSAndy Whitcroft } 2242773647a0SAndy Whitcroft } 2243773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2244773647a0SAndy Whitcroft $in_comment = 1; 2245773647a0SAndy Whitcroft } 2246773647a0SAndy Whitcroft 2247773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2248773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2249773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2250773647a0SAndy Whitcroft if (!defined $edge && 225183242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2252773647a0SAndy Whitcroft { 2253773647a0SAndy Whitcroft $in_comment = 1; 2254773647a0SAndy Whitcroft } 2255773647a0SAndy Whitcroft 2256773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2257773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2258773647a0SAndy Whitcroft 2259171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2260773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2261171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2262773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2263773647a0SAndy Whitcroft } 2264773647a0SAndy Whitcroft push(@lines, $line); 2265773647a0SAndy Whitcroft 2266773647a0SAndy Whitcroft if ($realcnt > 1) { 2267773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2268773647a0SAndy Whitcroft } else { 2269773647a0SAndy Whitcroft $realcnt = 0; 2270773647a0SAndy Whitcroft } 2271773647a0SAndy Whitcroft 2272773647a0SAndy Whitcroft #print "==>$rawline\n"; 2273773647a0SAndy Whitcroft #print "-->$line\n"; 2274de7d4f0eSAndy Whitcroft 2275de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2276de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2277de7d4f0eSAndy Whitcroft } 2278de7d4f0eSAndy Whitcroft } 2279de7d4f0eSAndy Whitcroft 22806c72ffaaSAndy Whitcroft $prefix = ''; 22816c72ffaaSAndy Whitcroft 2282773647a0SAndy Whitcroft $realcnt = 0; 2283773647a0SAndy Whitcroft $linenr = 0; 2284194f66fcSJoe Perches $fixlinenr = -1; 22850a920b5bSAndy Whitcroft foreach my $line (@lines) { 22860a920b5bSAndy Whitcroft $linenr++; 2287194f66fcSJoe Perches $fixlinenr++; 22881b5539b1SJoe Perches my $sline = $line; #copy of $line 22891b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 22900a920b5bSAndy Whitcroft 2291c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 22926c72ffaaSAndy Whitcroft 22930a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2294e518e9a5SJoe Perches if (!$in_commit_log && 2295*74fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 2296*74fd4f34SJoe Perches my $context = $4; 22970a920b5bSAndy Whitcroft $is_patch = 1; 22984a0df2efSAndy Whitcroft $first_line = $linenr + 1; 22990a920b5bSAndy Whitcroft $realline=$1-1; 23000a920b5bSAndy Whitcroft if (defined $2) { 23010a920b5bSAndy Whitcroft $realcnt=$3+1; 23020a920b5bSAndy Whitcroft } else { 23030a920b5bSAndy Whitcroft $realcnt=1+1; 23040a920b5bSAndy Whitcroft } 2305c2fdda0dSAndy Whitcroft annotate_reset(); 230613214adfSAndy Whitcroft $prev_values = 'E'; 230713214adfSAndy Whitcroft 2308773647a0SAndy Whitcroft %suppress_ifbraces = (); 2309170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 23102b474a1aSAndy Whitcroft %suppress_export = (); 23113e469cdcSAndy Whitcroft $suppress_statement = 0; 2312*74fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 2313*74fd4f34SJoe Perches $context_function = $1; 2314*74fd4f34SJoe Perches } else { 2315*74fd4f34SJoe Perches undef $context_function; 2316*74fd4f34SJoe Perches } 23170a920b5bSAndy Whitcroft next; 23180a920b5bSAndy Whitcroft 23194a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 23204a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 23214a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2322773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 23230a920b5bSAndy Whitcroft $realline++; 2324d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 23250a920b5bSAndy Whitcroft 23264a0df2efSAndy Whitcroft # Measure the line length and indent. 2327c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 23280a920b5bSAndy Whitcroft 23290a920b5bSAndy Whitcroft # Track the previous line. 23300a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 23310a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2332c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2333c2fdda0dSAndy Whitcroft 2334773647a0SAndy Whitcroft #warn "line<$line>\n"; 23356c72ffaaSAndy Whitcroft 2336d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2337d8aaf121SAndy Whitcroft $realcnt--; 23380a920b5bSAndy Whitcroft } 23390a920b5bSAndy Whitcroft 2340cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2341cc77cdcaSAndy Whitcroft 23426c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 23436c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2344773647a0SAndy Whitcroft 23452ac73b4fSJoe Perches my $found_file = 0; 2346773647a0SAndy Whitcroft # extract the filename as it passes 23473bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 23483bf9a009SRabin Vincent $realfile = $1; 23492b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2350270c49a0SJoe Perches $in_commit_log = 0; 23512ac73b4fSJoe Perches $found_file = 1; 23523bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2353773647a0SAndy Whitcroft $realfile = $1; 23542b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2355270c49a0SJoe Perches $in_commit_log = 0; 23561e855726SWolfram Sang 23571e855726SWolfram Sang $p1_prefix = $1; 2358e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2359e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2360000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2361000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 23621e855726SWolfram Sang } 2363773647a0SAndy Whitcroft 2364c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2365000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2366000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2367773647a0SAndy Whitcroft } 23682ac73b4fSJoe Perches $found_file = 1; 23692ac73b4fSJoe Perches } 23702ac73b4fSJoe Perches 237134d8815fSJoe Perches#make up the handle for any error we report on this line 237234d8815fSJoe Perches if ($showfile) { 237334d8815fSJoe Perches $prefix = "$realfile:$realline: " 237434d8815fSJoe Perches } elsif ($emacs) { 23757d3a9f67SJoe Perches if ($file) { 23767d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 23777d3a9f67SJoe Perches } else { 237834d8815fSJoe Perches $prefix = "$filename:$linenr: "; 237934d8815fSJoe Perches } 23807d3a9f67SJoe Perches } 238134d8815fSJoe Perches 23822ac73b4fSJoe Perches if ($found_file) { 238385b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 238485b0ee18SJoe Perches WARN("OBSOLETE", 238585b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 238685b0ee18SJoe Perches } 23877bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 23882ac73b4fSJoe Perches $check = 1; 23892ac73b4fSJoe Perches } else { 23902ac73b4fSJoe Perches $check = $check_orig; 23912ac73b4fSJoe Perches } 2392773647a0SAndy Whitcroft next; 2393773647a0SAndy Whitcroft } 2394773647a0SAndy Whitcroft 2395389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 23960a920b5bSAndy Whitcroft 2397c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2398c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2399c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 24000a920b5bSAndy Whitcroft 24016c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 24026c72ffaaSAndy Whitcroft 2403e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2404e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 2405e518e9a5SJoe Perches (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2406e518e9a5SJoe Perches $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 2407e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2408e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2409e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2410e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2411e518e9a5SJoe Perches $commit_log_has_diff = 1; 2412e518e9a5SJoe Perches } 2413e518e9a5SJoe Perches 24143bf9a009SRabin Vincent# Check for incorrect file permissions 24153bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 24163bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 241704db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 241804db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2419000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2420000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 24213bf9a009SRabin Vincent } 24223bf9a009SRabin Vincent } 24233bf9a009SRabin Vincent 242420112475SJoe Perches# Check the patch for a signoff: 2425d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 24264a0df2efSAndy Whitcroft $signoff++; 242715662b3eSJoe Perches $in_commit_log = 0; 24280a920b5bSAndy Whitcroft } 242920112475SJoe Perches 2430e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2431e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2432e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2433e0d975b1SJoe Perches $reported_maintainer_file = 1; 2434e0d975b1SJoe Perches } 2435e0d975b1SJoe Perches 243620112475SJoe Perches# Check signature styles 2437270c49a0SJoe Perches if (!$in_header_lines && 2438ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 243920112475SJoe Perches my $space_before = $1; 244020112475SJoe Perches my $sign_off = $2; 244120112475SJoe Perches my $space_after = $3; 244220112475SJoe Perches my $email = $4; 244320112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 244420112475SJoe Perches 2445ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2446ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2447ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2448ce0338dfSJoe Perches } 244920112475SJoe Perches if (defined $space_before && $space_before ne "") { 24503705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24513705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 24523705ce5bSJoe Perches $fix) { 2453194f66fcSJoe Perches $fixed[$fixlinenr] = 24543705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24553705ce5bSJoe Perches } 245620112475SJoe Perches } 245720112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 24583705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24593705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 24603705ce5bSJoe Perches $fix) { 2461194f66fcSJoe Perches $fixed[$fixlinenr] = 24623705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24633705ce5bSJoe Perches } 24643705ce5bSJoe Perches 246520112475SJoe Perches } 246620112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 24673705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24683705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 24693705ce5bSJoe Perches $fix) { 2470194f66fcSJoe Perches $fixed[$fixlinenr] = 24713705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24723705ce5bSJoe Perches } 247320112475SJoe Perches } 247420112475SJoe Perches 247520112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 247620112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 247720112475SJoe Perches if ($suggested_email eq "") { 2478000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2479000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 248020112475SJoe Perches } else { 248120112475SJoe Perches my $dequoted = $suggested_email; 248220112475SJoe Perches $dequoted =~ s/^"//; 248320112475SJoe Perches $dequoted =~ s/" </ </; 248420112475SJoe Perches # Don't force email to have quotes 248520112475SJoe Perches # Allow just an angle bracketed address 248620112475SJoe Perches if ("$dequoted$comment" ne $email && 248720112475SJoe Perches "<$email_address>$comment" ne $email && 248820112475SJoe Perches "$suggested_email$comment" ne $email) { 2489000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2490000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 249120112475SJoe Perches } 24920a920b5bSAndy Whitcroft } 24937e51f197SJoe Perches 24947e51f197SJoe Perches# Check for duplicate signatures 24957e51f197SJoe Perches my $sig_nospace = $line; 24967e51f197SJoe Perches $sig_nospace =~ s/\s//g; 24977e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 24987e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 24997e51f197SJoe Perches WARN("BAD_SIGN_OFF", 25007e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 25017e51f197SJoe Perches } else { 25027e51f197SJoe Perches $signatures{$sig_nospace} = 1; 25037e51f197SJoe Perches } 25040a920b5bSAndy Whitcroft } 25050a920b5bSAndy Whitcroft 2506a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2507a2fe16b9SJoe Perches if ($in_header_lines && 2508a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2509a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2510a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2511a2fe16b9SJoe Perches } 2512a2fe16b9SJoe Perches 25139b3189ebSJoe Perches# Check for old stable address 25149b3189ebSJoe Perches if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { 25159b3189ebSJoe Perches ERROR("STABLE_ADDRESS", 25169b3189ebSJoe Perches "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); 25179b3189ebSJoe Perches } 25189b3189ebSJoe Perches 25197ebd05efSChristopher Covington# Check for unwanted Gerrit info 25207ebd05efSChristopher Covington if ($in_commit_log && $line =~ /^\s*change-id:/i) { 25217ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 25227ebd05efSChristopher Covington "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 25237ebd05efSChristopher Covington } 25247ebd05efSChristopher Covington 2525369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 2526369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2527369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 2528369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 2529369c8dd3SJoe Perches # timestamp 2530369c8dd3SJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { 2531369c8dd3SJoe Perches # stack dump address 2532369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 2533369c8dd3SJoe Perches } 2534369c8dd3SJoe Perches 25352a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 25362a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 2537bf4daf12SJoe Perches length($line) > 75 && 2538bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 2539bf4daf12SJoe Perches # file delta changes 2540bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 2541bf4daf12SJoe Perches # filename then : 2542bf4daf12SJoe Perches $line =~ /^\s*(?:Fixes:|Link:)/i || 2543bf4daf12SJoe Perches # A Fixes: or Link: line 2544bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 25452a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 25462a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 25472a076f40SJoe Perches $commit_log_long_line = 1; 25482a076f40SJoe Perches } 25492a076f40SJoe Perches 2550bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 2551bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 2552bf4daf12SJoe Perches $line =~ /^\s*$/) { 2553bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 2554bf4daf12SJoe Perches } 2555bf4daf12SJoe Perches 25560d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 2557369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2558aab38f51SJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && 2559e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 2560fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 2561aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 2562369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 2563bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 2564fe043ea1SJoe Perches my $init_char = "c"; 2565fe043ea1SJoe Perches my $orig_commit = ""; 25660d7835fcSJoe Perches my $short = 1; 25670d7835fcSJoe Perches my $long = 0; 25680d7835fcSJoe Perches my $case = 1; 25690d7835fcSJoe Perches my $space = 1; 25700d7835fcSJoe Perches my $hasdesc = 0; 257119c146a6SJoe Perches my $hasparens = 0; 25720d7835fcSJoe Perches my $id = '0123456789ab'; 25730d7835fcSJoe Perches my $orig_desc = "commit description"; 25740d7835fcSJoe Perches my $description = ""; 25750d7835fcSJoe Perches 2576fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 2577fe043ea1SJoe Perches $init_char = $1; 2578fe043ea1SJoe Perches $orig_commit = lc($2); 2579fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 2580fe043ea1SJoe Perches $orig_commit = lc($1); 2581fe043ea1SJoe Perches } 2582fe043ea1SJoe Perches 25830d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 25840d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 25850d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 25860d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 25870d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 25880d7835fcSJoe Perches $orig_desc = $1; 258919c146a6SJoe Perches $hasparens = 1; 25900d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 25910d7835fcSJoe Perches defined $rawlines[$linenr] && 25920d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 25930d7835fcSJoe Perches $orig_desc = $1; 259419c146a6SJoe Perches $hasparens = 1; 2595b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2596b671fde0SJoe Perches defined $rawlines[$linenr] && 2597b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2598b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2599b671fde0SJoe Perches $orig_desc = $1; 2600b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2601b671fde0SJoe Perches $orig_desc .= " " . $1; 260219c146a6SJoe Perches $hasparens = 1; 26030d7835fcSJoe Perches } 26040d7835fcSJoe Perches 26050d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 26060d7835fcSJoe Perches $id, $orig_desc); 26070d7835fcSJoe Perches 260819c146a6SJoe Perches if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { 2609d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 26100d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 26110d7835fcSJoe Perches } 2612d311cd44SJoe Perches } 2613d311cd44SJoe Perches 261413f1937eSJoe Perches# Check for added, moved or deleted files 261513f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 261613f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 261713f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 261813f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 261913f1937eSJoe Perches (defined($1) || defined($2))))) { 2620a82603a8SAndrew Jeffery $is_patch = 1; 262113f1937eSJoe Perches $reported_maintainer_file = 1; 262213f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 262313f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 262413f1937eSJoe Perches } 262513f1937eSJoe Perches 262600df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 26278905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2628000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2629000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 26306c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2631de7d4f0eSAndy Whitcroft } 2632de7d4f0eSAndy Whitcroft 2633de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2634de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2635171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2636171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2637171ae1a4SAndy Whitcroft 2638171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2639171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2640171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2641171ae1a4SAndy Whitcroft 264234d99219SJoe Perches CHK("INVALID_UTF8", 2643000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 264400df344fSAndy Whitcroft } 26450a920b5bSAndy Whitcroft 264615662b3eSJoe Perches# Check if it's the start of a commit log 264715662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 264815662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 2649eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 2650eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 265115662b3eSJoe Perches $in_header_lines = 0; 265215662b3eSJoe Perches $in_commit_log = 1; 2653ed43c4e5SAllen Hubbe $has_commit_log = 1; 265415662b3eSJoe Perches } 265515662b3eSJoe Perches 2656fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2657fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2658fa64205dSPasi Savanainen if ($in_header_lines && 2659fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2660fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2661fa64205dSPasi Savanainen $non_utf8_charset = 1; 2662fa64205dSPasi Savanainen } 2663fa64205dSPasi Savanainen 2664fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 266515662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2666fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 266715662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 266815662b3eSJoe Perches } 266915662b3eSJoe Perches 2670d6430f71SJoe Perches# Check for absolute kernel paths in commit message 2671d6430f71SJoe Perches if ($tree && $in_commit_log) { 2672d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 2673d6430f71SJoe Perches my $file = $1; 2674d6430f71SJoe Perches 2675d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 2676d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 2677d6430f71SJoe Perches # 2678d6430f71SJoe Perches } else { 2679d6430f71SJoe Perches check_absolute_file($file, $herecurr); 2680d6430f71SJoe Perches } 2681d6430f71SJoe Perches } 2682d6430f71SJoe Perches } 2683d6430f71SJoe Perches 268466b47b4aSKees Cook# Check for various typo / spelling mistakes 268566d7a382SJoe Perches if (defined($misspellings) && 268666d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2687ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 268866b47b4aSKees Cook my $typo = $1; 268966b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 269066b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 269166b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 269266b47b4aSKees Cook my $msg_type = \&WARN; 269366b47b4aSKees Cook $msg_type = \&CHK if ($file); 269466b47b4aSKees Cook if (&{$msg_type}("TYPO_SPELLING", 269566b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 269666b47b4aSKees Cook $fix) { 269766b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 269866b47b4aSKees Cook } 269966b47b4aSKees Cook } 270066b47b4aSKees Cook } 270166b47b4aSKees Cook 270230670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 270330670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 270400df344fSAndy Whitcroft 27050a920b5bSAndy Whitcroft#trailing whitespace 27069c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2707c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2708d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2709d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2710d5e616fcSJoe Perches $fix) { 2711194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2712d5e616fcSJoe Perches } 2713c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2714c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27153705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 27163705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 27173705ce5bSJoe Perches $fix) { 2718194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 27193705ce5bSJoe Perches } 27203705ce5bSJoe Perches 2721d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 27220a920b5bSAndy Whitcroft } 27235368df20SAndy Whitcroft 27244783f894SJosh Triplett# Check for FSF mailing addresses. 2725109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 27261bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 27273e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 27283e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 27294783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27304783f894SJosh Triplett my $msg_type = \&ERROR; 27314783f894SJosh Triplett $msg_type = \&CHK if ($file); 27324783f894SJosh Triplett &{$msg_type}("FSF_MAILING_ADDRESS", 27334783f894SJosh 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) 27344783f894SJosh Triplett } 27354783f894SJosh Triplett 27363354957aSAndi Kleen# check for Kconfig help text having a real description 27379fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 27389fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 27393354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 27408d73e0e7SJoe Perches $line =~ /^\+\s*config\s+/) { 27413354957aSAndi Kleen my $length = 0; 27429fe287d7SAndy Whitcroft my $cnt = $realcnt; 27439fe287d7SAndy Whitcroft my $ln = $linenr + 1; 27449fe287d7SAndy Whitcroft my $f; 2745a1385803SAndy Whitcroft my $is_start = 0; 27469fe287d7SAndy Whitcroft my $is_end = 0; 2747a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 27489fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 27499fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 27509fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 27519fe287d7SAndy Whitcroft 27529fe287d7SAndy Whitcroft next if ($f =~ /^-/); 27538d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 2754a1385803SAndy Whitcroft 27558d73e0e7SJoe Perches if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2756a1385803SAndy Whitcroft $is_start = 1; 27578d73e0e7SJoe Perches } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2758a1385803SAndy Whitcroft $length = -1; 2759a1385803SAndy Whitcroft } 2760a1385803SAndy Whitcroft 27619fe287d7SAndy Whitcroft $f =~ s/^.//; 27623354957aSAndi Kleen $f =~ s/#.*//; 27633354957aSAndi Kleen $f =~ s/^\s+//; 27643354957aSAndi Kleen next if ($f =~ /^$/); 27659fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 27669fe287d7SAndy Whitcroft $is_end = 1; 27679fe287d7SAndy Whitcroft last; 27689fe287d7SAndy Whitcroft } 27693354957aSAndi Kleen $length++; 27703354957aSAndi Kleen } 277156193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 2772000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 277356193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 277456193274SVadim Bendebury } 2775a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 27763354957aSAndi Kleen } 27773354957aSAndi Kleen 2778327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 2779327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 2780327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 2781327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 2782327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2783327953e9SChristoph Jaeger } 2784327953e9SChristoph Jaeger 2785c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2786c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2787c68e5878SArnaud Lacombe my $flag = $1; 2788c68e5878SArnaud Lacombe my $replacement = { 2789c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 2790c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 2791c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 2792c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 2793c68e5878SArnaud Lacombe }; 2794c68e5878SArnaud Lacombe 2795c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 2796c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2797c68e5878SArnaud Lacombe } 2798c68e5878SArnaud Lacombe 2799bff5da43SRob Herring# check for DT compatible documentation 28007dd05b38SFlorian Vaussard if (defined $root && 28017dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 28027dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 28037dd05b38SFlorian Vaussard 2804bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 2805bff5da43SRob Herring 2806cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 2807cc93319bSFlorian Vaussard my $vp_file = $dt_path . "vendor-prefixes.txt"; 2808cc93319bSFlorian Vaussard 2809bff5da43SRob Herring foreach my $compat (@compats) { 2810bff5da43SRob Herring my $compat2 = $compat; 2811185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 2812185d566bSRob Herring my $compat3 = $compat; 2813185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 2814185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 2815bff5da43SRob Herring if ( $? >> 8 ) { 2816bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2817bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 2818bff5da43SRob Herring } 2819bff5da43SRob Herring 28204fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 28214fbf32a6SFlorian Vaussard my $vendor = $1; 2822cc93319bSFlorian Vaussard `grep -Eq "^$vendor\\b" $vp_file`; 2823bff5da43SRob Herring if ( $? >> 8 ) { 2824bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2825cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 2826bff5da43SRob Herring } 2827bff5da43SRob Herring } 2828bff5da43SRob Herring } 2829bff5da43SRob Herring 28305368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 2831d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 28325368df20SAndy Whitcroft 283347e0c88bSJoe Perches# line length limit (with some exclusions) 283447e0c88bSJoe Perches# 283547e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 283647e0c88bSJoe Perches# logging functions like pr_info that end in a string 283747e0c88bSJoe Perches# lines with a single string 283847e0c88bSJoe Perches# #defines that are a single string 283947e0c88bSJoe Perches# 284047e0c88bSJoe Perches# There are 3 different line length message types: 284147e0c88bSJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength 284247e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 284347e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 284447e0c88bSJoe Perches# 284547e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 284647e0c88bSJoe Perches# 284747e0c88bSJoe Perches 2848b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 284947e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 285047e0c88bSJoe Perches 285147e0c88bSJoe Perches # Check the allowed long line types first 285247e0c88bSJoe Perches 285347e0c88bSJoe Perches # logging functions that end in a string that starts 285447e0c88bSJoe Perches # before $max_line_length 285547e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 285647e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 285747e0c88bSJoe Perches $msg_type = ""; 285847e0c88bSJoe Perches 285947e0c88bSJoe Perches # lines with only strings (w/ possible termination) 286047e0c88bSJoe Perches # #defines with only strings 286147e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 286247e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 286347e0c88bSJoe Perches $msg_type = ""; 286447e0c88bSJoe Perches 2865d560a5f8SJoe Perches # EFI_GUID is another special case 2866d560a5f8SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { 2867d560a5f8SJoe Perches $msg_type = ""; 2868d560a5f8SJoe Perches 286947e0c88bSJoe Perches # Otherwise set the alternate message types 287047e0c88bSJoe Perches 287147e0c88bSJoe Perches # a comment starts before $max_line_length 287247e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 287347e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 287447e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 287547e0c88bSJoe Perches 287647e0c88bSJoe Perches # a quoted string starts before $max_line_length 287747e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 287847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 287947e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 288047e0c88bSJoe Perches } 288147e0c88bSJoe Perches 288247e0c88bSJoe Perches if ($msg_type ne "" && 288347e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 288447e0c88bSJoe Perches WARN($msg_type, 28856cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 28860a920b5bSAndy Whitcroft } 288747e0c88bSJoe Perches } 28880a920b5bSAndy Whitcroft 28898905a67cSAndy Whitcroft# check for adding lines without a newline. 28908905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2891000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 2892000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 28938905a67cSAndy Whitcroft } 28948905a67cSAndy Whitcroft 289542e41c54SMike Frysinger# Blackfin: use hi/lo macros 289642e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 289742e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 289842e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2899000d1cc1SJoe Perches ERROR("LO_MACRO", 2900000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 290142e41c54SMike Frysinger } 290242e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 290342e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2904000d1cc1SJoe Perches ERROR("HI_MACRO", 2905000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 290642e41c54SMike Frysinger } 290742e41c54SMike Frysinger } 290842e41c54SMike Frysinger 2909b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2910de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 29110a920b5bSAndy Whitcroft 29120a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 29130a920b5bSAndy Whitcroft# more than 8 must use tabs. 2914c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2915c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2916c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2917d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29183705ce5bSJoe Perches if (ERROR("CODE_INDENT", 29193705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 29203705ce5bSJoe Perches $fix) { 2921194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 29223705ce5bSJoe Perches } 29230a920b5bSAndy Whitcroft } 29240a920b5bSAndy Whitcroft 292508e44365SAlberto Panizzo# check for space before tabs. 292608e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 292708e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29283705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 29293705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 29303705ce5bSJoe Perches $fix) { 2931194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2932d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 2933194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2934c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 29353705ce5bSJoe Perches } 293608e44365SAlberto Panizzo } 293708e44365SAlberto Panizzo 2938d1fe9c09SJoe Perches# check for && or || at the start of a line 2939d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2940d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2941d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2942d1fe9c09SJoe Perches } 2943d1fe9c09SJoe Perches 2944a91e8994SJoe Perches# check indentation starts on a tab stop 2945a91e8994SJoe Perches if ($^V && $^V ge 5.10.0 && 2946a91e8994SJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { 2947a91e8994SJoe Perches my $indent = length($1); 2948a91e8994SJoe Perches if ($indent % 8) { 2949a91e8994SJoe Perches if (WARN("TABSTOP", 2950a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 2951a91e8994SJoe Perches $fix) { 2952a91e8994SJoe Perches $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 2953a91e8994SJoe Perches } 2954a91e8994SJoe Perches } 2955a91e8994SJoe Perches } 2956a91e8994SJoe Perches 2957d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2958d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 295991cb5195SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2960d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2961d1fe9c09SJoe Perches my $oldindent = $1; 2962d1fe9c09SJoe Perches my $rest = $2; 2963d1fe9c09SJoe Perches 2964d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2965d1fe9c09SJoe Perches if ($pos >= 0) { 2966b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2967b34a26f3SJoe Perches my $newindent = $2; 2968d1fe9c09SJoe Perches 2969d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2970d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2971d1fe9c09SJoe Perches " " x ($pos % 8); 2972d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2973d1fe9c09SJoe Perches 2974d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2975d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 29763705ce5bSJoe Perches 29773705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 29783705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 29793705ce5bSJoe Perches $fix && $line =~ /^\+/) { 2980194f66fcSJoe Perches $fixed[$fixlinenr] =~ 29813705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 29823705ce5bSJoe Perches } 2983d1fe9c09SJoe Perches } 2984d1fe9c09SJoe Perches } 2985d1fe9c09SJoe Perches } 2986d1fe9c09SJoe Perches 29876ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 29886ab3a970SJoe Perches# avoid checking a few false positives: 29896ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 29906ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 29916ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 29926ab3a970SJoe Perches# multiline macros that define functions 29936ab3a970SJoe Perches# known attributes or the __attribute__ keyword 29946ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 29956ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 29963705ce5bSJoe Perches if (CHK("SPACING", 2997f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 29983705ce5bSJoe Perches $fix) { 2999194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3000f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 30013705ce5bSJoe Perches } 3002aad4f614SJoe Perches } 3003aad4f614SJoe Perches 300486406b1cSJoe Perches# Block comment styles 300586406b1cSJoe Perches# Networking with an initial /* 300605880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3007fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 300885ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 300985ad978cSJoe Perches $realline > 2) { 301005880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 301105880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 301205880600SJoe Perches } 301305880600SJoe Perches 301486406b1cSJoe Perches# Block comments use * on subsequent lines 301586406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 301686406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3017a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 301861135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3019a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 302086406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 302186406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3022a605e32eSJoe Perches } 3023a605e32eSJoe Perches 302486406b1cSJoe Perches# Block comments use */ on trailing lines 302586406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3026c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3027c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3028c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 302986406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 303086406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 303105880600SJoe Perches } 303205880600SJoe Perches 303308eb9b80SJoe Perches# Block comment * alignment 303408eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3035af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3036af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3037af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 303808eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3039af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3040af207524SJoe Perches my $oldindent; 304108eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3042af207524SJoe Perches if (defined($1)) { 3043af207524SJoe Perches $oldindent = expand_tabs($1); 3044af207524SJoe Perches } else { 3045af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3046af207524SJoe Perches $oldindent = expand_tabs($1); 3047af207524SJoe Perches } 304808eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 304908eb9b80SJoe Perches my $newindent = $1; 305008eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3051af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 305208eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 305308eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 305408eb9b80SJoe Perches } 305508eb9b80SJoe Perches } 305608eb9b80SJoe Perches 30577f619191SJoe Perches# check for missing blank lines after struct/union declarations 30587f619191SJoe Perches# with exceptions for various attributes and macros 30597f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 30607f619191SJoe Perches $line =~ /^\+/ && 30617f619191SJoe Perches !($line =~ /^\+\s*$/ || 30627f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 30637f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 30647f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 30657f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 30667f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 30677f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 30687f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3069d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3070d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3071d752fcc8SJoe Perches $fix) { 3072f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3073d752fcc8SJoe Perches } 30747f619191SJoe Perches } 30757f619191SJoe Perches 3076365dd4eaSJoe Perches# check for multiple consecutive blank lines 3077365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3078365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3079365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3080d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3081d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3082d752fcc8SJoe Perches $fix) { 3083f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3084d752fcc8SJoe Perches } 3085d752fcc8SJoe Perches 3086365dd4eaSJoe Perches $last_blank_line = $linenr; 3087365dd4eaSJoe Perches } 3088365dd4eaSJoe Perches 30893b617e3bSJoe Perches# check for missing blank lines after declarations 30903f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 30913f7bac03SJoe Perches # actual declarations 30923f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 30935a4e1fd3SJoe Perches # function pointer declarations 30945a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 30953f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 30963f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 30973f7bac03SJoe Perches # known declaration macros 30983f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 30993f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 31003f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 31013f7bac03SJoe Perches # other possible extensions of declaration lines 31023f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 31033f7bac03SJoe Perches # not starting a section or a macro "\" extended line 31043f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 31053f7bac03SJoe Perches # looks like a declaration 31063f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31075a4e1fd3SJoe Perches # function pointer declarations 31085a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31093f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31103f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31113f7bac03SJoe Perches # known declaration macros 31123f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 31133f7bac03SJoe Perches # start of struct or union or enum 31143b617e3bSJoe Perches $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 31153f7bac03SJoe Perches # start or end of block or continuation of declaration 31163f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 31173f7bac03SJoe Perches # bitfield continuation 31183f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 31193f7bac03SJoe Perches # other possible extensions of declaration lines 31203f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 31213f7bac03SJoe Perches # indentation of previous and current line are the same 31223f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3123d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3124d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3125d752fcc8SJoe Perches $fix) { 3126f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3127d752fcc8SJoe Perches } 31283b617e3bSJoe Perches } 31293b617e3bSJoe Perches 31305f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 31316b4c5bebSAndy Whitcroft# Exceptions: 31326b4c5bebSAndy Whitcroft# 1) within comments 31336b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 31346b4c5bebSAndy Whitcroft# 3) hanging labels 31353705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 31365f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 31373705ce5bSJoe Perches if (WARN("LEADING_SPACE", 31383705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 31393705ce5bSJoe Perches $fix) { 3140194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31413705ce5bSJoe Perches } 31425f7ddae6SRaffaele Recalcati } 31435f7ddae6SRaffaele Recalcati 3144b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3145b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3146b9ea10d6SAndy Whitcroft 31474dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 31484dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 31494dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 31504dbed76fSJoe Perches $context_function = $1; 31514dbed76fSJoe Perches } 31524dbed76fSJoe Perches 31534dbed76fSJoe Perches# check if this appears to be the end of function declaration 31544dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 31554dbed76fSJoe Perches undef $context_function; 31564dbed76fSJoe Perches } 31574dbed76fSJoe Perches 3158032a4c0fSJoe Perches# check indentation of any line with a bare else 3159840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3160032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3161032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3162032a4c0fSJoe Perches my $tabs = length($1) + 1; 3163840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3164840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3165840080a0SJoe Perches defined $lines[$linenr] && 3166840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3167032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3168032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3169032a4c0fSJoe Perches } 3170032a4c0fSJoe Perches } 3171032a4c0fSJoe Perches 3172c00df19aSJoe Perches# check indentation of a line with a break; 3173c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3174c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3175c00df19aSJoe Perches my $tabs = $1; 3176c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3177c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3178c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3179c00df19aSJoe Perches } 3180c00df19aSJoe Perches } 3181c00df19aSJoe Perches 3182c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3183cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3184000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3185000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3186c2fdda0dSAndy Whitcroft } 318722f2a2efSAndy Whitcroft 318842e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 318942e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 319042e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3191000d1cc1SJoe Perches ERROR("CSYNC", 3192000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 319342e41c54SMike Frysinger } 319442e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 319542e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3196000d1cc1SJoe Perches ERROR("SSYNC", 3197000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 319842e41c54SMike Frysinger } 319942e41c54SMike Frysinger 320056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 320156e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 320256e77d70SJoe Perches WARN("HOTPLUG_SECTION", 320356e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 320456e77d70SJoe Perches } 320556e77d70SJoe Perches 32069c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 32072b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 32082b474a1aSAndy Whitcroft $realline_next); 32093e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 32103e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 32111b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3212170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3213f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3214171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3215171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3216171ae1a4SAndy Whitcroft 32173e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 32183e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 32193e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 32203e469cdcSAndy Whitcroft # until we hit end of it. 32213e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 32223e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 32233e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 32243e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 32253e469cdcSAndy Whitcroft } 3226f74bd194SAndy Whitcroft 32272b474a1aSAndy Whitcroft # Find the real next line. 32282b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 32292b474a1aSAndy Whitcroft if (defined $realline_next && 32302b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 32312b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 32322b474a1aSAndy Whitcroft $realline_next++; 32332b474a1aSAndy Whitcroft } 32342b474a1aSAndy Whitcroft 3235171ae1a4SAndy Whitcroft my $s = $stat; 3236171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3237cf655043SAndy Whitcroft 3238c2fdda0dSAndy Whitcroft # Ignore goto labels. 3239171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3240c2fdda0dSAndy Whitcroft 3241c2fdda0dSAndy Whitcroft # Ignore functions being called 3242171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3243c2fdda0dSAndy Whitcroft 3244463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3245463f2864SAndy Whitcroft 3246c45dcabdSAndy Whitcroft # declarations always start with types 3247d2506586SAndy 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) { 3248c45dcabdSAndy Whitcroft my $type = $1; 3249c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3250c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3251c45dcabdSAndy Whitcroft 32526c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3253a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3254c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3255c2fdda0dSAndy Whitcroft } 32568905a67cSAndy Whitcroft 32576c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 325865863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3259c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 32609c0ca6f9SAndy Whitcroft } 32618905a67cSAndy Whitcroft 32628905a67cSAndy Whitcroft # Check for any sort of function declaration. 32638905a67cSAndy Whitcroft # int foo(something bar, other baz); 32648905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3265171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 32668905a67cSAndy Whitcroft my ($name_len) = length($1); 32678905a67cSAndy Whitcroft 3268cf655043SAndy Whitcroft my $ctx = $s; 3269773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 32708905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3271cf655043SAndy Whitcroft 32728905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3273c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 32748905a67cSAndy Whitcroft 3275c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 32768905a67cSAndy Whitcroft } 32778905a67cSAndy Whitcroft } 32788905a67cSAndy Whitcroft } 32798905a67cSAndy Whitcroft 32809c0ca6f9SAndy Whitcroft } 32819c0ca6f9SAndy Whitcroft 328200df344fSAndy Whitcroft# 328300df344fSAndy Whitcroft# Checks which may be anchored in the context. 328400df344fSAndy Whitcroft# 328500df344fSAndy Whitcroft 328600df344fSAndy Whitcroft# Check for switch () and associated case and default 328700df344fSAndy Whitcroft# statements should be at the same indent. 328800df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 328900df344fSAndy Whitcroft my $err = ''; 329000df344fSAndy Whitcroft my $sep = ''; 329100df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 329200df344fSAndy Whitcroft shift(@ctx); 329300df344fSAndy Whitcroft for my $ctx (@ctx) { 329400df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 329500df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 329600df344fSAndy Whitcroft $indent != $cindent) { 329700df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 329800df344fSAndy Whitcroft $sep = ''; 329900df344fSAndy Whitcroft } else { 330000df344fSAndy Whitcroft $sep = "[...]\n"; 330100df344fSAndy Whitcroft } 330200df344fSAndy Whitcroft } 330300df344fSAndy Whitcroft if ($err ne '') { 3304000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3305000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3306de7d4f0eSAndy Whitcroft } 3307de7d4f0eSAndy Whitcroft } 3308de7d4f0eSAndy Whitcroft 3309de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3310de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 33110fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3312773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3313773647a0SAndy Whitcroft 33149c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 33158eef05ddSJoe Perches 33168eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 33178eef05ddSJoe Perches WARN("DEEP_INDENTATION", 33188eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 33198eef05ddSJoe Perches } 33208eef05ddSJoe Perches 3321de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3322de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3323de7d4f0eSAndy Whitcroft 3324548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3325548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3326de7d4f0eSAndy Whitcroft 3327548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3328548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3329548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3330548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3331548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3332773647a0SAndy Whitcroft $ctx_ln++; 3333773647a0SAndy Whitcroft } 3334548596d5SAndy Whitcroft 333553210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 333653210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3337773647a0SAndy Whitcroft 3338773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3339000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3340000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 334101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 334200df344fSAndy Whitcroft } 3343773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3344773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3345773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3346773647a0SAndy Whitcroft { 33479c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 33489c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3349000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3350000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 335101464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 33529c0ca6f9SAndy Whitcroft } 33539c0ca6f9SAndy Whitcroft } 335400df344fSAndy Whitcroft } 335500df344fSAndy Whitcroft 33564d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 33570fe3dc2bSJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 33583e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 33593e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 33603e469cdcSAndy Whitcroft if (!defined $stat); 33614d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 33624d001e4dSAndy Whitcroft 33634d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 33644d001e4dSAndy Whitcroft 33659f5af480SJoe Perches # remove inline comments 33669f5af480SJoe Perches $s =~ s/$;/ /g; 33679f5af480SJoe Perches $c =~ s/$;/ /g; 33684d001e4dSAndy Whitcroft 33694d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 33706f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 33716f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 33724d001e4dSAndy Whitcroft 33739f5af480SJoe Perches # Make sure we remove the line prefixes as we have 33749f5af480SJoe Perches # none on the first line, and are going to readd them 33759f5af480SJoe Perches # where necessary. 33769f5af480SJoe Perches $s =~ s/\n./\n/gs; 33779f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 33789f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 33799f5af480SJoe Perches } 33809f5af480SJoe Perches 33814d001e4dSAndy Whitcroft # We want to check the first line inside the block 33824d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 33834d001e4dSAndy Whitcroft # 1) any blank line termination 33844d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 33854d001e4dSAndy Whitcroft # 3) any do (...) { 33864d001e4dSAndy Whitcroft my $continuation = 0; 33874d001e4dSAndy Whitcroft my $check = 0; 33884d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 33894d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 33904d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 33914d001e4dSAndy Whitcroft $continuation = 1; 33924d001e4dSAndy Whitcroft } 33939bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 33944d001e4dSAndy Whitcroft $check = 1; 33954d001e4dSAndy Whitcroft $cond_lines++; 33964d001e4dSAndy Whitcroft } 33974d001e4dSAndy Whitcroft 33984d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 33994d001e4dSAndy Whitcroft # preprocessor statement. 34004d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 34014d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 34024d001e4dSAndy Whitcroft $check = 0; 34034d001e4dSAndy Whitcroft } 34044d001e4dSAndy Whitcroft 34059bd49efeSAndy Whitcroft my $cond_ptr = -1; 3406740504c6SAndy Whitcroft $continuation = 0; 34079bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 34089bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 34094d001e4dSAndy Whitcroft 3410f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3411f16fa28fSAndy Whitcroft # is not linear. 3412f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3413f16fa28fSAndy Whitcroft $check = 0; 3414f16fa28fSAndy Whitcroft } 3415f16fa28fSAndy Whitcroft 34169bd49efeSAndy Whitcroft # Ignore: 34179bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 34189bd49efeSAndy Whitcroft # 2) preprocessor lines, and 34199bd49efeSAndy Whitcroft # 3) labels. 3420740504c6SAndy Whitcroft if ($continuation || 3421740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 34229bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 34239bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3424740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 342530dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 34269bd49efeSAndy Whitcroft $cond_lines++; 34279bd49efeSAndy Whitcroft } 34284d001e4dSAndy Whitcroft } 342930dad6ebSAndy Whitcroft } 34304d001e4dSAndy Whitcroft 34314d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 34324d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 34334d001e4dSAndy Whitcroft 34344d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 34354d001e4dSAndy Whitcroft # this is not this patch's fault. 34364d001e4dSAndy Whitcroft if (!defined($stat_real) || 34374d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 34384d001e4dSAndy Whitcroft $check = 0; 34394d001e4dSAndy Whitcroft } 34404d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 34414d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 34424d001e4dSAndy Whitcroft } 34434d001e4dSAndy Whitcroft 34449bd49efeSAndy 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"; 34454d001e4dSAndy Whitcroft 34469f5af480SJoe Perches if ($check && $s ne '' && 34479f5af480SJoe Perches (($sindent % 8) != 0 || 34489f5af480SJoe Perches ($sindent < $indent) || 34499f5af480SJoe Perches ($sindent > $indent + 8))) { 3450000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3451000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 34524d001e4dSAndy Whitcroft } 34534d001e4dSAndy Whitcroft } 34544d001e4dSAndy Whitcroft 34556c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 34566c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 34571f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 34581f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 34596c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3460c2fdda0dSAndy Whitcroft if ($dbg_values) { 3461c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3462cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3463cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 34641f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3465c2fdda0dSAndy Whitcroft } 34666c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 34676c72ffaaSAndy Whitcroft 346800df344fSAndy Whitcroft#ignore lines not being added 34693705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 347000df344fSAndy Whitcroft 347111ca40a0SJoe Perches# check for dereferences that span multiple lines 347211ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 347311ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 347411ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 347511ca40a0SJoe Perches my $ref = $1; 347611ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 347711ca40a0SJoe Perches $ref .= $1; 347811ca40a0SJoe Perches $ref =~ s/\s//g; 347911ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 348011ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 348111ca40a0SJoe Perches } 348211ca40a0SJoe Perches 3483a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3484c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3485a1ce18e4SJoe Perches my $type = $1; 3486a1ce18e4SJoe Perches my $var = $2; 3487207a8e84SJoe Perches $var = "" if (!defined $var); 3488207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3489a1ce18e4SJoe Perches my $sign = $1; 3490a1ce18e4SJoe Perches my $pointer = $2; 3491a1ce18e4SJoe Perches 3492a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3493a1ce18e4SJoe Perches 3494a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3495a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3496a1ce18e4SJoe Perches $fix) { 3497a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3498207a8e84SJoe Perches my $comp_pointer = $pointer; 3499207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3500207a8e84SJoe Perches $decl .= $comp_pointer; 3501207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3502207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3503a1ce18e4SJoe Perches } 3504a1ce18e4SJoe Perches } 3505a1ce18e4SJoe Perches } 3506a1ce18e4SJoe Perches 3507653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 35087429c690SAndy Whitcroft if ($dbg_type) { 35097429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3510000d1cc1SJoe Perches ERROR("TEST_TYPE", 3511000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 35127429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3513000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3514000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 35157429c690SAndy Whitcroft } 3516653d4876SAndy Whitcroft next; 3517653d4876SAndy Whitcroft } 3518a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3519a1ef277eSAndy Whitcroft if ($dbg_attr) { 35209360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3521000d1cc1SJoe Perches ERROR("TEST_ATTR", 3522000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 35239360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3524000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3525000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3526a1ef277eSAndy Whitcroft } 3527a1ef277eSAndy Whitcroft next; 3528a1ef277eSAndy Whitcroft } 3529653d4876SAndy Whitcroft 3530f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 353199423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 353299423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3533d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3534d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3535f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3536f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3537f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3538d752fcc8SJoe Perches my $fixedline = $prevrawline; 3539d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3540f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3541d752fcc8SJoe Perches $fixedline = $line; 3542d752fcc8SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1/; 3543f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3544d752fcc8SJoe Perches } 3545f0a594c1SAndy Whitcroft } 3546f0a594c1SAndy Whitcroft 354700df344fSAndy Whitcroft# 354800df344fSAndy Whitcroft# Checks which are anchored on the added line. 354900df344fSAndy Whitcroft# 355000df344fSAndy Whitcroft 3551653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3552c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3553653d4876SAndy Whitcroft my $path = $1; 3554653d4876SAndy Whitcroft if ($path =~ m{//}) { 3555000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3556495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3557495e9d84SJoe Perches } 3558495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3559495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3560495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3561653d4876SAndy Whitcroft } 3562653d4876SAndy Whitcroft } 3563653d4876SAndy Whitcroft 356400df344fSAndy Whitcroft# no C99 // comments 356500df344fSAndy Whitcroft if ($line =~ m{//}) { 35663705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 35673705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 35683705ce5bSJoe Perches $fix) { 3569194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 35703705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 35713705ce5bSJoe Perches my $comment = trim($1); 3572194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 35733705ce5bSJoe Perches } 35743705ce5bSJoe Perches } 357500df344fSAndy Whitcroft } 357600df344fSAndy Whitcroft # Remove C99 comments. 35770a920b5bSAndy Whitcroft $line =~ s@//.*@@; 35786c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 35790a920b5bSAndy Whitcroft 35802b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 35812b474a1aSAndy Whitcroft# the whole statement. 35822b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 35832b474a1aSAndy Whitcroft if (defined $realline_next && 35842b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 35852b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 35862b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 35872b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 35883cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 35893cbf62dfSAndy Whitcroft # a prefix: 35903cbf62dfSAndy Whitcroft # XXX(foo); 35913cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3592653d4876SAndy Whitcroft my $name = $1; 359387a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 35943cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 35953cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 35963cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 35973cbf62dfSAndy Whitcroft 35983cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 35992b474a1aSAndy Whitcroft \n.}\s*$| 360048012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 360148012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 360248012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 36032b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 36042b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 360548012058SAndy Whitcroft )/x) { 36062b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 36072b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 36082b474a1aSAndy Whitcroft } else { 36092b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 36100a920b5bSAndy Whitcroft } 36110a920b5bSAndy Whitcroft } 36122b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 36132b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 36142b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36152b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36162b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 36172b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 36182b474a1aSAndy Whitcroft } 36192b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 36202b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3621000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3622000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 36232b474a1aSAndy Whitcroft } 36240a920b5bSAndy Whitcroft 36255150bda4SJoe Eloff# check for global initialisers. 36266d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3627d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 36286d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3629d5e616fcSJoe Perches $fix) { 36306d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3631d5e616fcSJoe Perches } 3632f0a594c1SAndy Whitcroft } 36330a920b5bSAndy Whitcroft# check for static initialisers. 36346d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3635d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 36366d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3637d5e616fcSJoe Perches $herecurr) && 3638d5e616fcSJoe Perches $fix) { 36396d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3640d5e616fcSJoe Perches } 36410a920b5bSAndy Whitcroft } 36420a920b5bSAndy Whitcroft 36431813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 36441813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36451813087dSJoe Perches my $tmp = trim($1); 36461813087dSJoe Perches WARN("MISORDERED_TYPE", 36471813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36481813087dSJoe Perches } 36491813087dSJoe Perches 3650cb710ecaSJoe Perches# check for static const char * arrays. 3651cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3652000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3653000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3654cb710ecaSJoe Perches $herecurr); 3655cb710ecaSJoe Perches } 3656cb710ecaSJoe Perches 3657cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3658cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3659000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3660000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3661cb710ecaSJoe Perches $herecurr); 3662cb710ecaSJoe Perches } 3663cb710ecaSJoe Perches 3664ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3665ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3666ab7e23f3SJoe Perches my $found = $1; 3667ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3668ab7e23f3SJoe Perches WARN("CONST_CONST", 3669ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3670ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3671ab7e23f3SJoe Perches WARN("CONST_CONST", 3672ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3673ab7e23f3SJoe Perches } 3674ab7e23f3SJoe Perches } 3675ab7e23f3SJoe Perches 36769b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 36779b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 36789b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 36799b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 36809b0fa60dSJoe Perches $herecurr); 36819b0fa60dSJoe Perches } 36829b0fa60dSJoe Perches 3683b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3684b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3685b598b670SJoe Perches my $array = $1; 3686b598b670SJoe 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*\))@) { 3687b598b670SJoe Perches my $array_div = $1; 3688b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3689b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3690b598b670SJoe Perches $fix) { 3691b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3692b598b670SJoe Perches } 3693b598b670SJoe Perches } 3694b598b670SJoe Perches } 3695b598b670SJoe Perches 3696b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3697b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3698b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3699b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3700b36190c5SJoe Perches $fix) { 3701194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3702b36190c5SJoe Perches } 3703b36190c5SJoe Perches } 3704b36190c5SJoe Perches 3705653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3706653d4876SAndy Whitcroft# make sense. 3707653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 37088054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3709c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 37108ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 371146d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 3712000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3713000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 37140a920b5bSAndy Whitcroft } 37150a920b5bSAndy Whitcroft 37160a920b5bSAndy Whitcroft# * goes on variable not on type 371765863862SAndy Whitcroft # (char*[ const]) 3718bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3719bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 37203705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3721d8aaf121SAndy Whitcroft 372265863862SAndy Whitcroft # Should start with a space. 372365863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 372465863862SAndy Whitcroft # Should not end with a space. 372565863862SAndy Whitcroft $to =~ s/\s+$//; 372665863862SAndy Whitcroft # '*'s should not have spaces between. 3727f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 372865863862SAndy Whitcroft } 3729d8aaf121SAndy Whitcroft 37303705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 373165863862SAndy Whitcroft if ($from ne $to) { 37323705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37333705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37343705ce5bSJoe Perches $fix) { 37353705ce5bSJoe Perches my $sub_from = $ident; 37363705ce5bSJoe Perches my $sub_to = $ident; 37373705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3738194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37393705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37403705ce5bSJoe Perches } 374165863862SAndy Whitcroft } 3742bfcb2cc7SAndy Whitcroft } 3743bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3744bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 37453705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3746d8aaf121SAndy Whitcroft 374765863862SAndy Whitcroft # Should start with a space. 374865863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 374965863862SAndy Whitcroft # Should not end with a space. 375065863862SAndy Whitcroft $to =~ s/\s+$//; 375165863862SAndy Whitcroft # '*'s should not have spaces between. 3752f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 375365863862SAndy Whitcroft } 375465863862SAndy Whitcroft # Modifiers should have spaces. 375565863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 375665863862SAndy Whitcroft 37573705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3758667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 37593705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37603705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 37613705ce5bSJoe Perches $fix) { 37623705ce5bSJoe Perches 37633705ce5bSJoe Perches my $sub_from = $match; 37643705ce5bSJoe Perches my $sub_to = $match; 37653705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3766194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37673705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37683705ce5bSJoe Perches } 376965863862SAndy Whitcroft } 37700a920b5bSAndy Whitcroft } 37710a920b5bSAndy Whitcroft 37729d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 37739d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 37749d3e3c70SJoe Perches my $msg_type = \&WARN; 37759d3e3c70SJoe Perches $msg_type = \&CHK if ($file); 37769d3e3c70SJoe Perches &{$msg_type}("AVOID_BUG", 37779d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 37789d3e3c70SJoe Perches } 37790a920b5bSAndy Whitcroft 37809d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 37818905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3782000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3783000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 37848905a67cSAndy Whitcroft } 37858905a67cSAndy Whitcroft 378617441227SJoe Perches# check for uses of printk_ratelimit 378717441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3788000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3789000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 379017441227SJoe Perches } 379117441227SJoe Perches 379200df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 379300df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 379400df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 379525985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 379600df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3797f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 379800df344fSAndy Whitcroft my $ok = 0; 379900df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 380000df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 380125985edcSLucas De Marchi # we have a preceding printk if it ends 380200df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 380300df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 380400df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 380500df344fSAndy Whitcroft $ok = 1; 380600df344fSAndy Whitcroft } 380700df344fSAndy Whitcroft last; 380800df344fSAndy Whitcroft } 380900df344fSAndy Whitcroft } 381000df344fSAndy Whitcroft if ($ok == 0) { 3811000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3812000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 38130a920b5bSAndy Whitcroft } 381400df344fSAndy Whitcroft } 38150a920b5bSAndy Whitcroft 3816243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3817243f3803SJoe Perches my $orig = $1; 3818243f3803SJoe Perches my $level = lc($orig); 3819243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 38208f26b837SJoe Perches my $level2 = $level; 38218f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3822243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3823daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3824243f3803SJoe Perches } 3825243f3803SJoe Perches 3826243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3827d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3828d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3829d5e616fcSJoe Perches $fix) { 3830194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3831d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3832d5e616fcSJoe Perches } 3833243f3803SJoe Perches } 3834243f3803SJoe Perches 3835dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3836dc139313SJoe Perches my $orig = $1; 3837dc139313SJoe Perches my $level = lc($orig); 3838dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3839dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3840dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3841dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3842dc139313SJoe Perches } 3843dc139313SJoe Perches 384491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 384591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 384691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 384791c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 384891c9afafSAndy Lutomirski WARN("ENOSYS", 384991c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 385091c9afafSAndy Lutomirski } 385191c9afafSAndy Lutomirski 3852653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3853653d4876SAndy Whitcroft# or if closed on same line 38548d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 38554e5d56bdSEddie Kovsky !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38568d182478SJoe Perches if (ERROR("OPEN_BRACE", 38578d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38588d182478SJoe Perches $fix) { 38598d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38608d182478SJoe Perches my $fixed_line = $rawline; 38618d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 38628d182478SJoe Perches my $line1 = $1; 38638d182478SJoe Perches my $line2 = $2; 38648d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 38658d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 38668d182478SJoe Perches if ($line2 !~ /^\s*$/) { 38678d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 38688d182478SJoe Perches } 38698d182478SJoe Perches } 38700a920b5bSAndy Whitcroft } 3871653d4876SAndy Whitcroft 38728905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 38738905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 38748905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 38758d182478SJoe Perches if (ERROR("OPEN_BRACE", 38768d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 38778d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 38788d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 38798d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38808d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 38818d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38828d182478SJoe Perches $fixedline = $rawline; 38838d182478SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1\t/; 38848d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 38858d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38868d182478SJoe Perches } 38878d182478SJoe Perches } 38888905a67cSAndy Whitcroft } 38898905a67cSAndy Whitcroft 38900c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 38913705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 38923705ce5bSJoe Perches if (WARN("SPACING", 38933705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 38943705ce5bSJoe Perches $fix) { 3895194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38963705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 38973705ce5bSJoe Perches } 38980c73b4ebSAndy Whitcroft } 38990c73b4ebSAndy Whitcroft 390031070b5dSJoe Perches# Function pointer declarations 390131070b5dSJoe Perches# check spacing between type, funcptr, and args 390231070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 390391f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 390431070b5dSJoe Perches my $declare = $1; 390531070b5dSJoe Perches my $pre_pointer_space = $2; 390631070b5dSJoe Perches my $post_pointer_space = $3; 390731070b5dSJoe Perches my $funcname = $4; 390831070b5dSJoe Perches my $post_funcname_space = $5; 390931070b5dSJoe Perches my $pre_args_space = $6; 391031070b5dSJoe Perches 391191f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 391291f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 391391f72e9cSJoe Perches# don't need a space so don't warn for those. 391491f72e9cSJoe Perches my $post_declare_space = ""; 391591f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 391691f72e9cSJoe Perches $post_declare_space = $1; 391791f72e9cSJoe Perches $declare = rtrim($declare); 391891f72e9cSJoe Perches } 391991f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 392031070b5dSJoe Perches WARN("SPACING", 392131070b5dSJoe Perches "missing space after return type\n" . $herecurr); 392291f72e9cSJoe Perches $post_declare_space = " "; 392331070b5dSJoe Perches } 392431070b5dSJoe Perches 392531070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 392691f72e9cSJoe Perches# This test is not currently implemented because these declarations are 392791f72e9cSJoe Perches# equivalent to 392891f72e9cSJoe Perches# int foo(int bar, ...) 392991f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 393091f72e9cSJoe Perches# 393191f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 393291f72e9cSJoe Perches# WARN("SPACING", 393391f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 393491f72e9cSJoe Perches# } 393531070b5dSJoe Perches 393631070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 393731070b5dSJoe Perches if (defined $pre_pointer_space && 393831070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 393931070b5dSJoe Perches WARN("SPACING", 394031070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 394131070b5dSJoe Perches } 394231070b5dSJoe Perches 394331070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 394431070b5dSJoe Perches if (defined $post_pointer_space && 394531070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 394631070b5dSJoe Perches WARN("SPACING", 394731070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 394831070b5dSJoe Perches } 394931070b5dSJoe Perches 395031070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 395131070b5dSJoe Perches if (defined $post_funcname_space && 395231070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 395331070b5dSJoe Perches WARN("SPACING", 395431070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 395531070b5dSJoe Perches } 395631070b5dSJoe Perches 395731070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 395831070b5dSJoe Perches if (defined $pre_args_space && 395931070b5dSJoe Perches $pre_args_space =~ /^\s/) { 396031070b5dSJoe Perches WARN("SPACING", 396131070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 396231070b5dSJoe Perches } 396331070b5dSJoe Perches 396431070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3965194f66fcSJoe Perches $fixed[$fixlinenr] =~ 396691f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 396731070b5dSJoe Perches } 396831070b5dSJoe Perches } 396931070b5dSJoe Perches 39708d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 39718d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3972fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3973fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 39748d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 39758d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 39768d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3977fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3978daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 39793705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 39803705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 39813705ce5bSJoe Perches $fix) { 3982194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39833705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 39843705ce5bSJoe Perches } 39858d31cfceSAndy Whitcroft } 39868d31cfceSAndy Whitcroft } 39878d31cfceSAndy Whitcroft 3988f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 39896c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 3990c2fdda0dSAndy Whitcroft my $name = $1; 3991773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 3992773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 3993c2fdda0dSAndy Whitcroft 3994c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 3995773647a0SAndy Whitcroft if ($name =~ /^(?: 3996773647a0SAndy Whitcroft if|for|while|switch|return|case| 3997773647a0SAndy Whitcroft volatile|__volatile__| 3998773647a0SAndy Whitcroft __attribute__|format|__extension__| 3999773647a0SAndy Whitcroft asm|__asm__)$/x) 4000773647a0SAndy Whitcroft { 4001c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4002c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4003c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4004c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4005773647a0SAndy Whitcroft 4006773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4007c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4008c2fdda0dSAndy Whitcroft 4009c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4010c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4011773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4012c2fdda0dSAndy Whitcroft 4013c2fdda0dSAndy Whitcroft } else { 40143705ce5bSJoe Perches if (WARN("SPACING", 40153705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40163705ce5bSJoe Perches $fix) { 4017194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40183705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 40193705ce5bSJoe Perches } 4020f0a594c1SAndy Whitcroft } 40216c72ffaaSAndy Whitcroft } 40229a4cad4eSEric Nelson 4023653d4876SAndy Whitcroft# Check operator spacing. 40240a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 40253705ce5bSJoe Perches my $fixed_line = ""; 40263705ce5bSJoe Perches my $line_fixed = 0; 40273705ce5bSJoe Perches 40289c0ca6f9SAndy Whitcroft my $ops = qr{ 40299c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 40309c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 40319c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 40321f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 403384731623SJoe Perches \?:|\?|: 40349c0ca6f9SAndy Whitcroft }x; 4035cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 40363705ce5bSJoe Perches 40373705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 40383705ce5bSJoe Perches## foreach my $el (@elements) { 40393705ce5bSJoe Perches## print("el: <$el>\n"); 40403705ce5bSJoe Perches## } 40413705ce5bSJoe Perches 40423705ce5bSJoe Perches my @fix_elements = (); 404300df344fSAndy Whitcroft my $off = 0; 40446c72ffaaSAndy Whitcroft 40453705ce5bSJoe Perches foreach my $el (@elements) { 40463705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 40473705ce5bSJoe Perches $off += length($el); 40483705ce5bSJoe Perches } 40493705ce5bSJoe Perches 40503705ce5bSJoe Perches $off = 0; 40513705ce5bSJoe Perches 40526c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4053b34c648bSJoe Perches my $last_after = -1; 40546c72ffaaSAndy Whitcroft 40550a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 40563705ce5bSJoe Perches 40573705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40583705ce5bSJoe Perches 40593705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 40603705ce5bSJoe Perches 40614a0df2efSAndy Whitcroft $off += length($elements[$n]); 40624a0df2efSAndy Whitcroft 406325985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4064773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4065773647a0SAndy Whitcroft my $cc = ''; 4066773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4067773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4068773647a0SAndy Whitcroft } 4069773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4070773647a0SAndy Whitcroft 40714a0df2efSAndy Whitcroft my $a = ''; 40724a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 40734a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4074cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 40754a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 40764a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4077773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 40784a0df2efSAndy Whitcroft 40790a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 40804a0df2efSAndy Whitcroft 40814a0df2efSAndy Whitcroft my $c = ''; 40820a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 40834a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 40844a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4085cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 40864a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 40874a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 40888b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 40894a0df2efSAndy Whitcroft } else { 40904a0df2efSAndy Whitcroft $c = 'E'; 40910a920b5bSAndy Whitcroft } 40920a920b5bSAndy Whitcroft 40934a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 40944a0df2efSAndy Whitcroft 40954a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 40964a0df2efSAndy Whitcroft 40976c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4098de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 40990a920b5bSAndy Whitcroft 410074048ed8SAndy Whitcroft # Pull out the value of this operator. 41016c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 41020a920b5bSAndy Whitcroft 41031f65f947SAndy Whitcroft # Get the full operator variant. 41041f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 41051f65f947SAndy Whitcroft 410613214adfSAndy Whitcroft # Ignore operators passed as parameters. 410713214adfSAndy Whitcroft if ($op_type ne 'V' && 4108d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 410913214adfSAndy Whitcroft 4110cf655043SAndy Whitcroft# # Ignore comments 4111cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 411213214adfSAndy Whitcroft 4113d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 411413214adfSAndy Whitcroft } elsif ($op eq ';') { 4115cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4116cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 41173705ce5bSJoe Perches if (ERROR("SPACING", 41183705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4119b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41203705ce5bSJoe Perches $line_fixed = 1; 41213705ce5bSJoe Perches } 4122d8aaf121SAndy Whitcroft } 4123d8aaf121SAndy Whitcroft 4124d8aaf121SAndy Whitcroft # // is a comment 4125d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 41260a920b5bSAndy Whitcroft 4127b00e4814SJoe Perches # : when part of a bitfield 4128b00e4814SJoe Perches } elsif ($opv eq ':B') { 4129b00e4814SJoe Perches # skip the bitfield test for now 4130b00e4814SJoe Perches 41311f65f947SAndy Whitcroft # No spaces for: 41321f65f947SAndy Whitcroft # -> 4133b00e4814SJoe Perches } elsif ($op eq '->') { 41344a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 41353705ce5bSJoe Perches if (ERROR("SPACING", 41363705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4137b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41383705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 41393705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 41403705ce5bSJoe Perches } 4141b34c648bSJoe Perches $line_fixed = 1; 41423705ce5bSJoe Perches } 41430a920b5bSAndy Whitcroft } 41440a920b5bSAndy Whitcroft 41452381097bSJoe Perches # , must not have a space before and must have a space on the right. 41460a920b5bSAndy Whitcroft } elsif ($op eq ',') { 41472381097bSJoe Perches my $rtrim_before = 0; 41482381097bSJoe Perches my $space_after = 0; 41492381097bSJoe Perches if ($ctx =~ /Wx./) { 41502381097bSJoe Perches if (ERROR("SPACING", 41512381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 41522381097bSJoe Perches $line_fixed = 1; 41532381097bSJoe Perches $rtrim_before = 1; 41542381097bSJoe Perches } 41552381097bSJoe Perches } 4156cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41573705ce5bSJoe Perches if (ERROR("SPACING", 41583705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 41593705ce5bSJoe Perches $line_fixed = 1; 4160b34c648bSJoe Perches $last_after = $n; 41612381097bSJoe Perches $space_after = 1; 41622381097bSJoe Perches } 41632381097bSJoe Perches } 41642381097bSJoe Perches if ($rtrim_before || $space_after) { 41652381097bSJoe Perches if ($rtrim_before) { 41662381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41672381097bSJoe Perches } else { 41682381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 41692381097bSJoe Perches } 41702381097bSJoe Perches if ($space_after) { 41712381097bSJoe Perches $good .= " "; 41723705ce5bSJoe Perches } 41730a920b5bSAndy Whitcroft } 41740a920b5bSAndy Whitcroft 41759c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 417674048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 41779c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 41789c0ca6f9SAndy Whitcroft 41799c0ca6f9SAndy Whitcroft # unary operators should have a space before and 41809c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 41819c0ca6f9SAndy Whitcroft # unary operator, or a cast 41829c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 418374048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 41840d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4185cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 41863705ce5bSJoe Perches if (ERROR("SPACING", 41873705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4188b34c648bSJoe Perches if ($n != $last_after + 2) { 4189b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 41903705ce5bSJoe Perches $line_fixed = 1; 41913705ce5bSJoe Perches } 41920a920b5bSAndy Whitcroft } 4193b34c648bSJoe Perches } 4194a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4195171ae1a4SAndy Whitcroft # A unary '*' may be const 4196171ae1a4SAndy Whitcroft 4197171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 41983705ce5bSJoe Perches if (ERROR("SPACING", 41993705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4200b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42013705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42023705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 42033705ce5bSJoe Perches } 4204b34c648bSJoe Perches $line_fixed = 1; 42053705ce5bSJoe Perches } 42060a920b5bSAndy Whitcroft } 42070a920b5bSAndy Whitcroft 42080a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 42090a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4210773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42113705ce5bSJoe Perches if (ERROR("SPACING", 42123705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4213b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42143705ce5bSJoe Perches $line_fixed = 1; 42153705ce5bSJoe Perches } 42160a920b5bSAndy Whitcroft } 4217773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4218773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42193705ce5bSJoe Perches if (ERROR("SPACING", 42203705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4221b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42223705ce5bSJoe Perches $line_fixed = 1; 42233705ce5bSJoe Perches } 4224653d4876SAndy Whitcroft } 4225773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 42263705ce5bSJoe Perches if (ERROR("SPACING", 42273705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4228b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42293705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42303705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4231773647a0SAndy Whitcroft } 4232b34c648bSJoe Perches $line_fixed = 1; 42333705ce5bSJoe Perches } 42343705ce5bSJoe Perches } 42350a920b5bSAndy Whitcroft 42360a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 42379c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 42389c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 42399c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4240c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4241c2fdda0dSAndy Whitcroft $op eq '%') 42420a920b5bSAndy Whitcroft { 4243d2e025f3SJoe Perches if ($check) { 4244d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4245d2e025f3SJoe Perches if (CHK("SPACING", 4246d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4247d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4248d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4249d2e025f3SJoe Perches $line_fixed = 1; 4250d2e025f3SJoe Perches } 4251d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4252d2e025f3SJoe Perches if (CHK("SPACING", 4253d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4254d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4255d2e025f3SJoe Perches $line_fixed = 1; 4256d2e025f3SJoe Perches } 4257d2e025f3SJoe Perches } 4258d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42593705ce5bSJoe Perches if (ERROR("SPACING", 42603705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4261b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4262b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4263b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4264b34c648bSJoe Perches } 42653705ce5bSJoe Perches $line_fixed = 1; 42663705ce5bSJoe Perches } 42670a920b5bSAndy Whitcroft } 42680a920b5bSAndy Whitcroft 42691f65f947SAndy Whitcroft # A colon needs no spaces before when it is 42701f65f947SAndy Whitcroft # terminating a case value or a label. 42711f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 42721f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 42733705ce5bSJoe Perches if (ERROR("SPACING", 42743705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4275b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42763705ce5bSJoe Perches $line_fixed = 1; 42773705ce5bSJoe Perches } 42781f65f947SAndy Whitcroft } 42791f65f947SAndy Whitcroft 42800a920b5bSAndy Whitcroft # All the others need spaces both sides. 4281cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 42821f65f947SAndy Whitcroft my $ok = 0; 42831f65f947SAndy Whitcroft 428422f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 42851f65f947SAndy Whitcroft if (($op eq '<' && 42861f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 42871f65f947SAndy Whitcroft ($op eq '>' && 42881f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 42891f65f947SAndy Whitcroft { 42901f65f947SAndy Whitcroft $ok = 1; 42911f65f947SAndy Whitcroft } 42921f65f947SAndy Whitcroft 4293e0df7e1fSJoe Perches # for asm volatile statements 4294e0df7e1fSJoe Perches # ignore a colon with another 4295e0df7e1fSJoe Perches # colon immediately before or after 4296e0df7e1fSJoe Perches if (($op eq ':') && 4297e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4298e0df7e1fSJoe Perches $ok = 1; 4299e0df7e1fSJoe Perches } 4300e0df7e1fSJoe Perches 430184731623SJoe Perches # messages are ERROR, but ?: are CHK 43021f65f947SAndy Whitcroft if ($ok == 0) { 430384731623SJoe Perches my $msg_type = \&ERROR; 430484731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 430584731623SJoe Perches 430684731623SJoe Perches if (&{$msg_type}("SPACING", 43073705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4308b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4309b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4310b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4311b34c648bSJoe Perches } 43123705ce5bSJoe Perches $line_fixed = 1; 43133705ce5bSJoe Perches } 43140a920b5bSAndy Whitcroft } 431522f2a2efSAndy Whitcroft } 43164a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 43173705ce5bSJoe Perches 43183705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 43193705ce5bSJoe Perches 43203705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 43210a920b5bSAndy Whitcroft } 43223705ce5bSJoe Perches 43233705ce5bSJoe Perches if (($#elements % 2) == 0) { 43243705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 43253705ce5bSJoe Perches } 43263705ce5bSJoe Perches 4327194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4328194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 43293705ce5bSJoe Perches } 43303705ce5bSJoe Perches 43313705ce5bSJoe Perches 43320a920b5bSAndy Whitcroft } 43330a920b5bSAndy Whitcroft 4334786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4335d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4336786b6326SJoe Perches if (WARN("SPACING", 4337786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4338786b6326SJoe Perches $fix) { 4339194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4340786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4341786b6326SJoe Perches } 4342786b6326SJoe Perches } 4343786b6326SJoe Perches 4344f0a594c1SAndy Whitcroft# check for multiple assignments 4345f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4346000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4347000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4348f0a594c1SAndy Whitcroft } 4349f0a594c1SAndy Whitcroft 435022f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 435122f2a2efSAndy Whitcroft## # continuation. 435222f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 435322f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 435422f2a2efSAndy Whitcroft## 435522f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 435622f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 435722f2a2efSAndy Whitcroft## my $ln = $line; 435822f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 435922f2a2efSAndy Whitcroft## } 436022f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4361000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4362000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 436322f2a2efSAndy Whitcroft## } 436422f2a2efSAndy Whitcroft## } 4365f0a594c1SAndy Whitcroft 43660a920b5bSAndy Whitcroft#need space before brace following if, while, etc 43676b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 43684e5d56bdSEddie Kovsky $line =~ /do\{/) { 43693705ce5bSJoe Perches if (ERROR("SPACING", 43703705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 43713705ce5bSJoe Perches $fix) { 4372194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; 43733705ce5bSJoe Perches } 4374de7d4f0eSAndy Whitcroft } 4375de7d4f0eSAndy Whitcroft 4376c4a62ef9SJoe Perches## # check for blank lines before declarations 4377c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4378c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4379c4a62ef9SJoe Perches## WARN("SPACING", 4380c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4381c4a62ef9SJoe Perches## } 4382c4a62ef9SJoe Perches## 4383c4a62ef9SJoe Perches 4384de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4385de7d4f0eSAndy Whitcroft# on the line 4386de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 4387d5e616fcSJoe Perches if (ERROR("SPACING", 4388d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4389d5e616fcSJoe Perches $fix) { 4390194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4391d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4392d5e616fcSJoe Perches } 43930a920b5bSAndy Whitcroft } 43940a920b5bSAndy Whitcroft 439522f2a2efSAndy Whitcroft# check spacing on square brackets 439622f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 43973705ce5bSJoe Perches if (ERROR("SPACING", 43983705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 43993705ce5bSJoe Perches $fix) { 4400194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44013705ce5bSJoe Perches s/\[\s+/\[/; 44023705ce5bSJoe Perches } 440322f2a2efSAndy Whitcroft } 440422f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 44053705ce5bSJoe Perches if (ERROR("SPACING", 44063705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 44073705ce5bSJoe Perches $fix) { 4408194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44093705ce5bSJoe Perches s/\s+\]/\]/; 44103705ce5bSJoe Perches } 441122f2a2efSAndy Whitcroft } 441222f2a2efSAndy Whitcroft 4413c45dcabdSAndy Whitcroft# check spacing on parentheses 44149c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 44159c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 44163705ce5bSJoe Perches if (ERROR("SPACING", 44173705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 44183705ce5bSJoe Perches $fix) { 4419194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44203705ce5bSJoe Perches s/\(\s+/\(/; 44213705ce5bSJoe Perches } 442222f2a2efSAndy Whitcroft } 442313214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4424c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4425c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 44263705ce5bSJoe Perches if (ERROR("SPACING", 44273705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44283705ce5bSJoe Perches $fix) { 4429194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44303705ce5bSJoe Perches s/\s+\)/\)/; 44313705ce5bSJoe Perches } 443222f2a2efSAndy Whitcroft } 443322f2a2efSAndy Whitcroft 4434e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4435e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4436e2826fd0SJoe Perches 4437e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4438ea4acbb1SJoe Perches my $var = $1; 4439ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4440ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4441ea4acbb1SJoe Perches $fix) { 4442ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4443ea4acbb1SJoe Perches } 4444ea4acbb1SJoe Perches } 4445ea4acbb1SJoe Perches 4446ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4447ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4448ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4449ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4450ea4acbb1SJoe Perches my $var = $2; 4451ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4452ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4453ea4acbb1SJoe Perches $fix) { 4454ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4455ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4456ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4457ea4acbb1SJoe Perches } 4458e2826fd0SJoe Perches } 4459e2826fd0SJoe Perches 44600a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 44614a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 44620a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 44633705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 44643705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 44653705ce5bSJoe Perches $fix) { 4466194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44673705ce5bSJoe Perches s/^(.)\s+/$1/; 44683705ce5bSJoe Perches } 44690a920b5bSAndy Whitcroft } 44700a920b5bSAndy Whitcroft 44715b9553abSJoe Perches# return is not a function 4472507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4473c45dcabdSAndy Whitcroft my $spacing = $1; 4474507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 44755b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 44765b9553abSJoe Perches my $value = $1; 44775b9553abSJoe Perches $value = deparenthesize($value); 44785b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4479000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4480000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 44815b9553abSJoe Perches } 4482c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4483000d1cc1SJoe Perches ERROR("SPACING", 4484000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4485c45dcabdSAndy Whitcroft } 4486c45dcabdSAndy Whitcroft } 4487507e5141SJoe Perches 4488b43ae21bSJoe Perches# unnecessary return in a void function 4489b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4490b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4491b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4492b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4493b43ae21bSJoe Perches $linenr >= 3 && 4494b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4495b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 44969819cf25SJoe Perches WARN("RETURN_VOID", 4497b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 44989819cf25SJoe Perches } 44999819cf25SJoe Perches 4500189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4501189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4502189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4503189248d8SJoe Perches my $openparens = $1; 4504189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4505189248d8SJoe Perches my $msg = ""; 4506189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4507189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4508189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4509189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4510189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4511189248d8SJoe Perches } 4512189248d8SJoe Perches } 4513189248d8SJoe Perches 4514c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4515c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4516c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4517c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4518c5595fa2SJoe Perches if ($^V && $^V ge 5.10.0 && 4519c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4520c5595fa2SJoe Perches my $lead = $1; 4521c5595fa2SJoe Perches my $const = $2; 4522c5595fa2SJoe Perches my $comp = $3; 4523c5595fa2SJoe Perches my $to = $4; 4524c5595fa2SJoe Perches my $newcomp = $comp; 4525f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4526c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4527c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4528c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4529c5595fa2SJoe Perches $fix) { 4530c5595fa2SJoe Perches if ($comp eq "<") { 4531c5595fa2SJoe Perches $newcomp = ">"; 4532c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4533c5595fa2SJoe Perches $newcomp = ">="; 4534c5595fa2SJoe Perches } elsif ($comp eq ">") { 4535c5595fa2SJoe Perches $newcomp = "<"; 4536c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4537c5595fa2SJoe Perches $newcomp = "<="; 4538c5595fa2SJoe Perches } 4539c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4540c5595fa2SJoe Perches } 4541c5595fa2SJoe Perches } 4542c5595fa2SJoe Perches 4543f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4544f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 454553a3c448SAndy Whitcroft my $name = $1; 454653a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4547000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4548f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 454953a3c448SAndy Whitcroft } 455053a3c448SAndy Whitcroft } 4551c45dcabdSAndy Whitcroft 45520a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 45534a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 45543705ce5bSJoe Perches if (ERROR("SPACING", 45553705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 45563705ce5bSJoe Perches $fix) { 4557194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45583705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 45593705ce5bSJoe Perches } 45600a920b5bSAndy Whitcroft } 45610a920b5bSAndy Whitcroft 4562f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4563f5fe35ddSAndy Whitcroft# statements after the conditional. 4564170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 45653e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 45663e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 45673e469cdcSAndy Whitcroft if (!defined $stat); 4568170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4569170d3a22SAndy Whitcroft $remain_next, $off_next); 4570170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4571170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4572170d3a22SAndy Whitcroft 4573170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4574170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4575170d3a22SAndy Whitcroft # then count those as offsets. 4576170d3a22SAndy Whitcroft my ($whitespace) = 4577170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4578170d3a22SAndy Whitcroft my $offset = 4579170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4580170d3a22SAndy Whitcroft 4581170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4582170d3a22SAndy Whitcroft $offset} = 1; 4583170d3a22SAndy Whitcroft } 4584170d3a22SAndy Whitcroft } 4585170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4586c11230f4SJoe Perches defined($stat) && defined($cond) && 4587170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4588171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 45898905a67cSAndy Whitcroft 4590b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4591000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4592000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 45938905a67cSAndy Whitcroft } 45948905a67cSAndy Whitcroft 45958905a67cSAndy Whitcroft # Find out what is on the end of the line after the 45968905a67cSAndy Whitcroft # conditional. 4597773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 45988905a67cSAndy Whitcroft $s =~ s/\n.*//g; 459913214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 460053210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 460153210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4602773647a0SAndy Whitcroft { 4603bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4604bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4605bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 460642bdf74cSHidetoshi Seto my $stat_real = ''; 4607bb44ad39SAndy Whitcroft 460842bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 460942bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4610bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4611bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4612bb44ad39SAndy Whitcroft } 4613bb44ad39SAndy Whitcroft 4614000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4615000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 46168905a67cSAndy Whitcroft } 46178905a67cSAndy Whitcroft } 46188905a67cSAndy Whitcroft 461913214adfSAndy Whitcroft# Check for bitwise tests written as boolean 462013214adfSAndy Whitcroft if ($line =~ / 462113214adfSAndy Whitcroft (?: 462213214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 462313214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 462413214adfSAndy Whitcroft (?:\&\&|\|\|) 462513214adfSAndy Whitcroft | 462613214adfSAndy Whitcroft (?:\&\&|\|\|) 462713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 462813214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 462913214adfSAndy Whitcroft )/x) 463013214adfSAndy Whitcroft { 4631000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4632000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 463313214adfSAndy Whitcroft } 463413214adfSAndy Whitcroft 46358905a67cSAndy Whitcroft# if and else should not have general statements after it 463613214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 463713214adfSAndy Whitcroft my $s = $1; 463813214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 463913214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4640000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4641000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 46420a920b5bSAndy Whitcroft } 464313214adfSAndy Whitcroft } 464439667782SAndy Whitcroft# if should not continue a brace 464539667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4646000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4647048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 464839667782SAndy Whitcroft $herecurr); 464939667782SAndy Whitcroft } 4650a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4651a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4652a1080bf8SAndy Whitcroft $line !~ /\G(?: 46533fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4654a1080bf8SAndy Whitcroft \s*return\s+ 4655a1080bf8SAndy Whitcroft )/xg) 4656a1080bf8SAndy Whitcroft { 4657000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4658000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4659a1080bf8SAndy Whitcroft } 46600a920b5bSAndy Whitcroft 46610a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 46620a920b5bSAndy Whitcroft # indent level to be relevant to each other. 46638b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 46640a920b5bSAndy Whitcroft $previndent == $indent) { 46658b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 46668b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 46678b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46688b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46698b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46708b8856f4SJoe Perches my $fixedline = $prevrawline; 46718b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 46728b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46738b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46748b8856f4SJoe Perches } 46758b8856f4SJoe Perches $fixedline = $rawline; 46768b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 46778b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46788b8856f4SJoe Perches } 46790a920b5bSAndy Whitcroft } 46800a920b5bSAndy Whitcroft 46818b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4682c2fdda0dSAndy Whitcroft $previndent == $indent) { 4683c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4684c2fdda0dSAndy Whitcroft 4685c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4686c2fdda0dSAndy Whitcroft # conditional. 4687773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4688c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4689c2fdda0dSAndy Whitcroft 4690c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 46918b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 46928b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 46938b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46948b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46958b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46968b8856f4SJoe Perches my $fixedline = $prevrawline; 46978b8856f4SJoe Perches my $trailing = $rawline; 46988b8856f4SJoe Perches $trailing =~ s/^\+//; 46998b8856f4SJoe Perches $trailing = trim($trailing); 47008b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 47018b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47028b8856f4SJoe Perches } 4703c2fdda0dSAndy Whitcroft } 4704c2fdda0dSAndy Whitcroft } 4705c2fdda0dSAndy Whitcroft 470695e2c602SJoe Perches#Specific variable tests 4707323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4708323c1260SJoe Perches my $var = $1; 470995e2c602SJoe Perches 471095e2c602SJoe Perches#gcc binary extension 471195e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4712d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4713d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4714d5e616fcSJoe Perches $fix) { 4715d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4716194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4717d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4718d5e616fcSJoe Perches } 471995e2c602SJoe Perches } 472095e2c602SJoe Perches 472195e2c602SJoe Perches#CamelCase 4722807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4723be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 472422735ce8SJoe Perches#Ignore Page<foo> variants 4725807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 472622735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4727f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4728f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4729f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47307e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 47317e781f67SJoe Perches my $word = $1; 47327e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4733d8b07710SJoe Perches if ($check) { 4734d8b07710SJoe Perches seed_camelcase_includes(); 4735d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4736d8b07710SJoe Perches seed_camelcase_file($realfile); 4737d8b07710SJoe Perches $camelcase_file_seeded = 1; 4738d8b07710SJoe Perches } 4739d8b07710SJoe Perches } 47407e781f67SJoe Perches if (!defined $camelcase{$word}) { 47417e781f67SJoe Perches $camelcase{$word} = 1; 4742be79794bSJoe Perches CHK("CAMELCASE", 47437e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 47447e781f67SJoe Perches } 4745323c1260SJoe Perches } 4746323c1260SJoe Perches } 47473445686aSJoe Perches } 47480a920b5bSAndy Whitcroft 47490a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4750d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4751d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4752d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4753d5e616fcSJoe Perches $fix) { 4754194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4755d5e616fcSJoe Perches } 47560a920b5bSAndy Whitcroft } 47570a920b5bSAndy Whitcroft 47580e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47590e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4760c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4761e09dec48SAndy Whitcroft my $file = "$1.h"; 4762e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4763e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4764e09dec48SAndy Whitcroft $realfile ne $checkfile && 47657840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4766c45dcabdSAndy Whitcroft { 47670e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 47680e212e0aSFabian Frederick if ($asminclude > 0) { 4769e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4770000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4771000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4772e09dec48SAndy Whitcroft } else { 4773000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4774000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4775e09dec48SAndy Whitcroft } 47760a920b5bSAndy Whitcroft } 47770a920b5bSAndy Whitcroft } 47780e212e0aSFabian Frederick } 47790a920b5bSAndy Whitcroft 4780653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4781653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4782cf655043SAndy Whitcroft# in a known good container 4783b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4784b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4785d8aaf121SAndy Whitcroft my $ln = $linenr; 4786d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4787c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4788c45dcabdSAndy Whitcroft my $ctx = ''; 478908a2843eSJoe Perches my $has_flow_statement = 0; 479008a2843eSJoe Perches my $has_arg_concat = 0; 4791c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4792f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4793f74bd194SAndy Whitcroft $ctx = $dstat; 4794c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4795a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4796c45dcabdSAndy Whitcroft 479708a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 479862e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 479908a2843eSJoe Perches 4800f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 4801f59b64bfSJoe Perches my $define_args = $1; 4802f59b64bfSJoe Perches my $define_stmt = $dstat; 4803f59b64bfSJoe Perches my @def_args = (); 4804f59b64bfSJoe Perches 4805f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 4806f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 4807f59b64bfSJoe Perches $define_args =~ s/\s*//g; 4808f59b64bfSJoe Perches @def_args = split(",", $define_args); 4809f59b64bfSJoe Perches } 4810f59b64bfSJoe Perches 4811292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4812c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4813c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4814c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4815c45dcabdSAndy Whitcroft 4816c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4817bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4818bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 48196b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 4820bf30d6edSAndy Whitcroft { 4821c45dcabdSAndy Whitcroft } 4822c45dcabdSAndy Whitcroft 4823e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 482433acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 482533acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 4826e45bab8eSAndy Whitcroft { 4827e45bab8eSAndy Whitcroft } 4828e45bab8eSAndy Whitcroft 482942e15293SJoe Perches # Make asm volatile uses seem like a generic function 483042e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 483142e15293SJoe Perches 4832c45dcabdSAndy Whitcroft my $exceptions = qr{ 4833c45dcabdSAndy Whitcroft $Declare| 4834c45dcabdSAndy Whitcroft module_param_named| 4835a0a0a7a9SKees Cook MODULE_PARM_DESC| 4836c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4837c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4838383099fdSAndy Whitcroft __typeof__\(| 483922fd2d3eSStefani Seibold union| 484022fd2d3eSStefani Seibold struct| 4841ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 48426b10df42SVladimir Zapolskiy ^\"|\"$| 48436b10df42SVladimir Zapolskiy ^\[ 4844c45dcabdSAndy Whitcroft }x; 48455eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4846f59b64bfSJoe Perches 4847f59b64bfSJoe Perches $ctx =~ s/\n*$//; 4848f59b64bfSJoe Perches my $herectx = $here . "\n"; 4849f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 4850f59b64bfSJoe Perches 4851f59b64bfSJoe Perches for (my $n = 0; $n < $stmt_cnt; $n++) { 4852f59b64bfSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4853f59b64bfSJoe Perches } 4854f59b64bfSJoe Perches 4855f74bd194SAndy Whitcroft if ($dstat ne '' && 4856f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4857f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48583cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4859356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4860f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4861f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4862e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 486372f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4864f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4865f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4866f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 48674e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 4868f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4869c45dcabdSAndy Whitcroft { 4870e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 4871e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4872e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 4873e795556aSJoe Perches } elsif ($dstat =~ /;/) { 4874f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4875f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4876f74bd194SAndy Whitcroft } else { 4877000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4878388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4879d8aaf121SAndy Whitcroft } 4880f59b64bfSJoe Perches 4881f59b64bfSJoe Perches } 48825207649bSJoe Perches 48835207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 48845207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 48855207649bSJoe Perches my $first = 1; 48865207649bSJoe Perches $define_stmt = ""; 48875207649bSJoe Perches foreach my $l (@stmt_array) { 48885207649bSJoe Perches $l =~ s/\\$//; 48895207649bSJoe Perches if ($first) { 48905207649bSJoe Perches $define_stmt = $l; 48915207649bSJoe Perches $first = 0; 48925207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 48935207649bSJoe Perches $define_stmt .= substr($l, 1); 48945207649bSJoe Perches } 48955207649bSJoe Perches } 48965207649bSJoe Perches $define_stmt =~ s/$;//g; 48975207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 48985207649bSJoe Perches $define_stmt = trim($define_stmt); 48995207649bSJoe Perches 4900f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 4901f59b64bfSJoe Perches foreach my $arg (@def_args) { 4902f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 49039192d41aSJoe Perches next if ($arg =~ /^type$/i); 4904f59b64bfSJoe Perches my $tmp = $define_stmt; 4905f59b64bfSJoe Perches $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49065207649bSJoe Perches $tmp =~ s/\#+\s*$arg\b//g; 4907f59b64bfSJoe Perches $tmp =~ s/\b$arg\s*\#\#//g; 4908f59b64bfSJoe Perches my $use_cnt = $tmp =~ s/\b$arg\b//g; 4909f59b64bfSJoe Perches if ($use_cnt > 1) { 4910f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 4911f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 4912f59b64bfSJoe Perches } 49139192d41aSJoe Perches# check if any macro arguments may have other precedence issues 49149192d41aSJoe Perches if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49159192d41aSJoe Perches ((defined($1) && $1 ne ',') || 49169192d41aSJoe Perches (defined($2) && $2 ne ','))) { 49179192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 49189192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49199192d41aSJoe Perches } 49200a920b5bSAndy Whitcroft } 49215023d347SJoe Perches 492208a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 492308a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 492408a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 492508a2843eSJoe Perches my $herectx = $here . "\n"; 492608a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 492708a2843eSJoe Perches 492808a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 492908a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 493008a2843eSJoe Perches } 493108a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 493208a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 493308a2843eSJoe Perches } 493408a2843eSJoe Perches 4935481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 49365023d347SJoe Perches 49375023d347SJoe Perches } else { 49385023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4939481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4940481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 49415023d347SJoe Perches $line =~ /^\+.*\\$/) { 49425023d347SJoe Perches WARN("LINE_CONTINUATIONS", 49435023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 49445023d347SJoe Perches } 4945653d4876SAndy Whitcroft } 49460a920b5bSAndy Whitcroft 4947b13edf7fSJoe Perches# do {} while (0) macro tests: 4948b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4949b13edf7fSJoe Perches# macro should not end with a semicolon 4950b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4951b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4952b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4953b13edf7fSJoe Perches my $ln = $linenr; 4954b13edf7fSJoe Perches my $cnt = $realcnt; 4955b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4956b13edf7fSJoe Perches my $ctx = ''; 4957b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4958b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4959b13edf7fSJoe Perches $ctx = $dstat; 4960b13edf7fSJoe Perches 4961b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 49621b36b201SJoe Perches $dstat =~ s/$;/ /g; 4963b13edf7fSJoe Perches 4964b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4965b13edf7fSJoe Perches my $stmts = $2; 4966b13edf7fSJoe Perches my $semis = $3; 4967b13edf7fSJoe Perches 4968b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4969b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4970b13edf7fSJoe Perches my $herectx = $here . "\n"; 4971b13edf7fSJoe Perches 4972b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4973b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4974b13edf7fSJoe Perches } 4975b13edf7fSJoe Perches 4976ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4977ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4978b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4979b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4980b13edf7fSJoe Perches } 4981b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4982b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4983b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 4984b13edf7fSJoe Perches } 4985f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 4986f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 4987f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 4988f5ef95b1SJoe Perches my $herectx = $here . "\n"; 4989f5ef95b1SJoe Perches 4990f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4991f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4992f5ef95b1SJoe Perches } 4993f5ef95b1SJoe Perches 4994f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 4995f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 4996b13edf7fSJoe Perches } 4997b13edf7fSJoe Perches } 4998b13edf7fSJoe Perches 4999080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5000080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 5001080ba929SMike Frysinger# . 5002080ba929SMike Frysinger# ALIGN(...) 5003080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 5004080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5005000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 5006000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5007080ba929SMike Frysinger } 5008080ba929SMike Frysinger 5009f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 501013214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 501113214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5012cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 501313214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5014cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5015cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5016aad4f614SJoe Perches my @allowed = (); 5017aad4f614SJoe Perches my $allow = 0; 501813214adfSAndy Whitcroft my $seen = 0; 5019773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5020cf655043SAndy Whitcroft my $ln = $linenr - 1; 502113214adfSAndy Whitcroft for my $chunk (@chunks) { 502213214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 502313214adfSAndy Whitcroft 5024773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5025773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5026773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5027773647a0SAndy Whitcroft 5028aad4f614SJoe Perches $allowed[$allow] = 0; 5029773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5030773647a0SAndy Whitcroft 5031773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5032773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5033773647a0SAndy Whitcroft 5034773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5035cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5036cf655043SAndy Whitcroft 5037773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 503813214adfSAndy Whitcroft 503913214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 504013214adfSAndy Whitcroft 5041aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5042cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5043cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5044aad4f614SJoe Perches $allowed[$allow] = 1; 504513214adfSAndy Whitcroft } 504613214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5047cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5048aad4f614SJoe Perches $allowed[$allow] = 1; 504913214adfSAndy Whitcroft } 5050cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5051cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5052aad4f614SJoe Perches $allowed[$allow] = 1; 505313214adfSAndy Whitcroft } 5054aad4f614SJoe Perches $allow++; 505513214adfSAndy Whitcroft } 5056aad4f614SJoe Perches if ($seen) { 5057aad4f614SJoe Perches my $sum_allowed = 0; 5058aad4f614SJoe Perches foreach (@allowed) { 5059aad4f614SJoe Perches $sum_allowed += $_; 5060aad4f614SJoe Perches } 5061aad4f614SJoe Perches if ($sum_allowed == 0) { 5062000d1cc1SJoe Perches WARN("BRACES", 5063000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5064aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5065aad4f614SJoe Perches $seen != $allow) { 5066aad4f614SJoe Perches CHK("BRACES", 5067aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5068aad4f614SJoe Perches } 506913214adfSAndy Whitcroft } 507013214adfSAndy Whitcroft } 507113214adfSAndy Whitcroft } 5072773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 507313214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5074cf655043SAndy Whitcroft my $allowed = 0; 5075f0a594c1SAndy Whitcroft 5076cf655043SAndy Whitcroft # Check the pre-context. 5077cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5078cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5079cf655043SAndy Whitcroft $allowed = 1; 5080f0a594c1SAndy Whitcroft } 5081773647a0SAndy Whitcroft 5082773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5083773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5084773647a0SAndy Whitcroft 5085cf655043SAndy Whitcroft # Check the condition. 5086cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5087773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5088cf655043SAndy Whitcroft if (defined $cond) { 5089773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5090cf655043SAndy Whitcroft } 5091cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5092cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5093cf655043SAndy Whitcroft $allowed = 1; 5094cf655043SAndy Whitcroft } 5095cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5096cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5097cf655043SAndy Whitcroft $allowed = 1; 5098cf655043SAndy Whitcroft } 5099cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5100cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5101cf655043SAndy Whitcroft $allowed = 1; 5102cf655043SAndy Whitcroft } 5103cf655043SAndy Whitcroft # Check the post-context. 5104cf655043SAndy Whitcroft if (defined $chunks[1]) { 5105cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5106cf655043SAndy Whitcroft if (defined $cond) { 5107773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5108cf655043SAndy Whitcroft } 5109cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5110cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5111cf655043SAndy Whitcroft $allowed = 1; 5112cf655043SAndy Whitcroft } 5113cf655043SAndy Whitcroft } 5114cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 511569932487SJustin P. Mattock my $herectx = $here . "\n"; 5116f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5117cf655043SAndy Whitcroft 5118f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 511969932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 5120cf655043SAndy Whitcroft } 5121cf655043SAndy Whitcroft 5122000d1cc1SJoe Perches WARN("BRACES", 5123000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5124f0a594c1SAndy Whitcroft } 5125f0a594c1SAndy Whitcroft } 5126f0a594c1SAndy Whitcroft 5127e4c5babdSJoe Perches# check for single line unbalanced braces 512895330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 512995330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5130e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5131e4c5babdSJoe Perches } 5132e4c5babdSJoe Perches 51330979ae66SJoe Perches# check for unnecessary blank lines around braces 513477b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5135f8e58219SJoe Perches if (CHK("BRACES", 5136f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5137f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5138f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5139f8e58219SJoe Perches } 51400979ae66SJoe Perches } 514177b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5142f8e58219SJoe Perches if (CHK("BRACES", 5143f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5144f8e58219SJoe Perches $fix) { 5145f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5146f8e58219SJoe Perches } 51470979ae66SJoe Perches } 51480979ae66SJoe Perches 51494a0df2efSAndy Whitcroft# no volatiles please 51506c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 51516c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5152000d1cc1SJoe Perches WARN("VOLATILE", 51538c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51544a0df2efSAndy Whitcroft } 51554a0df2efSAndy Whitcroft 51565e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 51575e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 51585e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51595e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 516033acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 51615e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 51625e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 51635e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 51645e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 51655e4f6ba5SJoe Perches $fix && 51665e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 51675e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 51685e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 51695e4f6ba5SJoe Perches my $comma_close = ""; 51705e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 51715e4f6ba5SJoe Perches $comma_close = $1; 51725e4f6ba5SJoe Perches } 51735e4f6ba5SJoe Perches 51745e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51755e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 51765e4f6ba5SJoe Perches my $fixedline = $prevrawline; 51775e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 51785e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 51795e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 51805e4f6ba5SJoe Perches $fixedline = $rawline; 51815e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 51825e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 51835e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51845e4f6ba5SJoe Perches } 51855e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 51865e4f6ba5SJoe Perches } 51875e4f6ba5SJoe Perches } 51885e4f6ba5SJoe Perches 51895e4f6ba5SJoe Perches# check for missing a space in a string concatenation 51905e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 51915e4f6ba5SJoe Perches WARN('MISSING_SPACE', 51925e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 51935e4f6ba5SJoe Perches } 51945e4f6ba5SJoe Perches 519577cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5196e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5197e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5198e4b7d309SJoe Perches# function declarations 519977cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 520077cb8546SJoe Perches defined($context_function) && 5201e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5202e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 520377cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5204e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 520577cb8546SJoe Perches } 520677cb8546SJoe Perches 52075e4f6ba5SJoe Perches# check for spaces before a quoted newline 52085e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 52095e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52105e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52115e4f6ba5SJoe Perches $fix) { 52125e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52135e4f6ba5SJoe Perches } 52145e4f6ba5SJoe Perches 52155e4f6ba5SJoe Perches } 52165e4f6ba5SJoe Perches 5217f17dba4fSJoe Perches# concatenated string without spaces between elements 521833acb54aSJoe Perches if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5219f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 5220f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 5221f17dba4fSJoe Perches } 5222f17dba4fSJoe Perches 522390ad30e5SJoe Perches# uncoalesced string fragments 522433acb54aSJoe Perches if ($line =~ /$String\s*"/) { 522590ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 522690ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 522790ad30e5SJoe Perches } 522890ad30e5SJoe Perches 5229522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5230522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5231522b837cSAlexey Dobriyan my $show_Z = 1; 52325e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5233522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52345e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5235522b837cSAlexey Dobriyan # check for %L 5236522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52375e4f6ba5SJoe Perches WARN("PRINTF_L", 5238522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5239522b837cSAlexey Dobriyan $show_L = 0; 52405e4f6ba5SJoe Perches } 5241522b837cSAlexey Dobriyan # check for %Z 5242522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5243522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5244522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5245522b837cSAlexey Dobriyan $show_Z = 0; 5246522b837cSAlexey Dobriyan } 5247522b837cSAlexey Dobriyan # check for 0x<decimal> 5248522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5249522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 52506e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 52516e300757SJoe Perches } 52525e4f6ba5SJoe Perches } 52535e4f6ba5SJoe Perches 52545e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 52555e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52565e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 52575e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 52585e4f6ba5SJoe Perches } 52595e4f6ba5SJoe Perches 526000df344fSAndy Whitcroft# warn about #if 0 5261c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5262000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 5263000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 5264de7d4f0eSAndy Whitcroft $herecurr); 52654a0df2efSAndy Whitcroft } 52664a0df2efSAndy Whitcroft 526703df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 526803df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5269100425deSJoe Perches my $tested = quotemeta($1); 5270100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5271100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5272100425deSJoe Perches my $func = $1; 5273100425deSJoe Perches if (WARN('NEEDLESS_IF', 5274100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5275100425deSJoe Perches $fix) { 5276100425deSJoe Perches my $do_fix = 1; 5277100425deSJoe Perches my $leading_tabs = ""; 5278100425deSJoe Perches my $new_leading_tabs = ""; 5279100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5280100425deSJoe Perches $leading_tabs = $1; 5281100425deSJoe Perches } else { 5282100425deSJoe Perches $do_fix = 0; 5283100425deSJoe Perches } 5284100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5285100425deSJoe Perches $new_leading_tabs = $1; 5286100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5287100425deSJoe Perches $do_fix = 0; 5288100425deSJoe Perches } 5289100425deSJoe Perches } else { 5290100425deSJoe Perches $do_fix = 0; 5291100425deSJoe Perches } 5292100425deSJoe Perches if ($do_fix) { 5293100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5294100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5295100425deSJoe Perches } 5296100425deSJoe Perches } 52974c432a8fSGreg Kroah-Hartman } 52984c432a8fSGreg Kroah-Hartman } 5299f0a594c1SAndy Whitcroft 5300ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5301ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5302ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5303ebfdc409SJoe Perches (defined $1 || defined $3) && 5304ebfdc409SJoe Perches $linenr > 3) { 5305ebfdc409SJoe Perches my $testval = $2; 5306ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5307ebfdc409SJoe Perches 5308ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5309ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5310ebfdc409SJoe Perches 5311ebfdc409SJoe Perches if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) { 5312ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5313ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5314ebfdc409SJoe Perches } 5315ebfdc409SJoe Perches } 5316ebfdc409SJoe Perches 5317f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5318dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5319f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5320f78d98f6SJoe Perches my $level = $1; 5321f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5322f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5323f78d98f6SJoe Perches $fix) { 5324f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5325f78d98f6SJoe Perches } 5326f78d98f6SJoe Perches } 5327f78d98f6SJoe Perches 532845c55e92SJoe Perches# check for logging continuations 532945c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 533045c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 533145c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 533245c55e92SJoe Perches } 533345c55e92SJoe Perches 5334abb08a53SJoe Perches# check for mask then right shift without a parentheses 5335abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 5336abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5337abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5338abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5339abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5340abb08a53SJoe Perches } 5341abb08a53SJoe Perches 5342b75ac618SJoe Perches# check for pointer comparisons to NULL 5343b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 5344b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5345b75ac618SJoe Perches my $val = $1; 5346b75ac618SJoe Perches my $equal = "!"; 5347b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5348b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5349b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5350b75ac618SJoe Perches $fix) { 5351b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5352b75ac618SJoe Perches } 5353b75ac618SJoe Perches } 5354b75ac618SJoe Perches } 5355b75ac618SJoe Perches 53568716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 53578716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 53588716de38SJoe Perches my $attr = $1; 53598716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 53608716de38SJoe Perches my $ptr = $1; 53618716de38SJoe Perches my $var = $2; 53628716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 53638716de38SJoe Perches ERROR("MISPLACED_INIT", 53648716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 53658716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 53668716de38SJoe Perches WARN("MISPLACED_INIT", 53678716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 53688716de38SJoe Perches $fix) { 5369194f66fcSJoe 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; 53708716de38SJoe Perches } 53718716de38SJoe Perches } 53728716de38SJoe Perches } 53738716de38SJoe Perches 5374e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5375e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5376e970b884SJoe Perches my $attr = $1; 5377e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5378e970b884SJoe Perches my $attr_prefix = $1; 5379e970b884SJoe Perches my $attr_type = $2; 5380e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5381e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5382e970b884SJoe Perches $fix) { 5383194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5384e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5385e970b884SJoe Perches } 5386e970b884SJoe Perches } 5387e970b884SJoe Perches 5388e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5389e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5390e970b884SJoe Perches my $attr = $1; 5391e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5392e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5393e970b884SJoe Perches $fix) { 5394194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5395e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5396e970b884SJoe Perches $lead = rtrim($1); 5397e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5398e970b884SJoe Perches $lead = "${lead}const "; 5399194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5400e970b884SJoe Perches } 5401e970b884SJoe Perches } 5402e970b884SJoe Perches 5403c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5404c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5405c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5406c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5407c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5408c17893c7SJoe Perches $fix) { 5409c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5410c17893c7SJoe Perches } 5411c17893c7SJoe Perches } 5412c17893c7SJoe Perches 5413fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5414fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5415fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5416fbdb8138SJoe Perches my $constant_func = $1; 5417fbdb8138SJoe Perches my $func = $constant_func; 5418fbdb8138SJoe Perches $func =~ s/^__constant_//; 5419fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5420fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5421fbdb8138SJoe Perches $fix) { 5422194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5423fbdb8138SJoe Perches } 5424fbdb8138SJoe Perches } 5425fbdb8138SJoe Perches 54261a15a250SPatrick Pannuto# prefer usleep_range over udelay 542737581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 542843c1d77cSJoe Perches my $delay = $1; 54291a15a250SPatrick Pannuto # ignore udelay's < 10, however 543043c1d77cSJoe Perches if (! ($delay < 10) ) { 5431000d1cc1SJoe Perches CHK("USLEEP_RANGE", 543243c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 543343c1d77cSJoe Perches } 543443c1d77cSJoe Perches if ($delay > 2000) { 543543c1d77cSJoe Perches WARN("LONG_UDELAY", 543643c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 54371a15a250SPatrick Pannuto } 54381a15a250SPatrick Pannuto } 54391a15a250SPatrick Pannuto 544009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 544109ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 544209ef8725SPatrick Pannuto if ($1 < 20) { 5443000d1cc1SJoe Perches WARN("MSLEEP", 544443c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 544509ef8725SPatrick Pannuto } 544609ef8725SPatrick Pannuto } 544709ef8725SPatrick Pannuto 544836ec1939SJoe Perches# check for comparisons of jiffies 544936ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 545036ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 545136ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 545236ec1939SJoe Perches } 545336ec1939SJoe Perches 54549d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 54559d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54569d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 54579d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54589d7a34a5SJoe Perches } 54599d7a34a5SJoe Perches 546000df344fSAndy Whitcroft# warn about #ifdefs in C files 5461c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 546200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 546300df344fSAndy Whitcroft# print "$herecurr"; 546400df344fSAndy Whitcroft# $clean = 0; 546500df344fSAndy Whitcroft# } 546600df344fSAndy Whitcroft 546722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5468c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 54693705ce5bSJoe Perches if (ERROR("SPACING", 54703705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 54713705ce5bSJoe Perches $fix) { 5472194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54733705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 54743705ce5bSJoe Perches } 54753705ce5bSJoe Perches 547622f2a2efSAndy Whitcroft } 547722f2a2efSAndy Whitcroft 54784a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5479171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5480171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 54814a0df2efSAndy Whitcroft my $which = $1; 54824a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5483000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5484000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 54854a0df2efSAndy Whitcroft } 54864a0df2efSAndy Whitcroft } 54874a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5488402c2553SMichael S. Tsirkin 5489402c2553SMichael S. Tsirkin my $barriers = qr{ 5490402c2553SMichael S. Tsirkin mb| 5491402c2553SMichael S. Tsirkin rmb| 5492402c2553SMichael S. Tsirkin wmb| 5493402c2553SMichael S. Tsirkin read_barrier_depends 5494402c2553SMichael S. Tsirkin }x; 5495402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5496402c2553SMichael S. Tsirkin mb__before_atomic| 5497402c2553SMichael S. Tsirkin mb__after_atomic| 5498402c2553SMichael S. Tsirkin store_release| 5499402c2553SMichael S. Tsirkin load_acquire| 5500402c2553SMichael S. Tsirkin store_mb| 5501402c2553SMichael S. Tsirkin (?:$barriers) 5502402c2553SMichael S. Tsirkin }x; 5503402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5504402c2553SMichael S. Tsirkin (?:$barriers)| 550543e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 550643e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5507402c2553SMichael S. Tsirkin }x; 5508402c2553SMichael S. Tsirkin 5509402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 55104a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5511c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5512000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 55134a0df2efSAndy Whitcroft } 55144a0df2efSAndy Whitcroft } 55153ad81779SPaul E. McKenney 5516f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5517f4073b0fSMichael S. Tsirkin 5518f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5519f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5520f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5521f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5522f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5523f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5524f4073b0fSMichael S. Tsirkin } 5525f4073b0fSMichael S. Tsirkin 5526cb426e99SJoe Perches# check for waitqueue_active without a comment. 5527cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5528cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5529cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5530cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5531cb426e99SJoe Perches } 5532cb426e99SJoe Perches } 55333ad81779SPaul E. McKenney 55343ad81779SPaul E. McKenney# Check for expedited grace periods that interrupt non-idle non-nohz 55353ad81779SPaul E. McKenney# online CPUs. These expedited can therefore degrade real-time response 55363ad81779SPaul E. McKenney# if used carelessly, and should be avoided where not absolutely 55373ad81779SPaul E. McKenney# needed. It is always OK to use synchronize_rcu_expedited() and 55383ad81779SPaul E. McKenney# synchronize_sched_expedited() at boot time (before real-time applications 55393ad81779SPaul E. McKenney# start) and in error situations where real-time response is compromised in 55403ad81779SPaul E. McKenney# any case. Note that synchronize_srcu_expedited() does -not- interrupt 55413ad81779SPaul E. McKenney# other CPUs, so don't warn on uses of synchronize_srcu_expedited(). 55423ad81779SPaul E. McKenney# Of course, nothing comes for free, and srcu_read_lock() and 55433ad81779SPaul E. McKenney# srcu_read_unlock() do contain full memory barriers in payment for 55443ad81779SPaul E. McKenney# synchronize_srcu_expedited() non-interruption properties. 55453ad81779SPaul E. McKenney if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) { 55463ad81779SPaul E. McKenney WARN("EXPEDITED_RCU_GRACE_PERIOD", 55473ad81779SPaul E. McKenney "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr); 55483ad81779SPaul E. McKenney 55493ad81779SPaul E. McKenney } 55503ad81779SPaul E. McKenney 55514a0df2efSAndy Whitcroft# check of hardware specific defines 5552c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5553000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5554000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 55550a920b5bSAndy Whitcroft } 5556653d4876SAndy Whitcroft 5557d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 5558d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 5559000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5560000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 5561d4977c78STobias Klauser } 5562d4977c78STobias Klauser 5563de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5564de7d4f0eSAndy Whitcroft# storage class and type. 55659c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 55669c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5567000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5568000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5569de7d4f0eSAndy Whitcroft } 5570de7d4f0eSAndy Whitcroft 55718905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 55722b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55732b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5574d5e616fcSJoe Perches if (WARN("INLINE", 5575d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5576d5e616fcSJoe Perches $fix) { 5577194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5578d5e616fcSJoe Perches 5579d5e616fcSJoe Perches } 55808905a67cSAndy Whitcroft } 55818905a67cSAndy Whitcroft 55823d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 55832b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55842b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5585000d1cc1SJoe Perches WARN("PREFER_PACKED", 5586000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 55873d130fd0SJoe Perches } 55883d130fd0SJoe Perches 558939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 55902b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55912b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5592000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5593000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 559439b7e287SJoe Perches } 559539b7e287SJoe Perches 55965f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 55972b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55982b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5599d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5600d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5601d5e616fcSJoe Perches $fix) { 5602194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5603d5e616fcSJoe Perches 5604d5e616fcSJoe Perches } 56055f14d3bdSJoe Perches } 56065f14d3bdSJoe Perches 56076061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 56082b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 56092b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5610d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5611d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5612d5e616fcSJoe Perches $fix) { 5613194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5614d5e616fcSJoe Perches } 56156061d949SJoe Perches } 56166061d949SJoe Perches 5617619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 5618619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 5619619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5620619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5621619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5622619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5623619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5624619a908aSJoe Perches } 5625619a908aSJoe Perches 5626fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5627e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5628fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5629e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5630e6176fa4SJoe Perches my $type = $1; 5631e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5632e6176fa4SJoe Perches $type = $1; 5633e6176fa4SJoe Perches my $kernel_type = 'u'; 5634e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5635e6176fa4SJoe Perches $type =~ /(\d+)/; 5636e6176fa4SJoe Perches $kernel_type .= $1; 5637e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5638e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5639e6176fa4SJoe Perches $fix) { 5640e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5641e6176fa4SJoe Perches } 5642e6176fa4SJoe Perches } 5643e6176fa4SJoe Perches } 5644e6176fa4SJoe Perches 5645938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5646938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5647938224b5SJoe Perches my $cast = $1; 5648938224b5SJoe Perches my $const = $2; 5649938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5650938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5651938224b5SJoe Perches $fix) { 5652938224b5SJoe Perches my $suffix = ""; 5653938224b5SJoe Perches my $newconst = $const; 5654938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5655938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5656938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5657938224b5SJoe Perches $suffix .= 'LL'; 5658938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5659938224b5SJoe Perches $suffix .= 'L'; 5660938224b5SJoe Perches } 5661938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5662938224b5SJoe Perches } 5663938224b5SJoe Perches } 5664938224b5SJoe Perches 56658f53a9b8SJoe Perches# check for sizeof(&) 56668f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5667000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5668000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 56698f53a9b8SJoe Perches } 56708f53a9b8SJoe Perches 567166c80b60SJoe Perches# check for sizeof without parenthesis 567266c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5673d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5674d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5675d5e616fcSJoe Perches $fix) { 5676194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5677d5e616fcSJoe Perches } 567866c80b60SJoe Perches } 567966c80b60SJoe Perches 568088982feaSJoe Perches# check for struct spinlock declarations 568188982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 568288982feaSJoe Perches WARN("USE_SPINLOCK_T", 568388982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 568488982feaSJoe Perches } 568588982feaSJoe Perches 5686a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 568706668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5688a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5689caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5690caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5691d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5692d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5693d5e616fcSJoe Perches $fix) { 5694194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5695d5e616fcSJoe Perches } 5696a6962d72SJoe Perches } 5697a6962d72SJoe Perches } 5698a6962d72SJoe Perches 56990b523769SJoe Perches # check for vsprintf extension %p<foo> misuses 57000b523769SJoe Perches if ($^V && $^V ge 5.10.0 && 57010b523769SJoe Perches defined $stat && 57020b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 57030b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 57040b523769SJoe Perches my $bad_extension = ""; 57050b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 57060b523769SJoe Perches $lc = $lc + $linenr; 57070b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 57080b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 57090b523769SJoe Perches $fmt =~ s/%%//g; 57100b523769SJoe Perches if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) { 57110b523769SJoe Perches $bad_extension = $1; 57120b523769SJoe Perches last; 57130b523769SJoe Perches } 57140b523769SJoe Perches } 57150b523769SJoe Perches if ($bad_extension ne "") { 57160b523769SJoe Perches my $stat_real = raw_line($linenr, 0); 57170b523769SJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 57180b523769SJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 57190b523769SJoe Perches } 57200b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 57210b523769SJoe Perches "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57220b523769SJoe Perches } 57230b523769SJoe Perches } 57240b523769SJoe Perches 5725554e165cSAndy Whitcroft# Check for misused memsets 5726d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5727d1fe9c09SJoe Perches defined $stat && 57289e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5729554e165cSAndy Whitcroft 5730d7c76ba7SJoe Perches my $ms_addr = $2; 5731d1fe9c09SJoe Perches my $ms_val = $7; 5732d1fe9c09SJoe Perches my $ms_size = $12; 5733d7c76ba7SJoe Perches 5734554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5735554e165cSAndy Whitcroft ERROR("MEMSET", 5736d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5737554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5738554e165cSAndy Whitcroft WARN("MEMSET", 5739d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5740d7c76ba7SJoe Perches } 5741d7c76ba7SJoe Perches } 5742d7c76ba7SJoe Perches 574398a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5744f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5745f333195dSJoe Perches# defined $stat && 5746f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5747f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 5748f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 5749f333195dSJoe Perches# $fix) { 5750f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 5751f333195dSJoe Perches# } 5752f333195dSJoe Perches# } 575398a9bba5SJoe Perches 5754b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5755f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5756f333195dSJoe Perches# defined $stat && 5757f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5758f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 5759f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 5760f333195dSJoe Perches# } 5761b6117d17SMateusz Kulikowski 57628617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 57638617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5764f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5765f333195dSJoe Perches# defined $stat && 5766f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5767f333195dSJoe Perches# 5768f333195dSJoe Perches# my $ms_val = $7; 5769f333195dSJoe Perches# 5770f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 5771f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 5772f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 5773f333195dSJoe Perches# $fix) { 5774f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 5775f333195dSJoe Perches# } 5776f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 5777f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 5778f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 5779f333195dSJoe Perches# $fix) { 5780f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 5781f333195dSJoe Perches# } 5782f333195dSJoe Perches# } 5783f333195dSJoe Perches# } 57848617cd09SMateusz Kulikowski 5785d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5786d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5787d1fe9c09SJoe Perches defined $stat && 5788d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5789d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5790d7c76ba7SJoe Perches my $call = $1; 5791d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5792d7c76ba7SJoe Perches my $arg1 = $3; 5793d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5794d1fe9c09SJoe Perches my $arg2 = $8; 5795d7c76ba7SJoe Perches my $cast; 5796d7c76ba7SJoe Perches 5797d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5798d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5799d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5800d7c76ba7SJoe Perches $cast = $cast1; 5801d7c76ba7SJoe Perches } else { 5802d7c76ba7SJoe Perches $cast = $cast2; 5803d7c76ba7SJoe Perches } 5804d7c76ba7SJoe Perches WARN("MINMAX", 5805d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5806554e165cSAndy Whitcroft } 5807554e165cSAndy Whitcroft } 5808554e165cSAndy Whitcroft 58094a273195SJoe Perches# check usleep_range arguments 58104a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 58114a273195SJoe Perches defined $stat && 58124a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 58134a273195SJoe Perches my $min = $1; 58144a273195SJoe Perches my $max = $7; 58154a273195SJoe Perches if ($min eq $max) { 58164a273195SJoe Perches WARN("USLEEP_RANGE", 58174a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58184a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 58194a273195SJoe Perches $min > $max) { 58204a273195SJoe Perches WARN("USLEEP_RANGE", 58214a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58224a273195SJoe Perches } 58234a273195SJoe Perches } 58244a273195SJoe Perches 5825823b794cSJoe Perches# check for naked sscanf 5826823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5827823b794cSJoe Perches defined $stat && 58286c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5829823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5830823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5831823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5832823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5833823b794cSJoe Perches $lc = $lc + $linenr; 5834823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5835823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5836823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5837823b794cSJoe Perches } 5838823b794cSJoe Perches WARN("NAKED_SSCANF", 5839823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5840823b794cSJoe Perches } 5841823b794cSJoe Perches 5842afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5843afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5844afc819abSJoe Perches defined $stat && 5845afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5846afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5847afc819abSJoe Perches $lc = $lc + $linenr; 5848afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5849afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5850afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5851afc819abSJoe Perches } 5852afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5853afc819abSJoe Perches my $format = $6; 5854afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5855afc819abSJoe Perches if ($count == 1 && 5856afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5857afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5858afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5859afc819abSJoe Perches } 5860afc819abSJoe Perches } 5861afc819abSJoe Perches } 5862afc819abSJoe Perches 586370dc8a48SJoe Perches# check for new externs in .h files. 586470dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 586570dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5866d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 586770dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 586870dc8a48SJoe Perches $fix) { 5869194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 587070dc8a48SJoe Perches } 587170dc8a48SJoe Perches } 587270dc8a48SJoe Perches 5873de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5874171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5875c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5876171ae1a4SAndy Whitcroft { 5877c45dcabdSAndy Whitcroft my $function_name = $1; 5878c45dcabdSAndy Whitcroft my $paren_space = $2; 5879171ae1a4SAndy Whitcroft 5880171ae1a4SAndy Whitcroft my $s = $stat; 5881171ae1a4SAndy Whitcroft if (defined $cond) { 5882171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5883171ae1a4SAndy Whitcroft } 5884c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5885c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5886c45dcabdSAndy Whitcroft { 5887000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5888000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5889de7d4f0eSAndy Whitcroft } 5890de7d4f0eSAndy Whitcroft 5891171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5892000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5893000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5894171ae1a4SAndy Whitcroft } 58959c9ba34eSAndy Whitcroft 58969c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 58979c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 58989c9ba34eSAndy Whitcroft { 5899000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5900000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5901171ae1a4SAndy Whitcroft } 5902171ae1a4SAndy Whitcroft 5903ca0d8929SJoe Perches if ($realfile =~ /\.[ch]$/ && defined $stat && 5904ca0d8929SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 5905ca0d8929SJoe Perches $1 ne "void") { 5906ca0d8929SJoe Perches my $args = trim($1); 5907ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 5908ca0d8929SJoe Perches my $arg = trim($1); 5909ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 5910ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 5911ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 5912ca0d8929SJoe Perches } 5913ca0d8929SJoe Perches } 5914ca0d8929SJoe Perches } 5915ca0d8929SJoe Perches 5916de7d4f0eSAndy Whitcroft# checks for new __setup's 5917de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5918de7d4f0eSAndy Whitcroft my $name = $1; 5919de7d4f0eSAndy Whitcroft 5920de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5921000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 59228c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5923de7d4f0eSAndy Whitcroft } 5924653d4876SAndy Whitcroft } 59259c0ca6f9SAndy Whitcroft 59269c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5927caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5928000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5929000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 59309c0ca6f9SAndy Whitcroft } 593113214adfSAndy Whitcroft 5932a640d25cSJoe Perches# alloc style 5933a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5934a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5935a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5936a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5937a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5938a640d25cSJoe Perches } 5939a640d25cSJoe Perches 594060a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 594160a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 59421b4a2ed4SJoe Perches defined $stat && 59431b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 594460a55369SJoe Perches my $oldfunc = $3; 594560a55369SJoe Perches my $a1 = $4; 594660a55369SJoe Perches my $a2 = $10; 594760a55369SJoe Perches my $newfunc = "kmalloc_array"; 594860a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 594960a55369SJoe Perches my $r1 = $a1; 595060a55369SJoe Perches my $r2 = $a2; 595160a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 595260a55369SJoe Perches $r1 = $a2; 595360a55369SJoe Perches $r2 = $a1; 595460a55369SJoe Perches } 5955e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5956e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 59571b4a2ed4SJoe Perches my $ctx = ''; 59581b4a2ed4SJoe Perches my $herectx = $here . "\n"; 59591b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 59601b4a2ed4SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 59611b4a2ed4SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 59621b4a2ed4SJoe Perches } 5963e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 59641b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 59651b4a2ed4SJoe Perches $cnt == 1 && 5966e367455aSJoe Perches $fix) { 5967194f66fcSJoe 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; 596860a55369SJoe Perches } 596960a55369SJoe Perches } 597060a55369SJoe Perches } 597160a55369SJoe Perches 5972972fdea2SJoe Perches# check for krealloc arg reuse 5973972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5974972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5975972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5976972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 5977972fdea2SJoe Perches } 5978972fdea2SJoe Perches 59795ce59ae0SJoe Perches# check for alloc argument mismatch 59805ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 59815ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 59825ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 59835ce59ae0SJoe Perches } 59845ce59ae0SJoe Perches 5985caf2a54fSJoe Perches# check for multiple semicolons 5986caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 5987d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 5988d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 5989d5e616fcSJoe Perches $fix) { 5990194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 5991d5e616fcSJoe Perches } 5992d1e2ad07SJoe Perches } 5993d1e2ad07SJoe Perches 5994cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 5995cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 5996cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 59970ab90191SJoe Perches my $ull = ""; 59980ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 59990ab90191SJoe Perches if (CHK("BIT_MACRO", 60000ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 60010ab90191SJoe Perches $fix) { 60020ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 60030ab90191SJoe Perches } 60040ab90191SJoe Perches } 60050ab90191SJoe Perches 60062d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 60072d632745SJoe 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*$/) { 60082d632745SJoe Perches my $config = $1; 60092d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 60102d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 60112d632745SJoe Perches $fix) { 60122d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 60132d632745SJoe Perches } 60142d632745SJoe Perches } 60152d632745SJoe Perches 6016e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6017c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6018c34c09a8SJoe Perches my $has_break = 0; 6019c34c09a8SJoe Perches my $has_statement = 0; 6020c34c09a8SJoe Perches my $count = 0; 6021c34c09a8SJoe Perches my $prevline = $linenr; 6022e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6023c34c09a8SJoe Perches $prevline--; 6024c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6025c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6026c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6027c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6028c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6029c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6030c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6031c34c09a8SJoe Perches $has_statement = 1; 6032c34c09a8SJoe Perches $count++; 6033c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 6034c34c09a8SJoe Perches } 6035c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6036c34c09a8SJoe Perches WARN("MISSING_BREAK", 6037224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6038c34c09a8SJoe Perches } 6039c34c09a8SJoe Perches } 6040c34c09a8SJoe Perches 6041d1e2ad07SJoe Perches# check for switch/default statements without a break; 6042d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 6043d1e2ad07SJoe Perches defined $stat && 6044d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6045d1e2ad07SJoe Perches my $ctx = ''; 6046d1e2ad07SJoe Perches my $herectx = $here . "\n"; 6047d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6048d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6049d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 6050d1e2ad07SJoe Perches } 6051d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6052d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6053caf2a54fSJoe Perches } 6054caf2a54fSJoe Perches 605513214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6056d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6057d5e616fcSJoe Perches if (WARN("USE_FUNC", 6058d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6059d5e616fcSJoe Perches $fix) { 6060194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6061d5e616fcSJoe Perches } 606213214adfSAndy Whitcroft } 6063773647a0SAndy Whitcroft 606462ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 606562ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 606662ec818fSJoe Perches ERROR("DATE_TIME", 606762ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 606862ec818fSJoe Perches } 606962ec818fSJoe Perches 60702c92488aSJoe Perches# check for use of yield() 60712c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 60722c92488aSJoe Perches WARN("YIELD", 60732c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 60742c92488aSJoe Perches } 60752c92488aSJoe Perches 6076179f8f40SJoe Perches# check for comparisons against true and false 6077179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6078179f8f40SJoe Perches my $lead = $1; 6079179f8f40SJoe Perches my $arg = $2; 6080179f8f40SJoe Perches my $test = $3; 6081179f8f40SJoe Perches my $otype = $4; 6082179f8f40SJoe Perches my $trail = $5; 6083179f8f40SJoe Perches my $op = "!"; 6084179f8f40SJoe Perches 6085179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6086179f8f40SJoe Perches 6087179f8f40SJoe Perches my $type = lc($otype); 6088179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6089179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6090179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6091179f8f40SJoe Perches $op = ""; 6092179f8f40SJoe Perches } 6093179f8f40SJoe Perches 6094179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6095179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6096179f8f40SJoe Perches 6097179f8f40SJoe Perches## maybe suggesting a correct construct would better 6098179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6099179f8f40SJoe Perches 6100179f8f40SJoe Perches } 6101179f8f40SJoe Perches } 6102179f8f40SJoe Perches 61034882720bSThomas Gleixner# check for semaphores initialized locked 61044882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6105000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6106000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6107773647a0SAndy Whitcroft } 61086712d858SJoe Perches 610967d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 611067d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6111000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 611267d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6113773647a0SAndy Whitcroft } 61146712d858SJoe Perches 6115ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6116f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6117000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6118ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6119f3db6639SMichael Ellerman } 61206712d858SJoe Perches 61210f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6122d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 61236903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6124d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6125000d1cc1SJoe Perches WARN("CONST_STRUCT", 6126d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 61272b6db5cbSAndy Whitcroft } 6128773647a0SAndy Whitcroft 6129773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6130773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6131773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6132c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6133c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6134171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6135171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6136171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6137773647a0SAndy Whitcroft { 6138000d1cc1SJoe Perches WARN("NR_CPUS", 6139000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6140773647a0SAndy Whitcroft } 61419c9ba34eSAndy Whitcroft 614252ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 614352ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 614452ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 614552ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 614652ea8506SJoe Perches } 614752ea8506SJoe Perches 6148acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6149acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 6150acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6151acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6152acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6153acd9362cSJoe Perches } 6154acd9362cSJoe Perches 6155691d77b6SAndy Whitcroft# whine mightly about in_atomic 6156691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6157691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6158000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6159000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6160f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6161000d1cc1SJoe Perches WARN("IN_ATOMIC", 6162000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6163691d77b6SAndy Whitcroft } 6164691d77b6SAndy Whitcroft } 61651704f47bSPeter Zijlstra 6166481aea5cSJoe Perches# whine about ACCESS_ONCE 6167481aea5cSJoe Perches if ($^V && $^V ge 5.10.0 && 6168481aea5cSJoe Perches $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 6169481aea5cSJoe Perches my $par = $1; 6170481aea5cSJoe Perches my $eq = $2; 6171481aea5cSJoe Perches my $fun = $3; 6172481aea5cSJoe Perches $par =~ s/^\(\s*(.*)\s*\)$/$1/; 6173481aea5cSJoe Perches if (defined($eq)) { 6174481aea5cSJoe Perches if (WARN("PREFER_WRITE_ONCE", 6175481aea5cSJoe Perches "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 6176481aea5cSJoe Perches $fix) { 6177481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 6178481aea5cSJoe Perches } 6179481aea5cSJoe Perches } else { 6180481aea5cSJoe Perches if (WARN("PREFER_READ_ONCE", 6181481aea5cSJoe Perches "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 6182481aea5cSJoe Perches $fix) { 6183481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 6184481aea5cSJoe Perches } 6185481aea5cSJoe Perches } 6186481aea5cSJoe Perches } 6187481aea5cSJoe Perches 61880f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 61890f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 61900f5225b0SPeter Zijlstra ERROR("LOCKING", 61910f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 61920f5225b0SPeter Zijlstra } 61930f5225b0SPeter Zijlstra 61941704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 61951704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 61961704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 61971704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 61981704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 61991704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6200000d1cc1SJoe Perches ERROR("LOCKDEP", 6201000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 62021704f47bSPeter Zijlstra } 62031704f47bSPeter Zijlstra } 620488f8831cSDave Jones 6205b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6206b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6207000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6208000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 620988f8831cSDave Jones } 62102435880fSJoe Perches 6211515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6212515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 6213515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 6214459cf0aeSJoe Perches defined $stat && 6215515a235eSJoe Perches $line =~ /$mode_perms_search/) { 62162435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 62172435880fSJoe Perches my $func = $entry->[0]; 62182435880fSJoe Perches my $arg_pos = $entry->[1]; 62192435880fSJoe Perches 6220459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6221459cf0aeSJoe Perches $lc = $lc + $linenr; 6222459cf0aeSJoe Perches my $stat_real = raw_line($linenr, 0); 6223459cf0aeSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 6224459cf0aeSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 6225459cf0aeSJoe Perches } 6226459cf0aeSJoe Perches 62272435880fSJoe Perches my $skip_args = ""; 62282435880fSJoe Perches if ($arg_pos > 1) { 62292435880fSJoe Perches $arg_pos--; 62302435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62312435880fSJoe Perches } 6232f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6233459cf0aeSJoe Perches if ($stat =~ /$test/) { 62342435880fSJoe Perches my $val = $1; 62352435880fSJoe Perches $val = $6 if ($skip_args ne ""); 6236f90774e1SJoe Perches if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 6237f90774e1SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4)) { 62382435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6239459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6240f90774e1SJoe Perches } 6241f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6242c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6243459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 62442435880fSJoe Perches } 6245459cf0aeSJoe Perches } 6246459cf0aeSJoe Perches } 6247459cf0aeSJoe Perches } 6248459cf0aeSJoe Perches 6249459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6250459cf0aeSJoe Perches if ($line =~ /\b$mode_perms_string_search\b/) { 6251459cf0aeSJoe Perches my $val = ""; 6252459cf0aeSJoe Perches my $oval = ""; 6253f90774e1SJoe Perches my $to = 0; 6254459cf0aeSJoe Perches my $curpos = 0; 6255459cf0aeSJoe Perches my $lastpos = 0; 6256459cf0aeSJoe Perches while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 6257459cf0aeSJoe Perches $curpos = pos($line); 6258459cf0aeSJoe Perches my $match = $2; 6259459cf0aeSJoe Perches my $omatch = $1; 6260459cf0aeSJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 6261459cf0aeSJoe Perches $lastpos = $curpos; 6262459cf0aeSJoe Perches $to |= $mode_permission_string_types{$match}; 6263459cf0aeSJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 6264459cf0aeSJoe Perches $val .= $match; 6265459cf0aeSJoe Perches $oval .= $omatch; 6266f90774e1SJoe Perches } 6267459cf0aeSJoe Perches $oval =~ s/^\s*\|\s*//; 6268459cf0aeSJoe Perches $oval =~ s/\s*\|\s*$//; 6269459cf0aeSJoe Perches my $octal = sprintf("%04o", $to); 6270f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6271459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6272f90774e1SJoe Perches $fix) { 6273459cf0aeSJoe Perches $fixed[$fixlinenr] =~ s/$val/$octal/; 62742435880fSJoe Perches } 627513214adfSAndy Whitcroft } 62765a6d20ceSBjorn Andersson 62775a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 62785a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 62795a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 62805a6d20ceSBjorn Andersson my $valid_licenses = qr{ 62815a6d20ceSBjorn Andersson GPL| 62825a6d20ceSBjorn Andersson GPL\ v2| 62835a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 62845a6d20ceSBjorn Andersson Dual\ BSD/GPL| 62855a6d20ceSBjorn Andersson Dual\ MIT/GPL| 62865a6d20ceSBjorn Andersson Dual\ MPL/GPL| 62875a6d20ceSBjorn Andersson Proprietary 62885a6d20ceSBjorn Andersson }x; 62895a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 62905a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 62915a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 62925a6d20ceSBjorn Andersson } 62935a6d20ceSBjorn Andersson } 6294515a235eSJoe Perches } 629513214adfSAndy Whitcroft 629613214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 629713214adfSAndy Whitcroft # so just keep quiet. 629813214adfSAndy Whitcroft if ($#rawlines == -1) { 629913214adfSAndy Whitcroft exit(0); 63000a920b5bSAndy Whitcroft } 63010a920b5bSAndy Whitcroft 63028905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 63038905a67cSAndy Whitcroft # things that appear to be patches. 63048905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 63058905a67cSAndy Whitcroft exit(0); 63068905a67cSAndy Whitcroft } 63078905a67cSAndy Whitcroft 63088905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 63098905a67cSAndy Whitcroft # just keep quiet. 63108905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 63118905a67cSAndy Whitcroft exit(0); 63128905a67cSAndy Whitcroft } 63138905a67cSAndy Whitcroft 631406330fc4SJoe Perches if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6315000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6316000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 63170a920b5bSAndy Whitcroft } 6318ed43c4e5SAllen Hubbe if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6319000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6320000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 63210a920b5bSAndy Whitcroft } 63220a920b5bSAndy Whitcroft 6323f0a594c1SAndy Whitcroft print report_dump(); 632413214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 632513214adfSAndy Whitcroft print "$filename " if ($summary_file); 63266c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 63276c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 63286c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 63296c72ffaaSAndy Whitcroft } 63308905a67cSAndy Whitcroft 6331d2c0a235SAndy Whitcroft if ($quiet == 0) { 6332ef212196SJoe Perches # If there were any defects found and not already fixing them 6333ef212196SJoe Perches if (!$clean and !$fix) { 6334ef212196SJoe Perches print << "EOM" 6335ef212196SJoe Perches 6336ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6337ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6338ef212196SJoe PerchesEOM 6339ef212196SJoe Perches } 6340d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6341d2c0a235SAndy Whitcroft # then suggest that. 6342d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6343b0781216SMike Frysinger $rpt_cleaners = 0; 6344d8469f16SJoe Perches print << "EOM" 6345d8469f16SJoe Perches 6346d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6347d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6348d8469f16SJoe PerchesEOM 6349d2c0a235SAndy Whitcroft } 6350d2c0a235SAndy Whitcroft } 6351d2c0a235SAndy Whitcroft 6352d752fcc8SJoe Perches if ($clean == 0 && $fix && 6353d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6354d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 63559624b8d6SJoe Perches my $newfile = $filename; 63569624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 63573705ce5bSJoe Perches my $linecount = 0; 63583705ce5bSJoe Perches my $f; 63593705ce5bSJoe Perches 6360d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6361d752fcc8SJoe Perches 63623705ce5bSJoe Perches open($f, '>', $newfile) 63633705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 63643705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 63653705ce5bSJoe Perches $linecount++; 63663705ce5bSJoe Perches if ($file) { 63673705ce5bSJoe Perches if ($linecount > 3) { 63683705ce5bSJoe Perches $fixed_line =~ s/^\+//; 63693705ce5bSJoe Perches print $f $fixed_line . "\n"; 63703705ce5bSJoe Perches } 63713705ce5bSJoe Perches } else { 63723705ce5bSJoe Perches print $f $fixed_line . "\n"; 63733705ce5bSJoe Perches } 63743705ce5bSJoe Perches } 63753705ce5bSJoe Perches close($f); 63763705ce5bSJoe Perches 63773705ce5bSJoe Perches if (!$quiet) { 63783705ce5bSJoe Perches print << "EOM"; 6379d8469f16SJoe Perches 63803705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 63813705ce5bSJoe Perches 63823705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 63833705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 63843705ce5bSJoe Perches 63853705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 63863705ce5bSJoe PerchesNo warranties, expressed or implied... 63873705ce5bSJoe PerchesEOM 63883705ce5bSJoe Perches } 63893705ce5bSJoe Perches } 63903705ce5bSJoe Perches 6391d8469f16SJoe Perches if ($quiet == 0) { 6392d8469f16SJoe Perches print "\n"; 6393d8469f16SJoe Perches if ($clean == 1) { 6394d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6395d8469f16SJoe Perches } else { 6396d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 63970a920b5bSAndy Whitcroft } 63980a920b5bSAndy Whitcroft } 63990a920b5bSAndy Whitcroft return $clean; 64000a920b5bSAndy Whitcroft} 6401