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 } 221674fd4f34SJoe 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 && 229574fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 229674fd4f34SJoe 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; 231274fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 231374fd4f34SJoe Perches $context_function = $1; 231474fd4f34SJoe Perches } else { 231574fd4f34SJoe Perches undef $context_function; 231674fd4f34SJoe 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. 3357f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\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) || 3449f6950a73SJoe Perches ($sindent == $indent && 3450f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 34519f5af480SJoe Perches ($sindent > $indent + 8))) { 3452000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3453000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 34544d001e4dSAndy Whitcroft } 34554d001e4dSAndy Whitcroft } 34564d001e4dSAndy Whitcroft 34576c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 34586c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 34591f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 34601f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 34616c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3462c2fdda0dSAndy Whitcroft if ($dbg_values) { 3463c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3464cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3465cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 34661f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3467c2fdda0dSAndy Whitcroft } 34686c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 34696c72ffaaSAndy Whitcroft 347000df344fSAndy Whitcroft#ignore lines not being added 34713705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 347200df344fSAndy Whitcroft 347311ca40a0SJoe Perches# check for dereferences that span multiple lines 347411ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 347511ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 347611ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 347711ca40a0SJoe Perches my $ref = $1; 347811ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 347911ca40a0SJoe Perches $ref .= $1; 348011ca40a0SJoe Perches $ref =~ s/\s//g; 348111ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 348211ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 348311ca40a0SJoe Perches } 348411ca40a0SJoe Perches 3485a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3486c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3487a1ce18e4SJoe Perches my $type = $1; 3488a1ce18e4SJoe Perches my $var = $2; 3489207a8e84SJoe Perches $var = "" if (!defined $var); 3490207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3491a1ce18e4SJoe Perches my $sign = $1; 3492a1ce18e4SJoe Perches my $pointer = $2; 3493a1ce18e4SJoe Perches 3494a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3495a1ce18e4SJoe Perches 3496a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3497a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3498a1ce18e4SJoe Perches $fix) { 3499a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3500207a8e84SJoe Perches my $comp_pointer = $pointer; 3501207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3502207a8e84SJoe Perches $decl .= $comp_pointer; 3503207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3504207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3505a1ce18e4SJoe Perches } 3506a1ce18e4SJoe Perches } 3507a1ce18e4SJoe Perches } 3508a1ce18e4SJoe Perches 3509653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 35107429c690SAndy Whitcroft if ($dbg_type) { 35117429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3512000d1cc1SJoe Perches ERROR("TEST_TYPE", 3513000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 35147429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3515000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3516000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 35177429c690SAndy Whitcroft } 3518653d4876SAndy Whitcroft next; 3519653d4876SAndy Whitcroft } 3520a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3521a1ef277eSAndy Whitcroft if ($dbg_attr) { 35229360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3523000d1cc1SJoe Perches ERROR("TEST_ATTR", 3524000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 35259360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3526000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3527000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3528a1ef277eSAndy Whitcroft } 3529a1ef277eSAndy Whitcroft next; 3530a1ef277eSAndy Whitcroft } 3531653d4876SAndy Whitcroft 3532f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 353399423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 353499423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3535d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3536d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3537f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3538f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3539f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3540d752fcc8SJoe Perches my $fixedline = $prevrawline; 3541d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3542f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3543d752fcc8SJoe Perches $fixedline = $line; 3544d752fcc8SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1/; 3545f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3546d752fcc8SJoe Perches } 3547f0a594c1SAndy Whitcroft } 3548f0a594c1SAndy Whitcroft 354900df344fSAndy Whitcroft# 355000df344fSAndy Whitcroft# Checks which are anchored on the added line. 355100df344fSAndy Whitcroft# 355200df344fSAndy Whitcroft 3553653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3554c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3555653d4876SAndy Whitcroft my $path = $1; 3556653d4876SAndy Whitcroft if ($path =~ m{//}) { 3557000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3558495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3559495e9d84SJoe Perches } 3560495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3561495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3562495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3563653d4876SAndy Whitcroft } 3564653d4876SAndy Whitcroft } 3565653d4876SAndy Whitcroft 356600df344fSAndy Whitcroft# no C99 // comments 356700df344fSAndy Whitcroft if ($line =~ m{//}) { 35683705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 35693705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 35703705ce5bSJoe Perches $fix) { 3571194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 35723705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 35733705ce5bSJoe Perches my $comment = trim($1); 3574194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 35753705ce5bSJoe Perches } 35763705ce5bSJoe Perches } 357700df344fSAndy Whitcroft } 357800df344fSAndy Whitcroft # Remove C99 comments. 35790a920b5bSAndy Whitcroft $line =~ s@//.*@@; 35806c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 35810a920b5bSAndy Whitcroft 35822b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 35832b474a1aSAndy Whitcroft# the whole statement. 35842b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 35852b474a1aSAndy Whitcroft if (defined $realline_next && 35862b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 35872b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 35882b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 35892b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 35903cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 35913cbf62dfSAndy Whitcroft # a prefix: 35923cbf62dfSAndy Whitcroft # XXX(foo); 35933cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3594653d4876SAndy Whitcroft my $name = $1; 359587a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 35963cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 35973cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 35983cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 35993cbf62dfSAndy Whitcroft 36003cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 36012b474a1aSAndy Whitcroft \n.}\s*$| 360248012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 360348012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 360448012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 36052b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 36062b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 360748012058SAndy Whitcroft )/x) { 36082b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 36092b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 36102b474a1aSAndy Whitcroft } else { 36112b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 36120a920b5bSAndy Whitcroft } 36130a920b5bSAndy Whitcroft } 36142b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 36152b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 36162b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36172b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36182b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 36192b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 36202b474a1aSAndy Whitcroft } 36212b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 36222b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3623000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3624000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 36252b474a1aSAndy Whitcroft } 36260a920b5bSAndy Whitcroft 36275150bda4SJoe Eloff# check for global initialisers. 36286d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3629d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 36306d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3631d5e616fcSJoe Perches $fix) { 36326d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3633d5e616fcSJoe Perches } 3634f0a594c1SAndy Whitcroft } 36350a920b5bSAndy Whitcroft# check for static initialisers. 36366d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3637d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 36386d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3639d5e616fcSJoe Perches $herecurr) && 3640d5e616fcSJoe Perches $fix) { 36416d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3642d5e616fcSJoe Perches } 36430a920b5bSAndy Whitcroft } 36440a920b5bSAndy Whitcroft 36451813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 36461813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36471813087dSJoe Perches my $tmp = trim($1); 36481813087dSJoe Perches WARN("MISORDERED_TYPE", 36491813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36501813087dSJoe Perches } 36511813087dSJoe Perches 3652cb710ecaSJoe Perches# check for static const char * arrays. 3653cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3654000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3655000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3656cb710ecaSJoe Perches $herecurr); 3657cb710ecaSJoe Perches } 3658cb710ecaSJoe Perches 3659cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3660cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3661000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3662000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3663cb710ecaSJoe Perches $herecurr); 3664cb710ecaSJoe Perches } 3665cb710ecaSJoe Perches 3666ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3667ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3668ab7e23f3SJoe Perches my $found = $1; 3669ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3670ab7e23f3SJoe Perches WARN("CONST_CONST", 3671ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3672ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3673ab7e23f3SJoe Perches WARN("CONST_CONST", 3674ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3675ab7e23f3SJoe Perches } 3676ab7e23f3SJoe Perches } 3677ab7e23f3SJoe Perches 36789b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 36799b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 36809b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 36819b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 36829b0fa60dSJoe Perches $herecurr); 36839b0fa60dSJoe Perches } 36849b0fa60dSJoe Perches 3685b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3686b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3687b598b670SJoe Perches my $array = $1; 3688b598b670SJoe 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*\))@) { 3689b598b670SJoe Perches my $array_div = $1; 3690b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3691b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3692b598b670SJoe Perches $fix) { 3693b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3694b598b670SJoe Perches } 3695b598b670SJoe Perches } 3696b598b670SJoe Perches } 3697b598b670SJoe Perches 3698b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3699b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3700b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3701b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3702b36190c5SJoe Perches $fix) { 3703194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3704b36190c5SJoe Perches } 3705b36190c5SJoe Perches } 3706b36190c5SJoe Perches 3707653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3708653d4876SAndy Whitcroft# make sense. 3709653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 37108054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3711c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 37128ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 371346d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 3714000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3715000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 37160a920b5bSAndy Whitcroft } 37170a920b5bSAndy Whitcroft 37180a920b5bSAndy Whitcroft# * goes on variable not on type 371965863862SAndy Whitcroft # (char*[ const]) 3720bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3721bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 37223705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3723d8aaf121SAndy Whitcroft 372465863862SAndy Whitcroft # Should start with a space. 372565863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 372665863862SAndy Whitcroft # Should not end with a space. 372765863862SAndy Whitcroft $to =~ s/\s+$//; 372865863862SAndy Whitcroft # '*'s should not have spaces between. 3729f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 373065863862SAndy Whitcroft } 3731d8aaf121SAndy Whitcroft 37323705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 373365863862SAndy Whitcroft if ($from ne $to) { 37343705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37353705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37363705ce5bSJoe Perches $fix) { 37373705ce5bSJoe Perches my $sub_from = $ident; 37383705ce5bSJoe Perches my $sub_to = $ident; 37393705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3740194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37413705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37423705ce5bSJoe Perches } 374365863862SAndy Whitcroft } 3744bfcb2cc7SAndy Whitcroft } 3745bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3746bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 37473705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3748d8aaf121SAndy Whitcroft 374965863862SAndy Whitcroft # Should start with a space. 375065863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 375165863862SAndy Whitcroft # Should not end with a space. 375265863862SAndy Whitcroft $to =~ s/\s+$//; 375365863862SAndy Whitcroft # '*'s should not have spaces between. 3754f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 375565863862SAndy Whitcroft } 375665863862SAndy Whitcroft # Modifiers should have spaces. 375765863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 375865863862SAndy Whitcroft 37593705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3760667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 37613705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37623705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 37633705ce5bSJoe Perches $fix) { 37643705ce5bSJoe Perches 37653705ce5bSJoe Perches my $sub_from = $match; 37663705ce5bSJoe Perches my $sub_to = $match; 37673705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3768194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37693705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37703705ce5bSJoe Perches } 377165863862SAndy Whitcroft } 37720a920b5bSAndy Whitcroft } 37730a920b5bSAndy Whitcroft 37749d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 37759d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 37769d3e3c70SJoe Perches my $msg_type = \&WARN; 37779d3e3c70SJoe Perches $msg_type = \&CHK if ($file); 37789d3e3c70SJoe Perches &{$msg_type}("AVOID_BUG", 37799d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 37809d3e3c70SJoe Perches } 37810a920b5bSAndy Whitcroft 37829d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 37838905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3784000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3785000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 37868905a67cSAndy Whitcroft } 37878905a67cSAndy Whitcroft 378817441227SJoe Perches# check for uses of printk_ratelimit 378917441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3790000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3791000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 379217441227SJoe Perches } 379317441227SJoe Perches 379400df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 379500df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 379600df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 379725985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 379800df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3799f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 380000df344fSAndy Whitcroft my $ok = 0; 380100df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 380200df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 380325985edcSLucas De Marchi # we have a preceding printk if it ends 380400df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 380500df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 380600df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 380700df344fSAndy Whitcroft $ok = 1; 380800df344fSAndy Whitcroft } 380900df344fSAndy Whitcroft last; 381000df344fSAndy Whitcroft } 381100df344fSAndy Whitcroft } 381200df344fSAndy Whitcroft if ($ok == 0) { 3813000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3814000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 38150a920b5bSAndy Whitcroft } 381600df344fSAndy Whitcroft } 38170a920b5bSAndy Whitcroft 3818243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3819243f3803SJoe Perches my $orig = $1; 3820243f3803SJoe Perches my $level = lc($orig); 3821243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 38228f26b837SJoe Perches my $level2 = $level; 38238f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3824243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3825daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3826243f3803SJoe Perches } 3827243f3803SJoe Perches 3828243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3829d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3830d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3831d5e616fcSJoe Perches $fix) { 3832194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3833d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3834d5e616fcSJoe Perches } 3835243f3803SJoe Perches } 3836243f3803SJoe Perches 3837dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3838dc139313SJoe Perches my $orig = $1; 3839dc139313SJoe Perches my $level = lc($orig); 3840dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3841dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3842dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3843dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3844dc139313SJoe Perches } 3845dc139313SJoe Perches 384691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 384791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 384891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 384991c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 385091c9afafSAndy Lutomirski WARN("ENOSYS", 385191c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 385291c9afafSAndy Lutomirski } 385391c9afafSAndy Lutomirski 3854653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3855653d4876SAndy Whitcroft# or if closed on same line 38568d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 38574e5d56bdSEddie Kovsky !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38588d182478SJoe Perches if (ERROR("OPEN_BRACE", 38598d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38608d182478SJoe Perches $fix) { 38618d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38628d182478SJoe Perches my $fixed_line = $rawline; 38638d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 38648d182478SJoe Perches my $line1 = $1; 38658d182478SJoe Perches my $line2 = $2; 38668d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 38678d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 38688d182478SJoe Perches if ($line2 !~ /^\s*$/) { 38698d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 38708d182478SJoe Perches } 38718d182478SJoe Perches } 38720a920b5bSAndy Whitcroft } 3873653d4876SAndy Whitcroft 38748905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 38758905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 38768905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 38778d182478SJoe Perches if (ERROR("OPEN_BRACE", 38788d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 38798d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 38808d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 38818d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38828d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 38838d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38848d182478SJoe Perches $fixedline = $rawline; 38858d182478SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1\t/; 38868d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 38878d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38888d182478SJoe Perches } 38898d182478SJoe Perches } 38908905a67cSAndy Whitcroft } 38918905a67cSAndy Whitcroft 38920c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 38933705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 38943705ce5bSJoe Perches if (WARN("SPACING", 38953705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 38963705ce5bSJoe Perches $fix) { 3897194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38983705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 38993705ce5bSJoe Perches } 39000c73b4ebSAndy Whitcroft } 39010c73b4ebSAndy Whitcroft 390231070b5dSJoe Perches# Function pointer declarations 390331070b5dSJoe Perches# check spacing between type, funcptr, and args 390431070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 390591f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 390631070b5dSJoe Perches my $declare = $1; 390731070b5dSJoe Perches my $pre_pointer_space = $2; 390831070b5dSJoe Perches my $post_pointer_space = $3; 390931070b5dSJoe Perches my $funcname = $4; 391031070b5dSJoe Perches my $post_funcname_space = $5; 391131070b5dSJoe Perches my $pre_args_space = $6; 391231070b5dSJoe Perches 391391f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 391491f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 391591f72e9cSJoe Perches# don't need a space so don't warn for those. 391691f72e9cSJoe Perches my $post_declare_space = ""; 391791f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 391891f72e9cSJoe Perches $post_declare_space = $1; 391991f72e9cSJoe Perches $declare = rtrim($declare); 392091f72e9cSJoe Perches } 392191f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 392231070b5dSJoe Perches WARN("SPACING", 392331070b5dSJoe Perches "missing space after return type\n" . $herecurr); 392491f72e9cSJoe Perches $post_declare_space = " "; 392531070b5dSJoe Perches } 392631070b5dSJoe Perches 392731070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 392891f72e9cSJoe Perches# This test is not currently implemented because these declarations are 392991f72e9cSJoe Perches# equivalent to 393091f72e9cSJoe Perches# int foo(int bar, ...) 393191f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 393291f72e9cSJoe Perches# 393391f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 393491f72e9cSJoe Perches# WARN("SPACING", 393591f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 393691f72e9cSJoe Perches# } 393731070b5dSJoe Perches 393831070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 393931070b5dSJoe Perches if (defined $pre_pointer_space && 394031070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 394131070b5dSJoe Perches WARN("SPACING", 394231070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 394331070b5dSJoe Perches } 394431070b5dSJoe Perches 394531070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 394631070b5dSJoe Perches if (defined $post_pointer_space && 394731070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 394831070b5dSJoe Perches WARN("SPACING", 394931070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 395031070b5dSJoe Perches } 395131070b5dSJoe Perches 395231070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 395331070b5dSJoe Perches if (defined $post_funcname_space && 395431070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 395531070b5dSJoe Perches WARN("SPACING", 395631070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 395731070b5dSJoe Perches } 395831070b5dSJoe Perches 395931070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 396031070b5dSJoe Perches if (defined $pre_args_space && 396131070b5dSJoe Perches $pre_args_space =~ /^\s/) { 396231070b5dSJoe Perches WARN("SPACING", 396331070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 396431070b5dSJoe Perches } 396531070b5dSJoe Perches 396631070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3967194f66fcSJoe Perches $fixed[$fixlinenr] =~ 396891f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 396931070b5dSJoe Perches } 397031070b5dSJoe Perches } 397131070b5dSJoe Perches 39728d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 39738d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3974fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3975fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 39768d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 39778d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 39788d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3979fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3980daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 39813705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 39823705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 39833705ce5bSJoe Perches $fix) { 3984194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39853705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 39863705ce5bSJoe Perches } 39878d31cfceSAndy Whitcroft } 39888d31cfceSAndy Whitcroft } 39898d31cfceSAndy Whitcroft 3990f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 39916c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 3992c2fdda0dSAndy Whitcroft my $name = $1; 3993773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 3994773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 3995c2fdda0dSAndy Whitcroft 3996c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 3997773647a0SAndy Whitcroft if ($name =~ /^(?: 3998773647a0SAndy Whitcroft if|for|while|switch|return|case| 3999773647a0SAndy Whitcroft volatile|__volatile__| 4000773647a0SAndy Whitcroft __attribute__|format|__extension__| 4001773647a0SAndy Whitcroft asm|__asm__)$/x) 4002773647a0SAndy Whitcroft { 4003c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4004c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4005c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4006c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4007773647a0SAndy Whitcroft 4008773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4009c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4010c2fdda0dSAndy Whitcroft 4011c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4012c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4013773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4014c2fdda0dSAndy Whitcroft 4015c2fdda0dSAndy Whitcroft } else { 40163705ce5bSJoe Perches if (WARN("SPACING", 40173705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40183705ce5bSJoe Perches $fix) { 4019194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40203705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 40213705ce5bSJoe Perches } 4022f0a594c1SAndy Whitcroft } 40236c72ffaaSAndy Whitcroft } 40249a4cad4eSEric Nelson 4025653d4876SAndy Whitcroft# Check operator spacing. 40260a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 40273705ce5bSJoe Perches my $fixed_line = ""; 40283705ce5bSJoe Perches my $line_fixed = 0; 40293705ce5bSJoe Perches 40309c0ca6f9SAndy Whitcroft my $ops = qr{ 40319c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 40329c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 40339c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 40341f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 403584731623SJoe Perches \?:|\?|: 40369c0ca6f9SAndy Whitcroft }x; 4037cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 40383705ce5bSJoe Perches 40393705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 40403705ce5bSJoe Perches## foreach my $el (@elements) { 40413705ce5bSJoe Perches## print("el: <$el>\n"); 40423705ce5bSJoe Perches## } 40433705ce5bSJoe Perches 40443705ce5bSJoe Perches my @fix_elements = (); 404500df344fSAndy Whitcroft my $off = 0; 40466c72ffaaSAndy Whitcroft 40473705ce5bSJoe Perches foreach my $el (@elements) { 40483705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 40493705ce5bSJoe Perches $off += length($el); 40503705ce5bSJoe Perches } 40513705ce5bSJoe Perches 40523705ce5bSJoe Perches $off = 0; 40533705ce5bSJoe Perches 40546c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4055b34c648bSJoe Perches my $last_after = -1; 40566c72ffaaSAndy Whitcroft 40570a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 40583705ce5bSJoe Perches 40593705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40603705ce5bSJoe Perches 40613705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 40623705ce5bSJoe Perches 40634a0df2efSAndy Whitcroft $off += length($elements[$n]); 40644a0df2efSAndy Whitcroft 406525985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4066773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4067773647a0SAndy Whitcroft my $cc = ''; 4068773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4069773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4070773647a0SAndy Whitcroft } 4071773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4072773647a0SAndy Whitcroft 40734a0df2efSAndy Whitcroft my $a = ''; 40744a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 40754a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4076cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 40774a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 40784a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4079773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 40804a0df2efSAndy Whitcroft 40810a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 40824a0df2efSAndy Whitcroft 40834a0df2efSAndy Whitcroft my $c = ''; 40840a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 40854a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 40864a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4087cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 40884a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 40894a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 40908b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 40914a0df2efSAndy Whitcroft } else { 40924a0df2efSAndy Whitcroft $c = 'E'; 40930a920b5bSAndy Whitcroft } 40940a920b5bSAndy Whitcroft 40954a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 40964a0df2efSAndy Whitcroft 40974a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 40984a0df2efSAndy Whitcroft 40996c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4100de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 41010a920b5bSAndy Whitcroft 410274048ed8SAndy Whitcroft # Pull out the value of this operator. 41036c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 41040a920b5bSAndy Whitcroft 41051f65f947SAndy Whitcroft # Get the full operator variant. 41061f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 41071f65f947SAndy Whitcroft 410813214adfSAndy Whitcroft # Ignore operators passed as parameters. 410913214adfSAndy Whitcroft if ($op_type ne 'V' && 4110d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 411113214adfSAndy Whitcroft 4112cf655043SAndy Whitcroft# # Ignore comments 4113cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 411413214adfSAndy Whitcroft 4115d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 411613214adfSAndy Whitcroft } elsif ($op eq ';') { 4117cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4118cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 41193705ce5bSJoe Perches if (ERROR("SPACING", 41203705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4121b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41223705ce5bSJoe Perches $line_fixed = 1; 41233705ce5bSJoe Perches } 4124d8aaf121SAndy Whitcroft } 4125d8aaf121SAndy Whitcroft 4126d8aaf121SAndy Whitcroft # // is a comment 4127d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 41280a920b5bSAndy Whitcroft 4129b00e4814SJoe Perches # : when part of a bitfield 4130b00e4814SJoe Perches } elsif ($opv eq ':B') { 4131b00e4814SJoe Perches # skip the bitfield test for now 4132b00e4814SJoe Perches 41331f65f947SAndy Whitcroft # No spaces for: 41341f65f947SAndy Whitcroft # -> 4135b00e4814SJoe Perches } elsif ($op eq '->') { 41364a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 41373705ce5bSJoe Perches if (ERROR("SPACING", 41383705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4139b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41403705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 41413705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 41423705ce5bSJoe Perches } 4143b34c648bSJoe Perches $line_fixed = 1; 41443705ce5bSJoe Perches } 41450a920b5bSAndy Whitcroft } 41460a920b5bSAndy Whitcroft 41472381097bSJoe Perches # , must not have a space before and must have a space on the right. 41480a920b5bSAndy Whitcroft } elsif ($op eq ',') { 41492381097bSJoe Perches my $rtrim_before = 0; 41502381097bSJoe Perches my $space_after = 0; 41512381097bSJoe Perches if ($ctx =~ /Wx./) { 41522381097bSJoe Perches if (ERROR("SPACING", 41532381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 41542381097bSJoe Perches $line_fixed = 1; 41552381097bSJoe Perches $rtrim_before = 1; 41562381097bSJoe Perches } 41572381097bSJoe Perches } 4158cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41593705ce5bSJoe Perches if (ERROR("SPACING", 41603705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 41613705ce5bSJoe Perches $line_fixed = 1; 4162b34c648bSJoe Perches $last_after = $n; 41632381097bSJoe Perches $space_after = 1; 41642381097bSJoe Perches } 41652381097bSJoe Perches } 41662381097bSJoe Perches if ($rtrim_before || $space_after) { 41672381097bSJoe Perches if ($rtrim_before) { 41682381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41692381097bSJoe Perches } else { 41702381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 41712381097bSJoe Perches } 41722381097bSJoe Perches if ($space_after) { 41732381097bSJoe Perches $good .= " "; 41743705ce5bSJoe Perches } 41750a920b5bSAndy Whitcroft } 41760a920b5bSAndy Whitcroft 41779c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 417874048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 41799c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 41809c0ca6f9SAndy Whitcroft 41819c0ca6f9SAndy Whitcroft # unary operators should have a space before and 41829c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 41839c0ca6f9SAndy Whitcroft # unary operator, or a cast 41849c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 418574048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 41860d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4187cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 41883705ce5bSJoe Perches if (ERROR("SPACING", 41893705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4190b34c648bSJoe Perches if ($n != $last_after + 2) { 4191b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 41923705ce5bSJoe Perches $line_fixed = 1; 41933705ce5bSJoe Perches } 41940a920b5bSAndy Whitcroft } 4195b34c648bSJoe Perches } 4196a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4197171ae1a4SAndy Whitcroft # A unary '*' may be const 4198171ae1a4SAndy Whitcroft 4199171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 42003705ce5bSJoe Perches if (ERROR("SPACING", 42013705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4202b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42033705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42043705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 42053705ce5bSJoe Perches } 4206b34c648bSJoe Perches $line_fixed = 1; 42073705ce5bSJoe Perches } 42080a920b5bSAndy Whitcroft } 42090a920b5bSAndy Whitcroft 42100a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 42110a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4212773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42133705ce5bSJoe Perches if (ERROR("SPACING", 42143705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4215b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42163705ce5bSJoe Perches $line_fixed = 1; 42173705ce5bSJoe Perches } 42180a920b5bSAndy Whitcroft } 4219773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4220773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42213705ce5bSJoe Perches if (ERROR("SPACING", 42223705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4223b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42243705ce5bSJoe Perches $line_fixed = 1; 42253705ce5bSJoe Perches } 4226653d4876SAndy Whitcroft } 4227773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 42283705ce5bSJoe Perches if (ERROR("SPACING", 42293705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4230b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42313705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42323705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4233773647a0SAndy Whitcroft } 4234b34c648bSJoe Perches $line_fixed = 1; 42353705ce5bSJoe Perches } 42363705ce5bSJoe Perches } 42370a920b5bSAndy Whitcroft 42380a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 42399c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 42409c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 42419c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4242c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4243c2fdda0dSAndy Whitcroft $op eq '%') 42440a920b5bSAndy Whitcroft { 4245d2e025f3SJoe Perches if ($check) { 4246d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4247d2e025f3SJoe Perches if (CHK("SPACING", 4248d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4249d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4250d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4251d2e025f3SJoe Perches $line_fixed = 1; 4252d2e025f3SJoe Perches } 4253d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4254d2e025f3SJoe Perches if (CHK("SPACING", 4255d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4256d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4257d2e025f3SJoe Perches $line_fixed = 1; 4258d2e025f3SJoe Perches } 4259d2e025f3SJoe Perches } 4260d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42613705ce5bSJoe Perches if (ERROR("SPACING", 42623705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4263b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4264b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4265b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4266b34c648bSJoe Perches } 42673705ce5bSJoe Perches $line_fixed = 1; 42683705ce5bSJoe Perches } 42690a920b5bSAndy Whitcroft } 42700a920b5bSAndy Whitcroft 42711f65f947SAndy Whitcroft # A colon needs no spaces before when it is 42721f65f947SAndy Whitcroft # terminating a case value or a label. 42731f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 42741f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 42753705ce5bSJoe Perches if (ERROR("SPACING", 42763705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4277b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42783705ce5bSJoe Perches $line_fixed = 1; 42793705ce5bSJoe Perches } 42801f65f947SAndy Whitcroft } 42811f65f947SAndy Whitcroft 42820a920b5bSAndy Whitcroft # All the others need spaces both sides. 4283cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 42841f65f947SAndy Whitcroft my $ok = 0; 42851f65f947SAndy Whitcroft 428622f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 42871f65f947SAndy Whitcroft if (($op eq '<' && 42881f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 42891f65f947SAndy Whitcroft ($op eq '>' && 42901f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 42911f65f947SAndy Whitcroft { 42921f65f947SAndy Whitcroft $ok = 1; 42931f65f947SAndy Whitcroft } 42941f65f947SAndy Whitcroft 4295e0df7e1fSJoe Perches # for asm volatile statements 4296e0df7e1fSJoe Perches # ignore a colon with another 4297e0df7e1fSJoe Perches # colon immediately before or after 4298e0df7e1fSJoe Perches if (($op eq ':') && 4299e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4300e0df7e1fSJoe Perches $ok = 1; 4301e0df7e1fSJoe Perches } 4302e0df7e1fSJoe Perches 430384731623SJoe Perches # messages are ERROR, but ?: are CHK 43041f65f947SAndy Whitcroft if ($ok == 0) { 430584731623SJoe Perches my $msg_type = \&ERROR; 430684731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 430784731623SJoe Perches 430884731623SJoe Perches if (&{$msg_type}("SPACING", 43093705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4310b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4311b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4312b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4313b34c648bSJoe Perches } 43143705ce5bSJoe Perches $line_fixed = 1; 43153705ce5bSJoe Perches } 43160a920b5bSAndy Whitcroft } 431722f2a2efSAndy Whitcroft } 43184a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 43193705ce5bSJoe Perches 43203705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 43213705ce5bSJoe Perches 43223705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 43230a920b5bSAndy Whitcroft } 43243705ce5bSJoe Perches 43253705ce5bSJoe Perches if (($#elements % 2) == 0) { 43263705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 43273705ce5bSJoe Perches } 43283705ce5bSJoe Perches 4329194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4330194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 43313705ce5bSJoe Perches } 43323705ce5bSJoe Perches 43333705ce5bSJoe Perches 43340a920b5bSAndy Whitcroft } 43350a920b5bSAndy Whitcroft 4336786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4337d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4338786b6326SJoe Perches if (WARN("SPACING", 4339786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4340786b6326SJoe Perches $fix) { 4341194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4342786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4343786b6326SJoe Perches } 4344786b6326SJoe Perches } 4345786b6326SJoe Perches 4346f0a594c1SAndy Whitcroft# check for multiple assignments 4347f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4348000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4349000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4350f0a594c1SAndy Whitcroft } 4351f0a594c1SAndy Whitcroft 435222f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 435322f2a2efSAndy Whitcroft## # continuation. 435422f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 435522f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 435622f2a2efSAndy Whitcroft## 435722f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 435822f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 435922f2a2efSAndy Whitcroft## my $ln = $line; 436022f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 436122f2a2efSAndy Whitcroft## } 436222f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4363000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4364000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 436522f2a2efSAndy Whitcroft## } 436622f2a2efSAndy Whitcroft## } 4367f0a594c1SAndy Whitcroft 43680a920b5bSAndy Whitcroft#need space before brace following if, while, etc 43696b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 43704e5d56bdSEddie Kovsky $line =~ /do\{/) { 43713705ce5bSJoe Perches if (ERROR("SPACING", 43723705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 43733705ce5bSJoe Perches $fix) { 4374194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; 43753705ce5bSJoe Perches } 4376de7d4f0eSAndy Whitcroft } 4377de7d4f0eSAndy Whitcroft 4378c4a62ef9SJoe Perches## # check for blank lines before declarations 4379c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4380c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4381c4a62ef9SJoe Perches## WARN("SPACING", 4382c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4383c4a62ef9SJoe Perches## } 4384c4a62ef9SJoe Perches## 4385c4a62ef9SJoe Perches 4386de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4387de7d4f0eSAndy Whitcroft# on the line 4388de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 4389d5e616fcSJoe Perches if (ERROR("SPACING", 4390d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4391d5e616fcSJoe Perches $fix) { 4392194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4393d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4394d5e616fcSJoe Perches } 43950a920b5bSAndy Whitcroft } 43960a920b5bSAndy Whitcroft 439722f2a2efSAndy Whitcroft# check spacing on square brackets 439822f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 43993705ce5bSJoe Perches if (ERROR("SPACING", 44003705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 44013705ce5bSJoe Perches $fix) { 4402194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44033705ce5bSJoe Perches s/\[\s+/\[/; 44043705ce5bSJoe Perches } 440522f2a2efSAndy Whitcroft } 440622f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 44073705ce5bSJoe Perches if (ERROR("SPACING", 44083705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 44093705ce5bSJoe Perches $fix) { 4410194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44113705ce5bSJoe Perches s/\s+\]/\]/; 44123705ce5bSJoe Perches } 441322f2a2efSAndy Whitcroft } 441422f2a2efSAndy Whitcroft 4415c45dcabdSAndy Whitcroft# check spacing on parentheses 44169c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 44179c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 44183705ce5bSJoe Perches if (ERROR("SPACING", 44193705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 44203705ce5bSJoe Perches $fix) { 4421194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44223705ce5bSJoe Perches s/\(\s+/\(/; 44233705ce5bSJoe Perches } 442422f2a2efSAndy Whitcroft } 442513214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4426c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4427c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 44283705ce5bSJoe Perches if (ERROR("SPACING", 44293705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44303705ce5bSJoe Perches $fix) { 4431194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44323705ce5bSJoe Perches s/\s+\)/\)/; 44333705ce5bSJoe Perches } 443422f2a2efSAndy Whitcroft } 443522f2a2efSAndy Whitcroft 4436e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4437e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4438e2826fd0SJoe Perches 4439e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4440ea4acbb1SJoe Perches my $var = $1; 4441ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4442ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4443ea4acbb1SJoe Perches $fix) { 4444ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4445ea4acbb1SJoe Perches } 4446ea4acbb1SJoe Perches } 4447ea4acbb1SJoe Perches 4448ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4449ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4450ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4451ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4452ea4acbb1SJoe Perches my $var = $2; 4453ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4454ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4455ea4acbb1SJoe Perches $fix) { 4456ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4457ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4458ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4459ea4acbb1SJoe Perches } 4460e2826fd0SJoe Perches } 4461e2826fd0SJoe Perches 44620a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 44634a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 44640a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 44653705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 44663705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 44673705ce5bSJoe Perches $fix) { 4468194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44693705ce5bSJoe Perches s/^(.)\s+/$1/; 44703705ce5bSJoe Perches } 44710a920b5bSAndy Whitcroft } 44720a920b5bSAndy Whitcroft 44735b9553abSJoe Perches# return is not a function 4474507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4475c45dcabdSAndy Whitcroft my $spacing = $1; 4476507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 44775b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 44785b9553abSJoe Perches my $value = $1; 44795b9553abSJoe Perches $value = deparenthesize($value); 44805b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4481000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4482000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 44835b9553abSJoe Perches } 4484c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4485000d1cc1SJoe Perches ERROR("SPACING", 4486000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4487c45dcabdSAndy Whitcroft } 4488c45dcabdSAndy Whitcroft } 4489507e5141SJoe Perches 4490b43ae21bSJoe Perches# unnecessary return in a void function 4491b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4492b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4493b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4494b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4495b43ae21bSJoe Perches $linenr >= 3 && 4496b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4497b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 44989819cf25SJoe Perches WARN("RETURN_VOID", 4499b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 45009819cf25SJoe Perches } 45019819cf25SJoe Perches 4502189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4503189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4504189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4505189248d8SJoe Perches my $openparens = $1; 4506189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4507189248d8SJoe Perches my $msg = ""; 4508189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4509189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4510189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4511189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4512189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4513189248d8SJoe Perches } 4514189248d8SJoe Perches } 4515189248d8SJoe Perches 4516c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4517c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4518c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4519c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4520c5595fa2SJoe Perches if ($^V && $^V ge 5.10.0 && 4521c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4522c5595fa2SJoe Perches my $lead = $1; 4523c5595fa2SJoe Perches my $const = $2; 4524c5595fa2SJoe Perches my $comp = $3; 4525c5595fa2SJoe Perches my $to = $4; 4526c5595fa2SJoe Perches my $newcomp = $comp; 4527f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4528c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4529c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4530c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4531c5595fa2SJoe Perches $fix) { 4532c5595fa2SJoe Perches if ($comp eq "<") { 4533c5595fa2SJoe Perches $newcomp = ">"; 4534c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4535c5595fa2SJoe Perches $newcomp = ">="; 4536c5595fa2SJoe Perches } elsif ($comp eq ">") { 4537c5595fa2SJoe Perches $newcomp = "<"; 4538c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4539c5595fa2SJoe Perches $newcomp = "<="; 4540c5595fa2SJoe Perches } 4541c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4542c5595fa2SJoe Perches } 4543c5595fa2SJoe Perches } 4544c5595fa2SJoe Perches 4545f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4546f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 454753a3c448SAndy Whitcroft my $name = $1; 454853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4549000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4550f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 455153a3c448SAndy Whitcroft } 455253a3c448SAndy Whitcroft } 4553c45dcabdSAndy Whitcroft 45540a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 45554a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 45563705ce5bSJoe Perches if (ERROR("SPACING", 45573705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 45583705ce5bSJoe Perches $fix) { 4559194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45603705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 45613705ce5bSJoe Perches } 45620a920b5bSAndy Whitcroft } 45630a920b5bSAndy Whitcroft 4564f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4565f5fe35ddSAndy Whitcroft# statements after the conditional. 4566170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 45673e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 45683e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 45693e469cdcSAndy Whitcroft if (!defined $stat); 4570170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4571170d3a22SAndy Whitcroft $remain_next, $off_next); 4572170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4573170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4574170d3a22SAndy Whitcroft 4575170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4576170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4577170d3a22SAndy Whitcroft # then count those as offsets. 4578170d3a22SAndy Whitcroft my ($whitespace) = 4579170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4580170d3a22SAndy Whitcroft my $offset = 4581170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4582170d3a22SAndy Whitcroft 4583170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4584170d3a22SAndy Whitcroft $offset} = 1; 4585170d3a22SAndy Whitcroft } 4586170d3a22SAndy Whitcroft } 4587170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4588c11230f4SJoe Perches defined($stat) && defined($cond) && 4589170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4590171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 45918905a67cSAndy Whitcroft 4592b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4593000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4594000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 45958905a67cSAndy Whitcroft } 45968905a67cSAndy Whitcroft 45978905a67cSAndy Whitcroft # Find out what is on the end of the line after the 45988905a67cSAndy Whitcroft # conditional. 4599773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 46008905a67cSAndy Whitcroft $s =~ s/\n.*//g; 460113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 460253210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 460353210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4604773647a0SAndy Whitcroft { 4605bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4606bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4607bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 460842bdf74cSHidetoshi Seto my $stat_real = ''; 4609bb44ad39SAndy Whitcroft 461042bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 461142bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4612bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4613bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4614bb44ad39SAndy Whitcroft } 4615bb44ad39SAndy Whitcroft 4616000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4617000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 46188905a67cSAndy Whitcroft } 46198905a67cSAndy Whitcroft } 46208905a67cSAndy Whitcroft 462113214adfSAndy Whitcroft# Check for bitwise tests written as boolean 462213214adfSAndy Whitcroft if ($line =~ / 462313214adfSAndy Whitcroft (?: 462413214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 462513214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 462613214adfSAndy Whitcroft (?:\&\&|\|\|) 462713214adfSAndy Whitcroft | 462813214adfSAndy Whitcroft (?:\&\&|\|\|) 462913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 463013214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 463113214adfSAndy Whitcroft )/x) 463213214adfSAndy Whitcroft { 4633000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4634000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 463513214adfSAndy Whitcroft } 463613214adfSAndy Whitcroft 46378905a67cSAndy Whitcroft# if and else should not have general statements after it 463813214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 463913214adfSAndy Whitcroft my $s = $1; 464013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 464113214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4642000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4643000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 46440a920b5bSAndy Whitcroft } 464513214adfSAndy Whitcroft } 464639667782SAndy Whitcroft# if should not continue a brace 464739667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4648000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4649048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 465039667782SAndy Whitcroft $herecurr); 465139667782SAndy Whitcroft } 4652a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4653a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4654a1080bf8SAndy Whitcroft $line !~ /\G(?: 46553fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4656a1080bf8SAndy Whitcroft \s*return\s+ 4657a1080bf8SAndy Whitcroft )/xg) 4658a1080bf8SAndy Whitcroft { 4659000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4660000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4661a1080bf8SAndy Whitcroft } 46620a920b5bSAndy Whitcroft 46630a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 46640a920b5bSAndy Whitcroft # indent level to be relevant to each other. 46658b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 46660a920b5bSAndy Whitcroft $previndent == $indent) { 46678b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 46688b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 46698b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46708b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46718b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46728b8856f4SJoe Perches my $fixedline = $prevrawline; 46738b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 46748b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46758b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46768b8856f4SJoe Perches } 46778b8856f4SJoe Perches $fixedline = $rawline; 46788b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 46798b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46808b8856f4SJoe Perches } 46810a920b5bSAndy Whitcroft } 46820a920b5bSAndy Whitcroft 46838b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4684c2fdda0dSAndy Whitcroft $previndent == $indent) { 4685c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4686c2fdda0dSAndy Whitcroft 4687c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4688c2fdda0dSAndy Whitcroft # conditional. 4689773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4690c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4691c2fdda0dSAndy Whitcroft 4692c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 46938b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 46948b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 46958b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46968b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46978b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46988b8856f4SJoe Perches my $fixedline = $prevrawline; 46998b8856f4SJoe Perches my $trailing = $rawline; 47008b8856f4SJoe Perches $trailing =~ s/^\+//; 47018b8856f4SJoe Perches $trailing = trim($trailing); 47028b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 47038b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47048b8856f4SJoe Perches } 4705c2fdda0dSAndy Whitcroft } 4706c2fdda0dSAndy Whitcroft } 4707c2fdda0dSAndy Whitcroft 470895e2c602SJoe Perches#Specific variable tests 4709323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4710323c1260SJoe Perches my $var = $1; 471195e2c602SJoe Perches 471295e2c602SJoe Perches#gcc binary extension 471395e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4714d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4715d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4716d5e616fcSJoe Perches $fix) { 4717d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4718194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4719d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4720d5e616fcSJoe Perches } 472195e2c602SJoe Perches } 472295e2c602SJoe Perches 472395e2c602SJoe Perches#CamelCase 4724807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4725be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 472622735ce8SJoe Perches#Ignore Page<foo> variants 4727807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 472822735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4729f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4730f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4731f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47327e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 47337e781f67SJoe Perches my $word = $1; 47347e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4735d8b07710SJoe Perches if ($check) { 4736d8b07710SJoe Perches seed_camelcase_includes(); 4737d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4738d8b07710SJoe Perches seed_camelcase_file($realfile); 4739d8b07710SJoe Perches $camelcase_file_seeded = 1; 4740d8b07710SJoe Perches } 4741d8b07710SJoe Perches } 47427e781f67SJoe Perches if (!defined $camelcase{$word}) { 47437e781f67SJoe Perches $camelcase{$word} = 1; 4744be79794bSJoe Perches CHK("CAMELCASE", 47457e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 47467e781f67SJoe Perches } 4747323c1260SJoe Perches } 4748323c1260SJoe Perches } 47493445686aSJoe Perches } 47500a920b5bSAndy Whitcroft 47510a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4752d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4753d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4754d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4755d5e616fcSJoe Perches $fix) { 4756194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4757d5e616fcSJoe Perches } 47580a920b5bSAndy Whitcroft } 47590a920b5bSAndy Whitcroft 47600e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47610e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4762c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4763e09dec48SAndy Whitcroft my $file = "$1.h"; 4764e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4765e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4766e09dec48SAndy Whitcroft $realfile ne $checkfile && 47677840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4768c45dcabdSAndy Whitcroft { 47690e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 47700e212e0aSFabian Frederick if ($asminclude > 0) { 4771e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4772000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4773000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4774e09dec48SAndy Whitcroft } else { 4775000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4776000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4777e09dec48SAndy Whitcroft } 47780a920b5bSAndy Whitcroft } 47790a920b5bSAndy Whitcroft } 47800e212e0aSFabian Frederick } 47810a920b5bSAndy Whitcroft 4782653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4783653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4784cf655043SAndy Whitcroft# in a known good container 4785b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4786b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4787d8aaf121SAndy Whitcroft my $ln = $linenr; 4788d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4789c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4790c45dcabdSAndy Whitcroft my $ctx = ''; 479108a2843eSJoe Perches my $has_flow_statement = 0; 479208a2843eSJoe Perches my $has_arg_concat = 0; 4793c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4794f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4795f74bd194SAndy Whitcroft $ctx = $dstat; 4796c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4797a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4798c45dcabdSAndy Whitcroft 479908a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 480062e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 480108a2843eSJoe Perches 4802f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 4803f59b64bfSJoe Perches my $define_args = $1; 4804f59b64bfSJoe Perches my $define_stmt = $dstat; 4805f59b64bfSJoe Perches my @def_args = (); 4806f59b64bfSJoe Perches 4807f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 4808f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 4809f59b64bfSJoe Perches $define_args =~ s/\s*//g; 4810f59b64bfSJoe Perches @def_args = split(",", $define_args); 4811f59b64bfSJoe Perches } 4812f59b64bfSJoe Perches 4813292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4814c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4815c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4816c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4817c45dcabdSAndy Whitcroft 4818c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4819bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4820bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 48216b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 4822bf30d6edSAndy Whitcroft { 4823c45dcabdSAndy Whitcroft } 4824c45dcabdSAndy Whitcroft 4825e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 482633acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 482733acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 4828e45bab8eSAndy Whitcroft { 4829e45bab8eSAndy Whitcroft } 4830e45bab8eSAndy Whitcroft 483142e15293SJoe Perches # Make asm volatile uses seem like a generic function 483242e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 483342e15293SJoe Perches 4834c45dcabdSAndy Whitcroft my $exceptions = qr{ 4835c45dcabdSAndy Whitcroft $Declare| 4836c45dcabdSAndy Whitcroft module_param_named| 4837a0a0a7a9SKees Cook MODULE_PARM_DESC| 4838c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4839c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4840383099fdSAndy Whitcroft __typeof__\(| 484122fd2d3eSStefani Seibold union| 484222fd2d3eSStefani Seibold struct| 4843ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 48446b10df42SVladimir Zapolskiy ^\"|\"$| 48456b10df42SVladimir Zapolskiy ^\[ 4846c45dcabdSAndy Whitcroft }x; 48475eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4848f59b64bfSJoe Perches 4849f59b64bfSJoe Perches $ctx =~ s/\n*$//; 4850f59b64bfSJoe Perches my $herectx = $here . "\n"; 4851f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 4852f59b64bfSJoe Perches 4853f59b64bfSJoe Perches for (my $n = 0; $n < $stmt_cnt; $n++) { 4854f59b64bfSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4855f59b64bfSJoe Perches } 4856f59b64bfSJoe Perches 4857f74bd194SAndy Whitcroft if ($dstat ne '' && 4858f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4859f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48603cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4861356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4862f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4863f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4864e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 486572f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4866f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4867f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4868f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 48694e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 4870f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4871c45dcabdSAndy Whitcroft { 4872e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 4873e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4874e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 4875e795556aSJoe Perches } elsif ($dstat =~ /;/) { 4876f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4877f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4878f74bd194SAndy Whitcroft } else { 4879000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4880388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4881d8aaf121SAndy Whitcroft } 4882f59b64bfSJoe Perches 4883f59b64bfSJoe Perches } 48845207649bSJoe Perches 48855207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 48865207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 48875207649bSJoe Perches my $first = 1; 48885207649bSJoe Perches $define_stmt = ""; 48895207649bSJoe Perches foreach my $l (@stmt_array) { 48905207649bSJoe Perches $l =~ s/\\$//; 48915207649bSJoe Perches if ($first) { 48925207649bSJoe Perches $define_stmt = $l; 48935207649bSJoe Perches $first = 0; 48945207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 48955207649bSJoe Perches $define_stmt .= substr($l, 1); 48965207649bSJoe Perches } 48975207649bSJoe Perches } 48985207649bSJoe Perches $define_stmt =~ s/$;//g; 48995207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 49005207649bSJoe Perches $define_stmt = trim($define_stmt); 49015207649bSJoe Perches 4902f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 4903f59b64bfSJoe Perches foreach my $arg (@def_args) { 4904f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 49059192d41aSJoe Perches next if ($arg =~ /^type$/i); 4906f59b64bfSJoe Perches my $tmp = $define_stmt; 4907f59b64bfSJoe Perches $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49085207649bSJoe Perches $tmp =~ s/\#+\s*$arg\b//g; 4909f59b64bfSJoe Perches $tmp =~ s/\b$arg\s*\#\#//g; 4910f59b64bfSJoe Perches my $use_cnt = $tmp =~ s/\b$arg\b//g; 4911f59b64bfSJoe Perches if ($use_cnt > 1) { 4912f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 4913f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 4914f59b64bfSJoe Perches } 49159192d41aSJoe Perches# check if any macro arguments may have other precedence issues 49169192d41aSJoe Perches if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49179192d41aSJoe Perches ((defined($1) && $1 ne ',') || 49189192d41aSJoe Perches (defined($2) && $2 ne ','))) { 49199192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 49209192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49219192d41aSJoe Perches } 49220a920b5bSAndy Whitcroft } 49235023d347SJoe Perches 492408a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 492508a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 492608a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 492708a2843eSJoe Perches my $herectx = $here . "\n"; 492808a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 492908a2843eSJoe Perches 493008a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 493108a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 493208a2843eSJoe Perches } 493308a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 493408a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 493508a2843eSJoe Perches } 493608a2843eSJoe Perches 4937481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 49385023d347SJoe Perches 49395023d347SJoe Perches } else { 49405023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4941481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4942481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 49435023d347SJoe Perches $line =~ /^\+.*\\$/) { 49445023d347SJoe Perches WARN("LINE_CONTINUATIONS", 49455023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 49465023d347SJoe Perches } 4947653d4876SAndy Whitcroft } 49480a920b5bSAndy Whitcroft 4949b13edf7fSJoe Perches# do {} while (0) macro tests: 4950b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4951b13edf7fSJoe Perches# macro should not end with a semicolon 4952b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4953b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4954b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4955b13edf7fSJoe Perches my $ln = $linenr; 4956b13edf7fSJoe Perches my $cnt = $realcnt; 4957b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4958b13edf7fSJoe Perches my $ctx = ''; 4959b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4960b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4961b13edf7fSJoe Perches $ctx = $dstat; 4962b13edf7fSJoe Perches 4963b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 49641b36b201SJoe Perches $dstat =~ s/$;/ /g; 4965b13edf7fSJoe Perches 4966b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4967b13edf7fSJoe Perches my $stmts = $2; 4968b13edf7fSJoe Perches my $semis = $3; 4969b13edf7fSJoe Perches 4970b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4971b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4972b13edf7fSJoe Perches my $herectx = $here . "\n"; 4973b13edf7fSJoe Perches 4974b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4975b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4976b13edf7fSJoe Perches } 4977b13edf7fSJoe Perches 4978ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4979ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4980b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4981b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4982b13edf7fSJoe Perches } 4983b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4984b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4985b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 4986b13edf7fSJoe Perches } 4987f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 4988f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 4989f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 4990f5ef95b1SJoe Perches my $herectx = $here . "\n"; 4991f5ef95b1SJoe Perches 4992f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4993f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4994f5ef95b1SJoe Perches } 4995f5ef95b1SJoe Perches 4996f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 4997f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 4998b13edf7fSJoe Perches } 4999b13edf7fSJoe Perches } 5000b13edf7fSJoe Perches 5001080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5002080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 5003080ba929SMike Frysinger# . 5004080ba929SMike Frysinger# ALIGN(...) 5005080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 5006080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5007000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 5008000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5009080ba929SMike Frysinger } 5010080ba929SMike Frysinger 5011f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 501213214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 501313214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5014cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 501513214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5016cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5017cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5018aad4f614SJoe Perches my @allowed = (); 5019aad4f614SJoe Perches my $allow = 0; 502013214adfSAndy Whitcroft my $seen = 0; 5021773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5022cf655043SAndy Whitcroft my $ln = $linenr - 1; 502313214adfSAndy Whitcroft for my $chunk (@chunks) { 502413214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 502513214adfSAndy Whitcroft 5026773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5027773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5028773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5029773647a0SAndy Whitcroft 5030aad4f614SJoe Perches $allowed[$allow] = 0; 5031773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5032773647a0SAndy Whitcroft 5033773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5034773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5035773647a0SAndy Whitcroft 5036773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5037cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5038cf655043SAndy Whitcroft 5039773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 504013214adfSAndy Whitcroft 504113214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 504213214adfSAndy Whitcroft 5043aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5044cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5045cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5046aad4f614SJoe Perches $allowed[$allow] = 1; 504713214adfSAndy Whitcroft } 504813214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5049cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5050aad4f614SJoe Perches $allowed[$allow] = 1; 505113214adfSAndy Whitcroft } 5052cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5053cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5054aad4f614SJoe Perches $allowed[$allow] = 1; 505513214adfSAndy Whitcroft } 5056aad4f614SJoe Perches $allow++; 505713214adfSAndy Whitcroft } 5058aad4f614SJoe Perches if ($seen) { 5059aad4f614SJoe Perches my $sum_allowed = 0; 5060aad4f614SJoe Perches foreach (@allowed) { 5061aad4f614SJoe Perches $sum_allowed += $_; 5062aad4f614SJoe Perches } 5063aad4f614SJoe Perches if ($sum_allowed == 0) { 5064000d1cc1SJoe Perches WARN("BRACES", 5065000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5066aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5067aad4f614SJoe Perches $seen != $allow) { 5068aad4f614SJoe Perches CHK("BRACES", 5069aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5070aad4f614SJoe Perches } 507113214adfSAndy Whitcroft } 507213214adfSAndy Whitcroft } 507313214adfSAndy Whitcroft } 5074773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 507513214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5076cf655043SAndy Whitcroft my $allowed = 0; 5077f0a594c1SAndy Whitcroft 5078cf655043SAndy Whitcroft # Check the pre-context. 5079cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5080cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5081cf655043SAndy Whitcroft $allowed = 1; 5082f0a594c1SAndy Whitcroft } 5083773647a0SAndy Whitcroft 5084773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5085773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5086773647a0SAndy Whitcroft 5087cf655043SAndy Whitcroft # Check the condition. 5088cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5089773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5090cf655043SAndy Whitcroft if (defined $cond) { 5091773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5092cf655043SAndy Whitcroft } 5093cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5094cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5095cf655043SAndy Whitcroft $allowed = 1; 5096cf655043SAndy Whitcroft } 5097cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5098cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5099cf655043SAndy Whitcroft $allowed = 1; 5100cf655043SAndy Whitcroft } 5101cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5102cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5103cf655043SAndy Whitcroft $allowed = 1; 5104cf655043SAndy Whitcroft } 5105cf655043SAndy Whitcroft # Check the post-context. 5106cf655043SAndy Whitcroft if (defined $chunks[1]) { 5107cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5108cf655043SAndy Whitcroft if (defined $cond) { 5109773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5110cf655043SAndy Whitcroft } 5111cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5112cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5113cf655043SAndy Whitcroft $allowed = 1; 5114cf655043SAndy Whitcroft } 5115cf655043SAndy Whitcroft } 5116cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 511769932487SJustin P. Mattock my $herectx = $here . "\n"; 5118f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5119cf655043SAndy Whitcroft 5120f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 512169932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 5122cf655043SAndy Whitcroft } 5123cf655043SAndy Whitcroft 5124000d1cc1SJoe Perches WARN("BRACES", 5125000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5126f0a594c1SAndy Whitcroft } 5127f0a594c1SAndy Whitcroft } 5128f0a594c1SAndy Whitcroft 5129e4c5babdSJoe Perches# check for single line unbalanced braces 513095330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 513195330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5132e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5133e4c5babdSJoe Perches } 5134e4c5babdSJoe Perches 51350979ae66SJoe Perches# check for unnecessary blank lines around braces 513677b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5137f8e58219SJoe Perches if (CHK("BRACES", 5138f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5139f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5140f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5141f8e58219SJoe Perches } 51420979ae66SJoe Perches } 514377b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5144f8e58219SJoe Perches if (CHK("BRACES", 5145f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5146f8e58219SJoe Perches $fix) { 5147f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5148f8e58219SJoe Perches } 51490979ae66SJoe Perches } 51500979ae66SJoe Perches 51514a0df2efSAndy Whitcroft# no volatiles please 51526c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 51536c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5154000d1cc1SJoe Perches WARN("VOLATILE", 51558c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51564a0df2efSAndy Whitcroft } 51574a0df2efSAndy Whitcroft 51585e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 51595e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 51605e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51615e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 516233acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 51635e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 51645e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 51655e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 51665e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 51675e4f6ba5SJoe Perches $fix && 51685e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 51695e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 51705e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 51715e4f6ba5SJoe Perches my $comma_close = ""; 51725e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 51735e4f6ba5SJoe Perches $comma_close = $1; 51745e4f6ba5SJoe Perches } 51755e4f6ba5SJoe Perches 51765e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51775e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 51785e4f6ba5SJoe Perches my $fixedline = $prevrawline; 51795e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 51805e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 51815e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 51825e4f6ba5SJoe Perches $fixedline = $rawline; 51835e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 51845e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 51855e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51865e4f6ba5SJoe Perches } 51875e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 51885e4f6ba5SJoe Perches } 51895e4f6ba5SJoe Perches } 51905e4f6ba5SJoe Perches 51915e4f6ba5SJoe Perches# check for missing a space in a string concatenation 51925e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 51935e4f6ba5SJoe Perches WARN('MISSING_SPACE', 51945e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 51955e4f6ba5SJoe Perches } 51965e4f6ba5SJoe Perches 519777cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5198e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5199e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5200e4b7d309SJoe Perches# function declarations 520177cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 520277cb8546SJoe Perches defined($context_function) && 5203e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5204e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 520577cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5206e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 520777cb8546SJoe Perches } 520877cb8546SJoe Perches 52095e4f6ba5SJoe Perches# check for spaces before a quoted newline 52105e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 52115e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52125e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52135e4f6ba5SJoe Perches $fix) { 52145e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52155e4f6ba5SJoe Perches } 52165e4f6ba5SJoe Perches 52175e4f6ba5SJoe Perches } 52185e4f6ba5SJoe Perches 5219f17dba4fSJoe Perches# concatenated string without spaces between elements 522033acb54aSJoe Perches if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5221f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 5222f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 5223f17dba4fSJoe Perches } 5224f17dba4fSJoe Perches 522590ad30e5SJoe Perches# uncoalesced string fragments 522633acb54aSJoe Perches if ($line =~ /$String\s*"/) { 522790ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 522890ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 522990ad30e5SJoe Perches } 523090ad30e5SJoe Perches 5231522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5232522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5233522b837cSAlexey Dobriyan my $show_Z = 1; 52345e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5235522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52365e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5237522b837cSAlexey Dobriyan # check for %L 5238522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52395e4f6ba5SJoe Perches WARN("PRINTF_L", 5240522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5241522b837cSAlexey Dobriyan $show_L = 0; 52425e4f6ba5SJoe Perches } 5243522b837cSAlexey Dobriyan # check for %Z 5244522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5245522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5246522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5247522b837cSAlexey Dobriyan $show_Z = 0; 5248522b837cSAlexey Dobriyan } 5249522b837cSAlexey Dobriyan # check for 0x<decimal> 5250522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5251522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 52526e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 52536e300757SJoe Perches } 52545e4f6ba5SJoe Perches } 52555e4f6ba5SJoe Perches 52565e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 52575e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52585e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 52595e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 52605e4f6ba5SJoe Perches } 52615e4f6ba5SJoe Perches 526200df344fSAndy Whitcroft# warn about #if 0 5263c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5264000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 5265000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 5266de7d4f0eSAndy Whitcroft $herecurr); 52674a0df2efSAndy Whitcroft } 52684a0df2efSAndy Whitcroft 526903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 527003df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5271100425deSJoe Perches my $tested = quotemeta($1); 5272100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5273100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5274100425deSJoe Perches my $func = $1; 5275100425deSJoe Perches if (WARN('NEEDLESS_IF', 5276100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5277100425deSJoe Perches $fix) { 5278100425deSJoe Perches my $do_fix = 1; 5279100425deSJoe Perches my $leading_tabs = ""; 5280100425deSJoe Perches my $new_leading_tabs = ""; 5281100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5282100425deSJoe Perches $leading_tabs = $1; 5283100425deSJoe Perches } else { 5284100425deSJoe Perches $do_fix = 0; 5285100425deSJoe Perches } 5286100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5287100425deSJoe Perches $new_leading_tabs = $1; 5288100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5289100425deSJoe Perches $do_fix = 0; 5290100425deSJoe Perches } 5291100425deSJoe Perches } else { 5292100425deSJoe Perches $do_fix = 0; 5293100425deSJoe Perches } 5294100425deSJoe Perches if ($do_fix) { 5295100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5296100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5297100425deSJoe Perches } 5298100425deSJoe Perches } 52994c432a8fSGreg Kroah-Hartman } 53004c432a8fSGreg Kroah-Hartman } 5301f0a594c1SAndy Whitcroft 5302ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5303ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5304ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5305ebfdc409SJoe Perches (defined $1 || defined $3) && 5306ebfdc409SJoe Perches $linenr > 3) { 5307ebfdc409SJoe Perches my $testval = $2; 5308ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5309ebfdc409SJoe Perches 5310ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5311ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5312ebfdc409SJoe Perches 5313ebfdc409SJoe 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)/) { 5314ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5315ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5316ebfdc409SJoe Perches } 5317ebfdc409SJoe Perches } 5318ebfdc409SJoe Perches 5319f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5320dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5321f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5322f78d98f6SJoe Perches my $level = $1; 5323f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5324f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5325f78d98f6SJoe Perches $fix) { 5326f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5327f78d98f6SJoe Perches } 5328f78d98f6SJoe Perches } 5329f78d98f6SJoe Perches 533045c55e92SJoe Perches# check for logging continuations 533145c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 533245c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 533345c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 533445c55e92SJoe Perches } 533545c55e92SJoe Perches 5336abb08a53SJoe Perches# check for mask then right shift without a parentheses 5337abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 5338abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5339abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5340abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5341abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5342abb08a53SJoe Perches } 5343abb08a53SJoe Perches 5344b75ac618SJoe Perches# check for pointer comparisons to NULL 5345b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 5346b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5347b75ac618SJoe Perches my $val = $1; 5348b75ac618SJoe Perches my $equal = "!"; 5349b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5350b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5351b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5352b75ac618SJoe Perches $fix) { 5353b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5354b75ac618SJoe Perches } 5355b75ac618SJoe Perches } 5356b75ac618SJoe Perches } 5357b75ac618SJoe Perches 53588716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 53598716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 53608716de38SJoe Perches my $attr = $1; 53618716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 53628716de38SJoe Perches my $ptr = $1; 53638716de38SJoe Perches my $var = $2; 53648716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 53658716de38SJoe Perches ERROR("MISPLACED_INIT", 53668716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 53678716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 53688716de38SJoe Perches WARN("MISPLACED_INIT", 53698716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 53708716de38SJoe Perches $fix) { 5371194f66fcSJoe 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; 53728716de38SJoe Perches } 53738716de38SJoe Perches } 53748716de38SJoe Perches } 53758716de38SJoe Perches 5376e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5377e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5378e970b884SJoe Perches my $attr = $1; 5379e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5380e970b884SJoe Perches my $attr_prefix = $1; 5381e970b884SJoe Perches my $attr_type = $2; 5382e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5383e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5384e970b884SJoe Perches $fix) { 5385194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5386e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5387e970b884SJoe Perches } 5388e970b884SJoe Perches } 5389e970b884SJoe Perches 5390e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5391e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5392e970b884SJoe Perches my $attr = $1; 5393e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5394e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5395e970b884SJoe Perches $fix) { 5396194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5397e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5398e970b884SJoe Perches $lead = rtrim($1); 5399e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5400e970b884SJoe Perches $lead = "${lead}const "; 5401194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5402e970b884SJoe Perches } 5403e970b884SJoe Perches } 5404e970b884SJoe Perches 5405c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5406c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5407c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5408c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5409c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5410c17893c7SJoe Perches $fix) { 5411c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5412c17893c7SJoe Perches } 5413c17893c7SJoe Perches } 5414c17893c7SJoe Perches 5415fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5416fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5417fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5418fbdb8138SJoe Perches my $constant_func = $1; 5419fbdb8138SJoe Perches my $func = $constant_func; 5420fbdb8138SJoe Perches $func =~ s/^__constant_//; 5421fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5422fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5423fbdb8138SJoe Perches $fix) { 5424194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5425fbdb8138SJoe Perches } 5426fbdb8138SJoe Perches } 5427fbdb8138SJoe Perches 54281a15a250SPatrick Pannuto# prefer usleep_range over udelay 542937581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 543043c1d77cSJoe Perches my $delay = $1; 54311a15a250SPatrick Pannuto # ignore udelay's < 10, however 543243c1d77cSJoe Perches if (! ($delay < 10) ) { 5433000d1cc1SJoe Perches CHK("USLEEP_RANGE", 543443c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 543543c1d77cSJoe Perches } 543643c1d77cSJoe Perches if ($delay > 2000) { 543743c1d77cSJoe Perches WARN("LONG_UDELAY", 543843c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 54391a15a250SPatrick Pannuto } 54401a15a250SPatrick Pannuto } 54411a15a250SPatrick Pannuto 544209ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 544309ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 544409ef8725SPatrick Pannuto if ($1 < 20) { 5445000d1cc1SJoe Perches WARN("MSLEEP", 544643c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 544709ef8725SPatrick Pannuto } 544809ef8725SPatrick Pannuto } 544909ef8725SPatrick Pannuto 545036ec1939SJoe Perches# check for comparisons of jiffies 545136ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 545236ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 545336ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 545436ec1939SJoe Perches } 545536ec1939SJoe Perches 54569d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 54579d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54589d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 54599d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54609d7a34a5SJoe Perches } 54619d7a34a5SJoe Perches 546200df344fSAndy Whitcroft# warn about #ifdefs in C files 5463c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 546400df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 546500df344fSAndy Whitcroft# print "$herecurr"; 546600df344fSAndy Whitcroft# $clean = 0; 546700df344fSAndy Whitcroft# } 546800df344fSAndy Whitcroft 546922f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5470c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 54713705ce5bSJoe Perches if (ERROR("SPACING", 54723705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 54733705ce5bSJoe Perches $fix) { 5474194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54753705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 54763705ce5bSJoe Perches } 54773705ce5bSJoe Perches 547822f2a2efSAndy Whitcroft } 547922f2a2efSAndy Whitcroft 54804a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5481171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5482171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 54834a0df2efSAndy Whitcroft my $which = $1; 54844a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5485000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5486000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 54874a0df2efSAndy Whitcroft } 54884a0df2efSAndy Whitcroft } 54894a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5490402c2553SMichael S. Tsirkin 5491402c2553SMichael S. Tsirkin my $barriers = qr{ 5492402c2553SMichael S. Tsirkin mb| 5493402c2553SMichael S. Tsirkin rmb| 5494402c2553SMichael S. Tsirkin wmb| 5495402c2553SMichael S. Tsirkin read_barrier_depends 5496402c2553SMichael S. Tsirkin }x; 5497402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5498402c2553SMichael S. Tsirkin mb__before_atomic| 5499402c2553SMichael S. Tsirkin mb__after_atomic| 5500402c2553SMichael S. Tsirkin store_release| 5501402c2553SMichael S. Tsirkin load_acquire| 5502402c2553SMichael S. Tsirkin store_mb| 5503402c2553SMichael S. Tsirkin (?:$barriers) 5504402c2553SMichael S. Tsirkin }x; 5505402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5506402c2553SMichael S. Tsirkin (?:$barriers)| 550743e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 550843e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5509402c2553SMichael S. Tsirkin }x; 5510402c2553SMichael S. Tsirkin 5511402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 55124a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5513c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5514000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 55154a0df2efSAndy Whitcroft } 55164a0df2efSAndy Whitcroft } 55173ad81779SPaul E. McKenney 5518f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5519f4073b0fSMichael S. Tsirkin 5520f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5521f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5522f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5523f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5524f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5525f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5526f4073b0fSMichael S. Tsirkin } 5527f4073b0fSMichael S. Tsirkin 5528cb426e99SJoe Perches# check for waitqueue_active without a comment. 5529cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5530cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5531cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5532cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5533cb426e99SJoe Perches } 5534cb426e99SJoe Perches } 55353ad81779SPaul E. McKenney 55363ad81779SPaul E. McKenney# Check for expedited grace periods that interrupt non-idle non-nohz 55373ad81779SPaul E. McKenney# online CPUs. These expedited can therefore degrade real-time response 55383ad81779SPaul E. McKenney# if used carelessly, and should be avoided where not absolutely 55393ad81779SPaul E. McKenney# needed. It is always OK to use synchronize_rcu_expedited() and 55403ad81779SPaul E. McKenney# synchronize_sched_expedited() at boot time (before real-time applications 55413ad81779SPaul E. McKenney# start) and in error situations where real-time response is compromised in 55423ad81779SPaul E. McKenney# any case. Note that synchronize_srcu_expedited() does -not- interrupt 55433ad81779SPaul E. McKenney# other CPUs, so don't warn on uses of synchronize_srcu_expedited(). 55443ad81779SPaul E. McKenney# Of course, nothing comes for free, and srcu_read_lock() and 55453ad81779SPaul E. McKenney# srcu_read_unlock() do contain full memory barriers in payment for 55463ad81779SPaul E. McKenney# synchronize_srcu_expedited() non-interruption properties. 55473ad81779SPaul E. McKenney if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) { 55483ad81779SPaul E. McKenney WARN("EXPEDITED_RCU_GRACE_PERIOD", 55493ad81779SPaul E. McKenney "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr); 55503ad81779SPaul E. McKenney 55513ad81779SPaul E. McKenney } 55523ad81779SPaul E. McKenney 55534a0df2efSAndy Whitcroft# check of hardware specific defines 5554c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5555000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5556000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 55570a920b5bSAndy Whitcroft } 5558653d4876SAndy Whitcroft 5559d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 5560d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 5561000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5562000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 5563d4977c78STobias Klauser } 5564d4977c78STobias Klauser 5565de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5566de7d4f0eSAndy Whitcroft# storage class and type. 55679c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 55689c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5569000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5570000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5571de7d4f0eSAndy Whitcroft } 5572de7d4f0eSAndy Whitcroft 55738905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 55742b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55752b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5576d5e616fcSJoe Perches if (WARN("INLINE", 5577d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5578d5e616fcSJoe Perches $fix) { 5579194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5580d5e616fcSJoe Perches 5581d5e616fcSJoe Perches } 55828905a67cSAndy Whitcroft } 55838905a67cSAndy Whitcroft 55843d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 55852b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55862b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5587000d1cc1SJoe Perches WARN("PREFER_PACKED", 5588000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 55893d130fd0SJoe Perches } 55903d130fd0SJoe Perches 559139b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 55922b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55932b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5594000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5595000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 559639b7e287SJoe Perches } 559739b7e287SJoe Perches 55985f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 55992b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 56002b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5601d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5602d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5603d5e616fcSJoe Perches $fix) { 5604194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5605d5e616fcSJoe Perches 5606d5e616fcSJoe Perches } 56075f14d3bdSJoe Perches } 56085f14d3bdSJoe Perches 56096061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 56102b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 56112b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5612d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5613d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5614d5e616fcSJoe Perches $fix) { 5615194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5616d5e616fcSJoe Perches } 56176061d949SJoe Perches } 56186061d949SJoe Perches 5619619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 5620619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 5621619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5622619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5623619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5624619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5625619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5626619a908aSJoe Perches } 5627619a908aSJoe Perches 5628fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5629e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5630fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5631e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5632e6176fa4SJoe Perches my $type = $1; 5633e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5634e6176fa4SJoe Perches $type = $1; 5635e6176fa4SJoe Perches my $kernel_type = 'u'; 5636e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5637e6176fa4SJoe Perches $type =~ /(\d+)/; 5638e6176fa4SJoe Perches $kernel_type .= $1; 5639e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5640e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5641e6176fa4SJoe Perches $fix) { 5642e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5643e6176fa4SJoe Perches } 5644e6176fa4SJoe Perches } 5645e6176fa4SJoe Perches } 5646e6176fa4SJoe Perches 5647938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5648938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5649938224b5SJoe Perches my $cast = $1; 5650938224b5SJoe Perches my $const = $2; 5651938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5652938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5653938224b5SJoe Perches $fix) { 5654938224b5SJoe Perches my $suffix = ""; 5655938224b5SJoe Perches my $newconst = $const; 5656938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5657938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5658938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5659938224b5SJoe Perches $suffix .= 'LL'; 5660938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5661938224b5SJoe Perches $suffix .= 'L'; 5662938224b5SJoe Perches } 5663938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5664938224b5SJoe Perches } 5665938224b5SJoe Perches } 5666938224b5SJoe Perches 56678f53a9b8SJoe Perches# check for sizeof(&) 56688f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5669000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5670000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 56718f53a9b8SJoe Perches } 56728f53a9b8SJoe Perches 567366c80b60SJoe Perches# check for sizeof without parenthesis 567466c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5675d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5676d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5677d5e616fcSJoe Perches $fix) { 5678194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5679d5e616fcSJoe Perches } 568066c80b60SJoe Perches } 568166c80b60SJoe Perches 568288982feaSJoe Perches# check for struct spinlock declarations 568388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 568488982feaSJoe Perches WARN("USE_SPINLOCK_T", 568588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 568688982feaSJoe Perches } 568788982feaSJoe Perches 5688a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 568906668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5690a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5691caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5692caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5693d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5694d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5695d5e616fcSJoe Perches $fix) { 5696194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5697d5e616fcSJoe Perches } 5698a6962d72SJoe Perches } 5699a6962d72SJoe Perches } 5700a6962d72SJoe Perches 57010b523769SJoe Perches # check for vsprintf extension %p<foo> misuses 57020b523769SJoe Perches if ($^V && $^V ge 5.10.0 && 57030b523769SJoe Perches defined $stat && 57040b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 57050b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 57060b523769SJoe Perches my $bad_extension = ""; 57070b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 57080b523769SJoe Perches $lc = $lc + $linenr; 57090b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 57100b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 57110b523769SJoe Perches $fmt =~ s/%%//g; 5712*ce4fecf1SPantelis Antoniou if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 57130b523769SJoe Perches $bad_extension = $1; 57140b523769SJoe Perches last; 57150b523769SJoe Perches } 57160b523769SJoe Perches } 57170b523769SJoe Perches if ($bad_extension ne "") { 57180b523769SJoe Perches my $stat_real = raw_line($linenr, 0); 57190b523769SJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 57200b523769SJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 57210b523769SJoe Perches } 57220b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 57230b523769SJoe Perches "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57240b523769SJoe Perches } 57250b523769SJoe Perches } 57260b523769SJoe Perches 5727554e165cSAndy Whitcroft# Check for misused memsets 5728d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5729d1fe9c09SJoe Perches defined $stat && 57309e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5731554e165cSAndy Whitcroft 5732d7c76ba7SJoe Perches my $ms_addr = $2; 5733d1fe9c09SJoe Perches my $ms_val = $7; 5734d1fe9c09SJoe Perches my $ms_size = $12; 5735d7c76ba7SJoe Perches 5736554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5737554e165cSAndy Whitcroft ERROR("MEMSET", 5738d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5739554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5740554e165cSAndy Whitcroft WARN("MEMSET", 5741d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5742d7c76ba7SJoe Perches } 5743d7c76ba7SJoe Perches } 5744d7c76ba7SJoe Perches 574598a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5746f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5747f333195dSJoe Perches# defined $stat && 5748f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5749f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 5750f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 5751f333195dSJoe Perches# $fix) { 5752f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 5753f333195dSJoe Perches# } 5754f333195dSJoe Perches# } 575598a9bba5SJoe Perches 5756b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5757f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5758f333195dSJoe Perches# defined $stat && 5759f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5760f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 5761f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 5762f333195dSJoe Perches# } 5763b6117d17SMateusz Kulikowski 57648617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 57658617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5766f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5767f333195dSJoe Perches# defined $stat && 5768f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5769f333195dSJoe Perches# 5770f333195dSJoe Perches# my $ms_val = $7; 5771f333195dSJoe Perches# 5772f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 5773f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 5774f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 5775f333195dSJoe Perches# $fix) { 5776f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 5777f333195dSJoe Perches# } 5778f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 5779f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 5780f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 5781f333195dSJoe Perches# $fix) { 5782f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 5783f333195dSJoe Perches# } 5784f333195dSJoe Perches# } 5785f333195dSJoe Perches# } 57868617cd09SMateusz Kulikowski 5787d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5788d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5789d1fe9c09SJoe Perches defined $stat && 5790d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5791d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5792d7c76ba7SJoe Perches my $call = $1; 5793d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5794d7c76ba7SJoe Perches my $arg1 = $3; 5795d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5796d1fe9c09SJoe Perches my $arg2 = $8; 5797d7c76ba7SJoe Perches my $cast; 5798d7c76ba7SJoe Perches 5799d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5800d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5801d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5802d7c76ba7SJoe Perches $cast = $cast1; 5803d7c76ba7SJoe Perches } else { 5804d7c76ba7SJoe Perches $cast = $cast2; 5805d7c76ba7SJoe Perches } 5806d7c76ba7SJoe Perches WARN("MINMAX", 5807d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5808554e165cSAndy Whitcroft } 5809554e165cSAndy Whitcroft } 5810554e165cSAndy Whitcroft 58114a273195SJoe Perches# check usleep_range arguments 58124a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 58134a273195SJoe Perches defined $stat && 58144a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 58154a273195SJoe Perches my $min = $1; 58164a273195SJoe Perches my $max = $7; 58174a273195SJoe Perches if ($min eq $max) { 58184a273195SJoe Perches WARN("USLEEP_RANGE", 58194a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58204a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 58214a273195SJoe Perches $min > $max) { 58224a273195SJoe Perches WARN("USLEEP_RANGE", 58234a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58244a273195SJoe Perches } 58254a273195SJoe Perches } 58264a273195SJoe Perches 5827823b794cSJoe Perches# check for naked sscanf 5828823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5829823b794cSJoe Perches defined $stat && 58306c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5831823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5832823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5833823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5834823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5835823b794cSJoe Perches $lc = $lc + $linenr; 5836823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5837823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5838823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5839823b794cSJoe Perches } 5840823b794cSJoe Perches WARN("NAKED_SSCANF", 5841823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5842823b794cSJoe Perches } 5843823b794cSJoe Perches 5844afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5845afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5846afc819abSJoe Perches defined $stat && 5847afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5848afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5849afc819abSJoe Perches $lc = $lc + $linenr; 5850afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5851afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5852afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5853afc819abSJoe Perches } 5854afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5855afc819abSJoe Perches my $format = $6; 5856afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5857afc819abSJoe Perches if ($count == 1 && 5858afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5859afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5860afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5861afc819abSJoe Perches } 5862afc819abSJoe Perches } 5863afc819abSJoe Perches } 5864afc819abSJoe Perches 586570dc8a48SJoe Perches# check for new externs in .h files. 586670dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 586770dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5868d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 586970dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 587070dc8a48SJoe Perches $fix) { 5871194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 587270dc8a48SJoe Perches } 587370dc8a48SJoe Perches } 587470dc8a48SJoe Perches 5875de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5876171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5877c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5878171ae1a4SAndy Whitcroft { 5879c45dcabdSAndy Whitcroft my $function_name = $1; 5880c45dcabdSAndy Whitcroft my $paren_space = $2; 5881171ae1a4SAndy Whitcroft 5882171ae1a4SAndy Whitcroft my $s = $stat; 5883171ae1a4SAndy Whitcroft if (defined $cond) { 5884171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5885171ae1a4SAndy Whitcroft } 5886c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5887c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5888c45dcabdSAndy Whitcroft { 5889000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5890000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5891de7d4f0eSAndy Whitcroft } 5892de7d4f0eSAndy Whitcroft 5893171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5894000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5895000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5896171ae1a4SAndy Whitcroft } 58979c9ba34eSAndy Whitcroft 58989c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 58999c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 59009c9ba34eSAndy Whitcroft { 5901000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5902000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5903171ae1a4SAndy Whitcroft } 5904171ae1a4SAndy Whitcroft 5905ca0d8929SJoe Perches if ($realfile =~ /\.[ch]$/ && defined $stat && 5906ca0d8929SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 5907ca0d8929SJoe Perches $1 ne "void") { 5908ca0d8929SJoe Perches my $args = trim($1); 5909ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 5910ca0d8929SJoe Perches my $arg = trim($1); 5911ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 5912ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 5913ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 5914ca0d8929SJoe Perches } 5915ca0d8929SJoe Perches } 5916ca0d8929SJoe Perches } 5917ca0d8929SJoe Perches 5918de7d4f0eSAndy Whitcroft# checks for new __setup's 5919de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5920de7d4f0eSAndy Whitcroft my $name = $1; 5921de7d4f0eSAndy Whitcroft 5922de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5923000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 59248c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5925de7d4f0eSAndy Whitcroft } 5926653d4876SAndy Whitcroft } 59279c0ca6f9SAndy Whitcroft 59289c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5929caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5930000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5931000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 59329c0ca6f9SAndy Whitcroft } 593313214adfSAndy Whitcroft 5934a640d25cSJoe Perches# alloc style 5935a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5936a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5937a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5938a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5939a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5940a640d25cSJoe Perches } 5941a640d25cSJoe Perches 594260a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 594360a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 59441b4a2ed4SJoe Perches defined $stat && 59451b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 594660a55369SJoe Perches my $oldfunc = $3; 594760a55369SJoe Perches my $a1 = $4; 594860a55369SJoe Perches my $a2 = $10; 594960a55369SJoe Perches my $newfunc = "kmalloc_array"; 595060a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 595160a55369SJoe Perches my $r1 = $a1; 595260a55369SJoe Perches my $r2 = $a2; 595360a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 595460a55369SJoe Perches $r1 = $a2; 595560a55369SJoe Perches $r2 = $a1; 595660a55369SJoe Perches } 5957e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5958e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 59591b4a2ed4SJoe Perches my $ctx = ''; 59601b4a2ed4SJoe Perches my $herectx = $here . "\n"; 59611b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 59621b4a2ed4SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 59631b4a2ed4SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 59641b4a2ed4SJoe Perches } 5965e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 59661b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 59671b4a2ed4SJoe Perches $cnt == 1 && 5968e367455aSJoe Perches $fix) { 5969194f66fcSJoe 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; 597060a55369SJoe Perches } 597160a55369SJoe Perches } 597260a55369SJoe Perches } 597360a55369SJoe Perches 5974972fdea2SJoe Perches# check for krealloc arg reuse 5975972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5976972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5977972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5978972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 5979972fdea2SJoe Perches } 5980972fdea2SJoe Perches 59815ce59ae0SJoe Perches# check for alloc argument mismatch 59825ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 59835ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 59845ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 59855ce59ae0SJoe Perches } 59865ce59ae0SJoe Perches 5987caf2a54fSJoe Perches# check for multiple semicolons 5988caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 5989d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 5990d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 5991d5e616fcSJoe Perches $fix) { 5992194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 5993d5e616fcSJoe Perches } 5994d1e2ad07SJoe Perches } 5995d1e2ad07SJoe Perches 5996cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 5997cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 5998cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 59990ab90191SJoe Perches my $ull = ""; 60000ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 60010ab90191SJoe Perches if (CHK("BIT_MACRO", 60020ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 60030ab90191SJoe Perches $fix) { 60040ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 60050ab90191SJoe Perches } 60060ab90191SJoe Perches } 60070ab90191SJoe Perches 60082d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 60092d632745SJoe 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*$/) { 60102d632745SJoe Perches my $config = $1; 60112d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 60122d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 60132d632745SJoe Perches $fix) { 60142d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 60152d632745SJoe Perches } 60162d632745SJoe Perches } 60172d632745SJoe Perches 6018e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6019c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6020c34c09a8SJoe Perches my $has_break = 0; 6021c34c09a8SJoe Perches my $has_statement = 0; 6022c34c09a8SJoe Perches my $count = 0; 6023c34c09a8SJoe Perches my $prevline = $linenr; 6024e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6025c34c09a8SJoe Perches $prevline--; 6026c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6027c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6028c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6029c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6030c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6031c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6032c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6033c34c09a8SJoe Perches $has_statement = 1; 6034c34c09a8SJoe Perches $count++; 6035c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 6036c34c09a8SJoe Perches } 6037c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6038c34c09a8SJoe Perches WARN("MISSING_BREAK", 6039224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6040c34c09a8SJoe Perches } 6041c34c09a8SJoe Perches } 6042c34c09a8SJoe Perches 6043d1e2ad07SJoe Perches# check for switch/default statements without a break; 6044d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 6045d1e2ad07SJoe Perches defined $stat && 6046d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6047d1e2ad07SJoe Perches my $ctx = ''; 6048d1e2ad07SJoe Perches my $herectx = $here . "\n"; 6049d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6050d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6051d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 6052d1e2ad07SJoe Perches } 6053d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6054d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6055caf2a54fSJoe Perches } 6056caf2a54fSJoe Perches 605713214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6058d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6059d5e616fcSJoe Perches if (WARN("USE_FUNC", 6060d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6061d5e616fcSJoe Perches $fix) { 6062194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6063d5e616fcSJoe Perches } 606413214adfSAndy Whitcroft } 6065773647a0SAndy Whitcroft 606662ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 606762ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 606862ec818fSJoe Perches ERROR("DATE_TIME", 606962ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 607062ec818fSJoe Perches } 607162ec818fSJoe Perches 60722c92488aSJoe Perches# check for use of yield() 60732c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 60742c92488aSJoe Perches WARN("YIELD", 60752c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 60762c92488aSJoe Perches } 60772c92488aSJoe Perches 6078179f8f40SJoe Perches# check for comparisons against true and false 6079179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6080179f8f40SJoe Perches my $lead = $1; 6081179f8f40SJoe Perches my $arg = $2; 6082179f8f40SJoe Perches my $test = $3; 6083179f8f40SJoe Perches my $otype = $4; 6084179f8f40SJoe Perches my $trail = $5; 6085179f8f40SJoe Perches my $op = "!"; 6086179f8f40SJoe Perches 6087179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6088179f8f40SJoe Perches 6089179f8f40SJoe Perches my $type = lc($otype); 6090179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6091179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6092179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6093179f8f40SJoe Perches $op = ""; 6094179f8f40SJoe Perches } 6095179f8f40SJoe Perches 6096179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6097179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6098179f8f40SJoe Perches 6099179f8f40SJoe Perches## maybe suggesting a correct construct would better 6100179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6101179f8f40SJoe Perches 6102179f8f40SJoe Perches } 6103179f8f40SJoe Perches } 6104179f8f40SJoe Perches 61054882720bSThomas Gleixner# check for semaphores initialized locked 61064882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6107000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6108000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6109773647a0SAndy Whitcroft } 61106712d858SJoe Perches 611167d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 611267d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6113000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 611467d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6115773647a0SAndy Whitcroft } 61166712d858SJoe Perches 6117ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6118f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6119000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6120ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6121f3db6639SMichael Ellerman } 61226712d858SJoe Perches 61230f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6124d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 61256903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6126d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6127000d1cc1SJoe Perches WARN("CONST_STRUCT", 6128d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 61292b6db5cbSAndy Whitcroft } 6130773647a0SAndy Whitcroft 6131773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6132773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6133773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6134c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6135c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6136171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6137171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6138171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6139773647a0SAndy Whitcroft { 6140000d1cc1SJoe Perches WARN("NR_CPUS", 6141000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6142773647a0SAndy Whitcroft } 61439c9ba34eSAndy Whitcroft 614452ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 614552ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 614652ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 614752ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 614852ea8506SJoe Perches } 614952ea8506SJoe Perches 6150acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6151acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 6152acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6153acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6154acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6155acd9362cSJoe Perches } 6156acd9362cSJoe Perches 6157691d77b6SAndy Whitcroft# whine mightly about in_atomic 6158691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6159691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6160000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6161000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6162f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6163000d1cc1SJoe Perches WARN("IN_ATOMIC", 6164000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6165691d77b6SAndy Whitcroft } 6166691d77b6SAndy Whitcroft } 61671704f47bSPeter Zijlstra 6168481aea5cSJoe Perches# whine about ACCESS_ONCE 6169481aea5cSJoe Perches if ($^V && $^V ge 5.10.0 && 6170481aea5cSJoe Perches $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 6171481aea5cSJoe Perches my $par = $1; 6172481aea5cSJoe Perches my $eq = $2; 6173481aea5cSJoe Perches my $fun = $3; 6174481aea5cSJoe Perches $par =~ s/^\(\s*(.*)\s*\)$/$1/; 6175481aea5cSJoe Perches if (defined($eq)) { 6176481aea5cSJoe Perches if (WARN("PREFER_WRITE_ONCE", 6177481aea5cSJoe Perches "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 6178481aea5cSJoe Perches $fix) { 6179481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 6180481aea5cSJoe Perches } 6181481aea5cSJoe Perches } else { 6182481aea5cSJoe Perches if (WARN("PREFER_READ_ONCE", 6183481aea5cSJoe Perches "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 6184481aea5cSJoe Perches $fix) { 6185481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 6186481aea5cSJoe Perches } 6187481aea5cSJoe Perches } 6188481aea5cSJoe Perches } 6189481aea5cSJoe Perches 61900f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 61910f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 61920f5225b0SPeter Zijlstra ERROR("LOCKING", 61930f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 61940f5225b0SPeter Zijlstra } 61950f5225b0SPeter Zijlstra 61961704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 61971704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 61981704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 61991704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 62001704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 62011704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6202000d1cc1SJoe Perches ERROR("LOCKDEP", 6203000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 62041704f47bSPeter Zijlstra } 62051704f47bSPeter Zijlstra } 620688f8831cSDave Jones 6207b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6208b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6209000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6210000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 621188f8831cSDave Jones } 62122435880fSJoe Perches 6213515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6214515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 6215515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 6216459cf0aeSJoe Perches defined $stat && 6217515a235eSJoe Perches $line =~ /$mode_perms_search/) { 62182435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 62192435880fSJoe Perches my $func = $entry->[0]; 62202435880fSJoe Perches my $arg_pos = $entry->[1]; 62212435880fSJoe Perches 6222459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6223459cf0aeSJoe Perches $lc = $lc + $linenr; 6224459cf0aeSJoe Perches my $stat_real = raw_line($linenr, 0); 6225459cf0aeSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 6226459cf0aeSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 6227459cf0aeSJoe Perches } 6228459cf0aeSJoe Perches 62292435880fSJoe Perches my $skip_args = ""; 62302435880fSJoe Perches if ($arg_pos > 1) { 62312435880fSJoe Perches $arg_pos--; 62322435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62332435880fSJoe Perches } 6234f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6235459cf0aeSJoe Perches if ($stat =~ /$test/) { 62362435880fSJoe Perches my $val = $1; 62372435880fSJoe Perches $val = $6 if ($skip_args ne ""); 6238f90774e1SJoe Perches if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 6239f90774e1SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4)) { 62402435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6241459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6242f90774e1SJoe Perches } 6243f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6244c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6245459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 62462435880fSJoe Perches } 6247459cf0aeSJoe Perches } 6248459cf0aeSJoe Perches } 6249459cf0aeSJoe Perches } 6250459cf0aeSJoe Perches 6251459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6252459cf0aeSJoe Perches if ($line =~ /\b$mode_perms_string_search\b/) { 6253459cf0aeSJoe Perches my $val = ""; 6254459cf0aeSJoe Perches my $oval = ""; 6255f90774e1SJoe Perches my $to = 0; 6256459cf0aeSJoe Perches my $curpos = 0; 6257459cf0aeSJoe Perches my $lastpos = 0; 6258459cf0aeSJoe Perches while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 6259459cf0aeSJoe Perches $curpos = pos($line); 6260459cf0aeSJoe Perches my $match = $2; 6261459cf0aeSJoe Perches my $omatch = $1; 6262459cf0aeSJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 6263459cf0aeSJoe Perches $lastpos = $curpos; 6264459cf0aeSJoe Perches $to |= $mode_permission_string_types{$match}; 6265459cf0aeSJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 6266459cf0aeSJoe Perches $val .= $match; 6267459cf0aeSJoe Perches $oval .= $omatch; 6268f90774e1SJoe Perches } 6269459cf0aeSJoe Perches $oval =~ s/^\s*\|\s*//; 6270459cf0aeSJoe Perches $oval =~ s/\s*\|\s*$//; 6271459cf0aeSJoe Perches my $octal = sprintf("%04o", $to); 6272f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6273459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6274f90774e1SJoe Perches $fix) { 6275459cf0aeSJoe Perches $fixed[$fixlinenr] =~ s/$val/$octal/; 62762435880fSJoe Perches } 627713214adfSAndy Whitcroft } 62785a6d20ceSBjorn Andersson 62795a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 62805a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 62815a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 62825a6d20ceSBjorn Andersson my $valid_licenses = qr{ 62835a6d20ceSBjorn Andersson GPL| 62845a6d20ceSBjorn Andersson GPL\ v2| 62855a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 62865a6d20ceSBjorn Andersson Dual\ BSD/GPL| 62875a6d20ceSBjorn Andersson Dual\ MIT/GPL| 62885a6d20ceSBjorn Andersson Dual\ MPL/GPL| 62895a6d20ceSBjorn Andersson Proprietary 62905a6d20ceSBjorn Andersson }x; 62915a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 62925a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 62935a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 62945a6d20ceSBjorn Andersson } 62955a6d20ceSBjorn Andersson } 6296515a235eSJoe Perches } 629713214adfSAndy Whitcroft 629813214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 629913214adfSAndy Whitcroft # so just keep quiet. 630013214adfSAndy Whitcroft if ($#rawlines == -1) { 630113214adfSAndy Whitcroft exit(0); 63020a920b5bSAndy Whitcroft } 63030a920b5bSAndy Whitcroft 63048905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 63058905a67cSAndy Whitcroft # things that appear to be patches. 63068905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 63078905a67cSAndy Whitcroft exit(0); 63088905a67cSAndy Whitcroft } 63098905a67cSAndy Whitcroft 63108905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 63118905a67cSAndy Whitcroft # just keep quiet. 63128905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 63138905a67cSAndy Whitcroft exit(0); 63148905a67cSAndy Whitcroft } 63158905a67cSAndy Whitcroft 631606330fc4SJoe Perches if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6317000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6318000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 63190a920b5bSAndy Whitcroft } 6320ed43c4e5SAllen Hubbe if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6321000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6322000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 63230a920b5bSAndy Whitcroft } 63240a920b5bSAndy Whitcroft 6325f0a594c1SAndy Whitcroft print report_dump(); 632613214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 632713214adfSAndy Whitcroft print "$filename " if ($summary_file); 63286c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 63296c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 63306c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 63316c72ffaaSAndy Whitcroft } 63328905a67cSAndy Whitcroft 6333d2c0a235SAndy Whitcroft if ($quiet == 0) { 6334ef212196SJoe Perches # If there were any defects found and not already fixing them 6335ef212196SJoe Perches if (!$clean and !$fix) { 6336ef212196SJoe Perches print << "EOM" 6337ef212196SJoe Perches 6338ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6339ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6340ef212196SJoe PerchesEOM 6341ef212196SJoe Perches } 6342d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6343d2c0a235SAndy Whitcroft # then suggest that. 6344d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6345b0781216SMike Frysinger $rpt_cleaners = 0; 6346d8469f16SJoe Perches print << "EOM" 6347d8469f16SJoe Perches 6348d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6349d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6350d8469f16SJoe PerchesEOM 6351d2c0a235SAndy Whitcroft } 6352d2c0a235SAndy Whitcroft } 6353d2c0a235SAndy Whitcroft 6354d752fcc8SJoe Perches if ($clean == 0 && $fix && 6355d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6356d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 63579624b8d6SJoe Perches my $newfile = $filename; 63589624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 63593705ce5bSJoe Perches my $linecount = 0; 63603705ce5bSJoe Perches my $f; 63613705ce5bSJoe Perches 6362d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6363d752fcc8SJoe Perches 63643705ce5bSJoe Perches open($f, '>', $newfile) 63653705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 63663705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 63673705ce5bSJoe Perches $linecount++; 63683705ce5bSJoe Perches if ($file) { 63693705ce5bSJoe Perches if ($linecount > 3) { 63703705ce5bSJoe Perches $fixed_line =~ s/^\+//; 63713705ce5bSJoe Perches print $f $fixed_line . "\n"; 63723705ce5bSJoe Perches } 63733705ce5bSJoe Perches } else { 63743705ce5bSJoe Perches print $f $fixed_line . "\n"; 63753705ce5bSJoe Perches } 63763705ce5bSJoe Perches } 63773705ce5bSJoe Perches close($f); 63783705ce5bSJoe Perches 63793705ce5bSJoe Perches if (!$quiet) { 63803705ce5bSJoe Perches print << "EOM"; 6381d8469f16SJoe Perches 63823705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 63833705ce5bSJoe Perches 63843705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 63853705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 63863705ce5bSJoe Perches 63873705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 63883705ce5bSJoe PerchesNo warranties, expressed or implied... 63893705ce5bSJoe PerchesEOM 63903705ce5bSJoe Perches } 63913705ce5bSJoe Perches } 63923705ce5bSJoe Perches 6393d8469f16SJoe Perches if ($quiet == 0) { 6394d8469f16SJoe Perches print "\n"; 6395d8469f16SJoe Perches if ($clean == 1) { 6396d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6397d8469f16SJoe Perches } else { 6398d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 63990a920b5bSAndy Whitcroft } 64000a920b5bSAndy Whitcroft } 64010a920b5bSAndy Whitcroft return $clean; 64020a920b5bSAndy Whitcroft} 6403