1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 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; 9cb77f0d6SKamil Rytarowskiuse warnings; 10c707a81dSJoe Perchesuse POSIX; 1136061e38SJoe Perchesuse File::Basename; 1236061e38SJoe Perchesuse Cwd 'abs_path'; 1357230297SJoe Perchesuse Term::ANSIColor qw(:constants); 140a920b5bSAndy Whitcroft 150a920b5bSAndy Whitcroftmy $P = $0; 1636061e38SJoe Perchesmy $D = dirname(abs_path($P)); 170a920b5bSAndy Whitcroft 18000d1cc1SJoe Perchesmy $V = '0.32'; 190a920b5bSAndy Whitcroft 200a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 210a920b5bSAndy Whitcroft 220a920b5bSAndy Whitcroftmy $quiet = 0; 230a920b5bSAndy Whitcroftmy $tree = 1; 240a920b5bSAndy Whitcroftmy $chk_signoff = 1; 250a920b5bSAndy Whitcroftmy $chk_patch = 1; 26773647a0SAndy Whitcroftmy $tst_only; 276c72ffaaSAndy Whitcroftmy $emacs = 0; 288905a67cSAndy Whitcroftmy $terse = 0; 2934d8815fSJoe Perchesmy $showfile = 0; 306c72ffaaSAndy Whitcroftmy $file = 0; 314a593c34SDu, Changbinmy $git = 0; 320dea9f1eSJoe Perchesmy %git_commits = (); 336c72ffaaSAndy Whitcroftmy $check = 0; 342ac73b4fSJoe Perchesmy $check_orig = 0; 358905a67cSAndy Whitcroftmy $summary = 1; 368905a67cSAndy Whitcroftmy $mailback = 0; 3713214adfSAndy Whitcroftmy $summary_file = 0; 38000d1cc1SJoe Perchesmy $show_types = 0; 393beb42ecSJoe Perchesmy $list_types = 0; 403705ce5bSJoe Perchesmy $fix = 0; 419624b8d6SJoe Perchesmy $fix_inplace = 0; 426c72ffaaSAndy Whitcroftmy $root; 43c2fdda0dSAndy Whitcroftmy %debug; 443445686aSJoe Perchesmy %camelcase = (); 4591bfe484SJoe Perchesmy %use_type = (); 4691bfe484SJoe Perchesmy @use = (); 4791bfe484SJoe Perchesmy %ignore_type = (); 48000d1cc1SJoe Perchesmy @ignore = (); 4977f5b10aSHannes Edermy $help = 0; 50000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 516cd7f386SJoe Perchesmy $max_line_length = 80; 52d62a201fSDave Hansenmy $ignore_perl_version = 0; 53d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0; 5456193274SVadim Bendeburymy $min_conf_desc_length = 4; 5566b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt"; 56ebfd7d62SJoe Perchesmy $codespell = 0; 57f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt"; 58bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch"; 5975ad8c57SJerome Forissiermy $typedefsfile = ""; 6057230297SJoe Perchesmy $color = 1; 61dadf680dSJoe Perchesmy $allow_c99_comments = 1; 6277f5b10aSHannes Eder 6377f5b10aSHannes Edersub help { 6477f5b10aSHannes Eder my ($exitcode) = @_; 6577f5b10aSHannes Eder 6677f5b10aSHannes Eder print << "EOM"; 6777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 6877f5b10aSHannes EderVersion: $V 6977f5b10aSHannes Eder 7077f5b10aSHannes EderOptions: 7177f5b10aSHannes Eder -q, --quiet quiet 7277f5b10aSHannes Eder --no-tree run without a kernel tree 7377f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 7477f5b10aSHannes Eder --patch treat FILE as patchfile (default) 7577f5b10aSHannes Eder --emacs emacs compile window format 7677f5b10aSHannes Eder --terse one line per report 7734d8815fSJoe Perches --showfile emit diffed file position, not input file position 784a593c34SDu, Changbin -g, --git treat FILE as a single commit or git revision range 794a593c34SDu, Changbin single git commit with: 804a593c34SDu, Changbin <rev> 814a593c34SDu, Changbin <rev>^ 824a593c34SDu, Changbin <rev>~n 834a593c34SDu, Changbin multiple git commits with: 844a593c34SDu, Changbin <rev1>..<rev2> 854a593c34SDu, Changbin <rev1>...<rev2> 864a593c34SDu, Changbin <rev>-<count> 874a593c34SDu, Changbin git merges are ignored 8877f5b10aSHannes Eder -f, --file treat FILE as regular source file 8977f5b10aSHannes Eder --subjective, --strict enable more subjective tests 903beb42ecSJoe Perches --list-types list the possible message types 9191bfe484SJoe Perches --types TYPE(,TYPE2...) show only these comma separated message types 92000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 933beb42ecSJoe Perches --show-types show the specific message type in the output 946cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 9556193274SVadim Bendebury --min-conf-desc-length=n set the min description length, if shorter, warn 9677f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 9777f5b10aSHannes Eder --no-summary suppress the per-file summary 9877f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 9977f5b10aSHannes Eder --summary-file include the filename in summary 10077f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 10177f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 10277f5b10aSHannes Eder is all off) 10377f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 10477f5b10aSHannes Eder literally 1053705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 1063705ce5bSJoe Perches If correctable single-line errors exist, create 1073705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 1083705ce5bSJoe Perches with potential errors corrected to the preferred 1093705ce5bSJoe Perches checkpatch style 1109624b8d6SJoe Perches --fix-inplace EXPERIMENTAL - may create horrible results 1119624b8d6SJoe Perches Is the same as --fix, but overwrites the input 1129624b8d6SJoe Perches file. It's your fault if there's no backup or git 113d62a201fSDave Hansen --ignore-perl-version override checking of perl version. expect 114d62a201fSDave Hansen runtime errors. 115ebfd7d62SJoe Perches --codespell Use the codespell dictionary for spelling/typos 116f1a63678SMaxim Uvarov (default:/usr/share/codespell/dictionary.txt) 117ebfd7d62SJoe Perches --codespellfile Use this codespell dictionary 11875ad8c57SJerome Forissier --typedefsfile Read additional types from this file 11957230297SJoe Perches --color Use colors when output is STDOUT (default: on) 12077f5b10aSHannes Eder -h, --help, --version display this help and exit 12177f5b10aSHannes Eder 12277f5b10aSHannes EderWhen FILE is - read standard input. 12377f5b10aSHannes EderEOM 12477f5b10aSHannes Eder 12577f5b10aSHannes Eder exit($exitcode); 12677f5b10aSHannes Eder} 12777f5b10aSHannes Eder 1283beb42ecSJoe Perchessub uniq { 1293beb42ecSJoe Perches my %seen; 1303beb42ecSJoe Perches return grep { !$seen{$_}++ } @_; 1313beb42ecSJoe Perches} 1323beb42ecSJoe Perches 1333beb42ecSJoe Perchessub list_types { 1343beb42ecSJoe Perches my ($exitcode) = @_; 1353beb42ecSJoe Perches 1363beb42ecSJoe Perches my $count = 0; 1373beb42ecSJoe Perches 1383beb42ecSJoe Perches local $/ = undef; 1393beb42ecSJoe Perches 1403beb42ecSJoe Perches open(my $script, '<', abs_path($P)) or 1413beb42ecSJoe Perches die "$P: Can't read '$P' $!\n"; 1423beb42ecSJoe Perches 1433beb42ecSJoe Perches my $text = <$script>; 1443beb42ecSJoe Perches close($script); 1453beb42ecSJoe Perches 1463beb42ecSJoe Perches my @types = (); 1473beb42ecSJoe Perches for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) { 1483beb42ecSJoe Perches push (@types, $_); 1493beb42ecSJoe Perches } 1503beb42ecSJoe Perches @types = sort(uniq(@types)); 1513beb42ecSJoe Perches print("#\tMessage type\n\n"); 1523beb42ecSJoe Perches foreach my $type (@types) { 1533beb42ecSJoe Perches print(++$count . "\t" . $type . "\n"); 1543beb42ecSJoe Perches } 1553beb42ecSJoe Perches 1563beb42ecSJoe Perches exit($exitcode); 1573beb42ecSJoe Perches} 1583beb42ecSJoe Perches 159000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 160000d1cc1SJoe Perchesif (-f $conf) { 161000d1cc1SJoe Perches my @conf_args; 162000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 163000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 164000d1cc1SJoe Perches 165000d1cc1SJoe Perches while (<$conffile>) { 166000d1cc1SJoe Perches my $line = $_; 167000d1cc1SJoe Perches 168000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 169000d1cc1SJoe Perches $line =~ s/^\s*//g; 170000d1cc1SJoe Perches $line =~ s/\s+/ /g; 171000d1cc1SJoe Perches 172000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 173000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 174000d1cc1SJoe Perches 175000d1cc1SJoe Perches my @words = split(" ", $line); 176000d1cc1SJoe Perches foreach my $word (@words) { 177000d1cc1SJoe Perches last if ($word =~ m/^#/); 178000d1cc1SJoe Perches push (@conf_args, $word); 179000d1cc1SJoe Perches } 180000d1cc1SJoe Perches } 181000d1cc1SJoe Perches close($conffile); 182000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 183000d1cc1SJoe Perches} 184000d1cc1SJoe Perches 1850a920b5bSAndy WhitcroftGetOptions( 1866c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 1870a920b5bSAndy Whitcroft 'tree!' => \$tree, 1880a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 1890a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 1906c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 1918905a67cSAndy Whitcroft 'terse!' => \$terse, 19234d8815fSJoe Perches 'showfile!' => \$showfile, 19377f5b10aSHannes Eder 'f|file!' => \$file, 1944a593c34SDu, Changbin 'g|git!' => \$git, 1956c72ffaaSAndy Whitcroft 'subjective!' => \$check, 1966c72ffaaSAndy Whitcroft 'strict!' => \$check, 197000d1cc1SJoe Perches 'ignore=s' => \@ignore, 19891bfe484SJoe Perches 'types=s' => \@use, 199000d1cc1SJoe Perches 'show-types!' => \$show_types, 2003beb42ecSJoe Perches 'list-types!' => \$list_types, 2016cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 20256193274SVadim Bendebury 'min-conf-desc-length=i' => \$min_conf_desc_length, 2036c72ffaaSAndy Whitcroft 'root=s' => \$root, 2048905a67cSAndy Whitcroft 'summary!' => \$summary, 2058905a67cSAndy Whitcroft 'mailback!' => \$mailback, 20613214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 2073705ce5bSJoe Perches 'fix!' => \$fix, 2089624b8d6SJoe Perches 'fix-inplace!' => \$fix_inplace, 209d62a201fSDave Hansen 'ignore-perl-version!' => \$ignore_perl_version, 210c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 211773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 212ebfd7d62SJoe Perches 'codespell!' => \$codespell, 213ebfd7d62SJoe Perches 'codespellfile=s' => \$codespellfile, 21475ad8c57SJerome Forissier 'typedefsfile=s' => \$typedefsfile, 21557230297SJoe Perches 'color!' => \$color, 21677f5b10aSHannes Eder 'h|help' => \$help, 21777f5b10aSHannes Eder 'version' => \$help 21877f5b10aSHannes Eder) or help(1); 21977f5b10aSHannes Eder 22077f5b10aSHannes Ederhelp(0) if ($help); 2210a920b5bSAndy Whitcroft 2223beb42ecSJoe Percheslist_types(0) if ($list_types); 2233beb42ecSJoe Perches 2249624b8d6SJoe Perches$fix = 1 if ($fix_inplace); 2252ac73b4fSJoe Perches$check_orig = $check; 2269624b8d6SJoe Perches 2270a920b5bSAndy Whitcroftmy $exit = 0; 2280a920b5bSAndy Whitcroft 229d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) { 230d62a201fSDave Hansen printf "$P: requires at least perl version %vd\n", $minimum_perl_version; 231d62a201fSDave Hansen if (!$ignore_perl_version) { 232d62a201fSDave Hansen exit(1); 233d62a201fSDave Hansen } 234d62a201fSDave Hansen} 235d62a201fSDave Hansen 23645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin 2370a920b5bSAndy Whitcroftif ($#ARGV < 0) { 23845107ff6SAllen Hubbe push(@ARGV, '-'); 2390a920b5bSAndy Whitcroft} 2400a920b5bSAndy Whitcroft 24191bfe484SJoe Perchessub hash_save_array_words { 24291bfe484SJoe Perches my ($hashRef, $arrayRef) = @_; 24391bfe484SJoe Perches 24491bfe484SJoe Perches my @array = split(/,/, join(',', @$arrayRef)); 24591bfe484SJoe Perches foreach my $word (@array) { 246000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 247000d1cc1SJoe Perches $word =~ s/^\s*//g; 248000d1cc1SJoe Perches $word =~ s/\s+/ /g; 249000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 250000d1cc1SJoe Perches 251000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 252000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 253000d1cc1SJoe Perches 25491bfe484SJoe Perches $hashRef->{$word}++; 255000d1cc1SJoe Perches } 25691bfe484SJoe Perches} 25791bfe484SJoe Perches 25891bfe484SJoe Perchessub hash_show_words { 25991bfe484SJoe Perches my ($hashRef, $prefix) = @_; 26091bfe484SJoe Perches 2613c816e49SJoe Perches if (keys %$hashRef) { 262d8469f16SJoe Perches print "\nNOTE: $prefix message types:"; 26358cb3cf6SJoe Perches foreach my $word (sort keys %$hashRef) { 26491bfe484SJoe Perches print " $word"; 26591bfe484SJoe Perches } 266d8469f16SJoe Perches print "\n"; 26791bfe484SJoe Perches } 26891bfe484SJoe Perches} 26991bfe484SJoe Perches 27091bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore); 27191bfe484SJoe Percheshash_save_array_words(\%use_type, \@use); 272000d1cc1SJoe Perches 273c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 274c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 2757429c690SAndy Whitcroftmy $dbg_type = 0; 276a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 277c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 27821caa13cSAndy Whitcroft ## no critic 27921caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 28021caa13cSAndy Whitcroft die "$@" if ($@); 281c2fdda0dSAndy Whitcroft} 282c2fdda0dSAndy Whitcroft 283d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 284d2c0a235SAndy Whitcroft 2858905a67cSAndy Whitcroftif ($terse) { 2868905a67cSAndy Whitcroft $emacs = 1; 2878905a67cSAndy Whitcroft $quiet++; 2888905a67cSAndy Whitcroft} 2898905a67cSAndy Whitcroft 2906c72ffaaSAndy Whitcroftif ($tree) { 2916c72ffaaSAndy Whitcroft if (defined $root) { 2926c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 2936c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 2946c72ffaaSAndy Whitcroft } 2956c72ffaaSAndy Whitcroft } else { 2966c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 2976c72ffaaSAndy Whitcroft $root = '.'; 2986c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 2996c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 3006c72ffaaSAndy Whitcroft $root = $1; 3016c72ffaaSAndy Whitcroft } 3026c72ffaaSAndy Whitcroft } 3036c72ffaaSAndy Whitcroft 3046c72ffaaSAndy Whitcroft if (!defined $root) { 3050a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 3060a920b5bSAndy Whitcroft exit(2); 3070a920b5bSAndy Whitcroft } 3086c72ffaaSAndy Whitcroft} 3096c72ffaaSAndy Whitcroft 3106c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 3116c72ffaaSAndy Whitcroft 3122ceb532bSAndy Whitcroftour $Ident = qr{ 3132ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 3142ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 3152ceb532bSAndy Whitcroft }x; 3166c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 3176c72ffaaSAndy Whitcroftour $Sparse = qr{ 3186c72ffaaSAndy Whitcroft __user| 3196c72ffaaSAndy Whitcroft __kernel| 3206c72ffaaSAndy Whitcroft __force| 3216c72ffaaSAndy Whitcroft __iomem| 3226c72ffaaSAndy Whitcroft __must_check| 3236c72ffaaSAndy Whitcroft __init_refok| 324417495edSAndy Whitcroft __kprobes| 325165e72a6SSven Eckelmann __ref| 326ad315455SBoqun Feng __rcu| 327ad315455SBoqun Feng __private 3286c72ffaaSAndy Whitcroft }x; 329e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; 330e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; 331e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; 332e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; 333e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; 3348716de38SJoe Perches 33552131292SWolfram Sang# Notes to $Attribute: 33652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 3376c72ffaaSAndy Whitcroftour $Attribute = qr{ 3386c72ffaaSAndy Whitcroft const| 33903f1df7dSJoe Perches __percpu| 34003f1df7dSJoe Perches __nocast| 34103f1df7dSJoe Perches __safe| 34246d832f5SMichael S. Tsirkin __bitwise| 34303f1df7dSJoe Perches __packed__| 34403f1df7dSJoe Perches __packed2__| 34503f1df7dSJoe Perches __naked| 34603f1df7dSJoe Perches __maybe_unused| 34703f1df7dSJoe Perches __always_unused| 34803f1df7dSJoe Perches __noreturn| 34903f1df7dSJoe Perches __used| 35003f1df7dSJoe Perches __cold| 351e23ef1f3SJoe Perches __pure| 35203f1df7dSJoe Perches __noclone| 35303f1df7dSJoe Perches __deprecated| 3546c72ffaaSAndy Whitcroft __read_mostly| 3556c72ffaaSAndy Whitcroft __kprobes| 3568716de38SJoe Perches $InitAttribute| 35724e1d81aSAndy Whitcroft ____cacheline_aligned| 35824e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 3595fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 3605fe3af11SAndy Whitcroft __weak 3616c72ffaaSAndy Whitcroft }x; 362c45dcabdSAndy Whitcroftour $Modifier; 36391cb5195SJoe Perchesour $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; 3646c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 3656c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 3666c72ffaaSAndy Whitcroft 36795e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 36895e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 36995e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 37095e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 3712435880fSJoe Perchesour $Octal = qr{0[0-7]+$Int_type?}; 372c0a5c898SJoe Perchesour $String = qr{"[X\t]*"}; 373326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 374326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 375326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 37674349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 3772435880fSJoe Perchesour $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; 378326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 379447432f3SJoe Perchesour $Compare = qr{<=|>=|==|!=|<|(?<!-)>}; 38023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 3816c72ffaaSAndy Whitcroftour $Operators = qr{ 3826c72ffaaSAndy Whitcroft <=|>=|==|!=| 3836c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 38423f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 3856c72ffaaSAndy Whitcroft }x; 3866c72ffaaSAndy Whitcroft 38791cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; 38891cb5195SJoe Perches 389ab7e23f3SJoe Perchesour $BasicType; 3908905a67cSAndy Whitcroftour $NonptrType; 3911813087dSJoe Perchesour $NonptrTypeMisordered; 3928716de38SJoe Perchesour $NonptrTypeWithAttr; 3938905a67cSAndy Whitcroftour $Type; 3941813087dSJoe Perchesour $TypeMisordered; 3958905a67cSAndy Whitcroftour $Declare; 3961813087dSJoe Perchesour $DeclareMisordered; 3978905a67cSAndy Whitcroft 39815662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 39915662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 400171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 401171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 402171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 403171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 404171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 405171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 406171ae1a4SAndy Whitcroft}x; 407171ae1a4SAndy Whitcroft 40815662b3eSJoe Perchesour $UTF8 = qr{ 40915662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 41015662b3eSJoe Perches | $NON_ASCII_UTF8 41115662b3eSJoe Perches}x; 41215662b3eSJoe Perches 413e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; 414021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x: 415021158b4SJoe Perches u_(?:char|short|int|long) | # bsd 416021158b4SJoe Perches u(?:nchar|short|int|long) # sysv 417021158b4SJoe Perches)}; 418e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x: 419fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 4208ed22cadSAndy Whitcroft atomic_t 4218ed22cadSAndy Whitcroft)}; 422e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x: 423e6176fa4SJoe Perches $typeC99Typedefs\b| 424e6176fa4SJoe Perches $typeOtherOSTypedefs\b| 425e6176fa4SJoe Perches $typeKernelTypedefs\b 426e6176fa4SJoe Perches)}; 4278ed22cadSAndy Whitcroft 4286d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; 4296d32f7a3SJoe Perches 430691e669bSJoe Perchesour $logFunctions = qr{(?x: 431758d7aadSMiles Chen printk(?:_ratelimited|_once|_deferred_once|_deferred|)| 4327d0b6594SJacob Keller (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 4336e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 434b0531722SJoe Perches panic| 43506668727SJoe Perches MODULE_[A-Z_]+| 43606668727SJoe Perches seq_vprintf|seq_printf|seq_puts 437691e669bSJoe Perches)}; 438691e669bSJoe Perches 43920112475SJoe Perchesour $signature_tags = qr{(?xi: 44020112475SJoe Perches Signed-off-by:| 44120112475SJoe Perches Acked-by:| 44220112475SJoe Perches Tested-by:| 44320112475SJoe Perches Reviewed-by:| 44420112475SJoe Perches Reported-by:| 4458543ae12SMugunthan V N Suggested-by:| 44620112475SJoe Perches To:| 44720112475SJoe Perches Cc: 44820112475SJoe Perches)}; 44920112475SJoe Perches 4501813087dSJoe Perchesour @typeListMisordered = ( 4511813087dSJoe Perches qr{char\s+(?:un)?signed}, 4521813087dSJoe Perches qr{int\s+(?:(?:un)?signed\s+)?short\s}, 4531813087dSJoe Perches qr{int\s+short(?:\s+(?:un)?signed)}, 4541813087dSJoe Perches qr{short\s+int(?:\s+(?:un)?signed)}, 4551813087dSJoe Perches qr{(?:un)?signed\s+int\s+short}, 4561813087dSJoe Perches qr{short\s+(?:un)?signed}, 4571813087dSJoe Perches qr{long\s+int\s+(?:un)?signed}, 4581813087dSJoe Perches qr{int\s+long\s+(?:un)?signed}, 4591813087dSJoe Perches qr{long\s+(?:un)?signed\s+int}, 4601813087dSJoe Perches qr{int\s+(?:un)?signed\s+long}, 4611813087dSJoe Perches qr{int\s+(?:un)?signed}, 4621813087dSJoe Perches qr{int\s+long\s+long\s+(?:un)?signed}, 4631813087dSJoe Perches qr{long\s+long\s+int\s+(?:un)?signed}, 4641813087dSJoe Perches qr{long\s+long\s+(?:un)?signed\s+int}, 4651813087dSJoe Perches qr{long\s+long\s+(?:un)?signed}, 4661813087dSJoe Perches qr{long\s+(?:un)?signed}, 4671813087dSJoe Perches); 4681813087dSJoe Perches 4698905a67cSAndy Whitcroftour @typeList = ( 4708905a67cSAndy Whitcroft qr{void}, 4710c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?char}, 4720c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short\s+int}, 4730c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?short}, 4740c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?int}, 4750c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+int}, 4760c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, 4770c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long\s+long}, 4780c773d9dSJoe Perches qr{(?:(?:un)?signed\s+)?long}, 4790c773d9dSJoe Perches qr{(?:un)?signed}, 4808905a67cSAndy Whitcroft qr{float}, 4818905a67cSAndy Whitcroft qr{double}, 4828905a67cSAndy Whitcroft qr{bool}, 4838905a67cSAndy Whitcroft qr{struct\s+$Ident}, 4848905a67cSAndy Whitcroft qr{union\s+$Ident}, 4858905a67cSAndy Whitcroft qr{enum\s+$Ident}, 4868905a67cSAndy Whitcroft qr{${Ident}_t}, 4878905a67cSAndy Whitcroft qr{${Ident}_handler}, 4888905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 4891813087dSJoe Perches @typeListMisordered, 4908905a67cSAndy Whitcroft); 491938224b5SJoe Perches 492938224b5SJoe Perchesour $C90_int_types = qr{(?x: 493938224b5SJoe Perches long\s+long\s+int\s+(?:un)?signed| 494938224b5SJoe Perches long\s+long\s+(?:un)?signed\s+int| 495938224b5SJoe Perches long\s+long\s+(?:un)?signed| 496938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long\s+int| 497938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+long| 498938224b5SJoe Perches int\s+long\s+long\s+(?:un)?signed| 499938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long\s+long| 500938224b5SJoe Perches 501938224b5SJoe Perches long\s+int\s+(?:un)?signed| 502938224b5SJoe Perches long\s+(?:un)?signed\s+int| 503938224b5SJoe Perches long\s+(?:un)?signed| 504938224b5SJoe Perches (?:(?:un)?signed\s+)?long\s+int| 505938224b5SJoe Perches (?:(?:un)?signed\s+)?long| 506938224b5SJoe Perches int\s+long\s+(?:un)?signed| 507938224b5SJoe Perches int\s+(?:(?:un)?signed\s+)?long| 508938224b5SJoe Perches 509938224b5SJoe Perches int\s+(?:un)?signed| 510938224b5SJoe Perches (?:(?:un)?signed\s+)?int 511938224b5SJoe Perches)}; 512938224b5SJoe Perches 513485ff23eSAlex Dowadour @typeListFile = (); 5148716de38SJoe Perchesour @typeListWithAttr = ( 5158716de38SJoe Perches @typeList, 5168716de38SJoe Perches qr{struct\s+$InitAttribute\s+$Ident}, 5178716de38SJoe Perches qr{union\s+$InitAttribute\s+$Ident}, 5188716de38SJoe Perches); 5198716de38SJoe Perches 520c45dcabdSAndy Whitcroftour @modifierList = ( 521c45dcabdSAndy Whitcroft qr{fastcall}, 522c45dcabdSAndy Whitcroft); 523485ff23eSAlex Dowadour @modifierListFile = (); 5248905a67cSAndy Whitcroft 5252435880fSJoe Perchesour @mode_permission_funcs = ( 5262435880fSJoe Perches ["module_param", 3], 5272435880fSJoe Perches ["module_param_(?:array|named|string)", 4], 5282435880fSJoe Perches ["module_param_array_named", 5], 5292435880fSJoe Perches ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], 5302435880fSJoe Perches ["proc_create(?:_data|)", 2], 531459cf0aeSJoe Perches ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], 532459cf0aeSJoe Perches ["IIO_DEV_ATTR_[A-Z_]+", 1], 533459cf0aeSJoe Perches ["SENSOR_(?:DEVICE_|)ATTR_2", 2], 534459cf0aeSJoe Perches ["SENSOR_TEMPLATE(?:_2|)", 3], 535459cf0aeSJoe Perches ["__ATTR", 2], 5362435880fSJoe Perches); 5372435880fSJoe Perches 538515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below 539515a235eSJoe Perchesour $mode_perms_search = ""; 540515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) { 541515a235eSJoe Perches $mode_perms_search .= '|' if ($mode_perms_search ne ""); 542515a235eSJoe Perches $mode_perms_search .= $entry->[0]; 543515a235eSJoe Perches} 544515a235eSJoe Perches 545b392c64fSJoe Perchesour $mode_perms_world_writable = qr{ 546b392c64fSJoe Perches S_IWUGO | 547b392c64fSJoe Perches S_IWOTH | 548b392c64fSJoe Perches S_IRWXUGO | 549b392c64fSJoe Perches S_IALLUGO | 550b392c64fSJoe Perches 0[0-7][0-7][2367] 551b392c64fSJoe Perches}x; 552b392c64fSJoe Perches 553f90774e1SJoe Perchesour %mode_permission_string_types = ( 554f90774e1SJoe Perches "S_IRWXU" => 0700, 555f90774e1SJoe Perches "S_IRUSR" => 0400, 556f90774e1SJoe Perches "S_IWUSR" => 0200, 557f90774e1SJoe Perches "S_IXUSR" => 0100, 558f90774e1SJoe Perches "S_IRWXG" => 0070, 559f90774e1SJoe Perches "S_IRGRP" => 0040, 560f90774e1SJoe Perches "S_IWGRP" => 0020, 561f90774e1SJoe Perches "S_IXGRP" => 0010, 562f90774e1SJoe Perches "S_IRWXO" => 0007, 563f90774e1SJoe Perches "S_IROTH" => 0004, 564f90774e1SJoe Perches "S_IWOTH" => 0002, 565f90774e1SJoe Perches "S_IXOTH" => 0001, 566f90774e1SJoe Perches "S_IRWXUGO" => 0777, 567f90774e1SJoe Perches "S_IRUGO" => 0444, 568f90774e1SJoe Perches "S_IWUGO" => 0222, 569f90774e1SJoe Perches "S_IXUGO" => 0111, 570f90774e1SJoe Perches); 571f90774e1SJoe Perches 572f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below 573f90774e1SJoe Perchesour $mode_perms_string_search = ""; 574f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) { 575f90774e1SJoe Perches $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); 576f90774e1SJoe Perches $mode_perms_string_search .= $entry; 577f90774e1SJoe Perches} 578f90774e1SJoe Perches 5797840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 5807840a94cSWolfram Sang irq| 581cdcee686SSergey Ryazanov memory| 582cdcee686SSergey Ryazanov time| 583cdcee686SSergey Ryazanov reboot 5847840a94cSWolfram Sang)}; 5857840a94cSWolfram Sang# memory.h: ARM has a custom one 5867840a94cSWolfram Sang 58766b47b4aSKees Cook# Load common spelling mistakes and build regular expression list. 58866b47b4aSKees Cookmy $misspellings; 58966b47b4aSKees Cookmy %spelling_fix; 59036061e38SJoe Perches 59136061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) { 59266b47b4aSKees Cook while (<$spelling>) { 59366b47b4aSKees Cook my $line = $_; 59466b47b4aSKees Cook 59566b47b4aSKees Cook $line =~ s/\s*\n?$//g; 59666b47b4aSKees Cook $line =~ s/^\s*//g; 59766b47b4aSKees Cook 59866b47b4aSKees Cook next if ($line =~ m/^\s*#/); 59966b47b4aSKees Cook next if ($line =~ m/^\s*$/); 60066b47b4aSKees Cook 60166b47b4aSKees Cook my ($suspect, $fix) = split(/\|\|/, $line); 60266b47b4aSKees Cook 60366b47b4aSKees Cook $spelling_fix{$suspect} = $fix; 60466b47b4aSKees Cook } 60566b47b4aSKees Cook close($spelling); 60636061e38SJoe Perches} else { 60736061e38SJoe Perches warn "No typos will be found - file '$spelling_file': $!\n"; 60836061e38SJoe Perches} 60966b47b4aSKees Cook 610ebfd7d62SJoe Perchesif ($codespell) { 611ebfd7d62SJoe Perches if (open(my $spelling, '<', $codespellfile)) { 612ebfd7d62SJoe Perches while (<$spelling>) { 613ebfd7d62SJoe Perches my $line = $_; 614ebfd7d62SJoe Perches 615ebfd7d62SJoe Perches $line =~ s/\s*\n?$//g; 616ebfd7d62SJoe Perches $line =~ s/^\s*//g; 617ebfd7d62SJoe Perches 618ebfd7d62SJoe Perches next if ($line =~ m/^\s*#/); 619ebfd7d62SJoe Perches next if ($line =~ m/^\s*$/); 620ebfd7d62SJoe Perches next if ($line =~ m/, disabled/i); 621ebfd7d62SJoe Perches 622ebfd7d62SJoe Perches $line =~ s/,.*$//; 623ebfd7d62SJoe Perches 624ebfd7d62SJoe Perches my ($suspect, $fix) = split(/->/, $line); 625ebfd7d62SJoe Perches 626ebfd7d62SJoe Perches $spelling_fix{$suspect} = $fix; 627ebfd7d62SJoe Perches } 628ebfd7d62SJoe Perches close($spelling); 629ebfd7d62SJoe Perches } else { 630ebfd7d62SJoe Perches warn "No codespell typos will be found - file '$codespellfile': $!\n"; 631ebfd7d62SJoe Perches } 632ebfd7d62SJoe Perches} 633ebfd7d62SJoe Perches 634ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; 635ebfd7d62SJoe Perches 63675ad8c57SJerome Forissiersub read_words { 63775ad8c57SJerome Forissier my ($wordsRef, $file) = @_; 63875ad8c57SJerome Forissier 63975ad8c57SJerome Forissier if (open(my $words, '<', $file)) { 64075ad8c57SJerome Forissier while (<$words>) { 641bf1fa1daSJoe Perches my $line = $_; 642bf1fa1daSJoe Perches 643bf1fa1daSJoe Perches $line =~ s/\s*\n?$//g; 644bf1fa1daSJoe Perches $line =~ s/^\s*//g; 645bf1fa1daSJoe Perches 646bf1fa1daSJoe Perches next if ($line =~ m/^\s*#/); 647bf1fa1daSJoe Perches next if ($line =~ m/^\s*$/); 648bf1fa1daSJoe Perches if ($line =~ /\s/) { 64975ad8c57SJerome Forissier print("$file: '$line' invalid - ignored\n"); 650bf1fa1daSJoe Perches next; 651bf1fa1daSJoe Perches } 652bf1fa1daSJoe Perches 65375ad8c57SJerome Forissier $$wordsRef .= '|' if ($$wordsRef ne ""); 65475ad8c57SJerome Forissier $$wordsRef .= $line; 655bf1fa1daSJoe Perches } 65675ad8c57SJerome Forissier close($file); 65775ad8c57SJerome Forissier return 1; 658bf1fa1daSJoe Perches } 659bf1fa1daSJoe Perches 66075ad8c57SJerome Forissier return 0; 66175ad8c57SJerome Forissier} 66275ad8c57SJerome Forissier 66375ad8c57SJerome Forissiermy $const_structs = ""; 66475ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile) 66575ad8c57SJerome Forissier or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; 66675ad8c57SJerome Forissier 66775ad8c57SJerome Forissiermy $typeOtherTypedefs = ""; 66875ad8c57SJerome Forissierif (length($typedefsfile)) { 66975ad8c57SJerome Forissier read_words(\$typeOtherTypedefs, $typedefsfile) 67075ad8c57SJerome Forissier or warn "No additional types will be considered - file '$typedefsfile': $!\n"; 67175ad8c57SJerome Forissier} 67275ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); 67375ad8c57SJerome Forissier 6748905a67cSAndy Whitcroftsub build_types { 675485ff23eSAlex Dowad my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; 676485ff23eSAlex Dowad my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; 6771813087dSJoe Perches my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; 6788716de38SJoe Perches my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; 679c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 680ab7e23f3SJoe Perches $BasicType = qr{ 681ab7e23f3SJoe Perches (?:$typeTypedefs\b)| 682ab7e23f3SJoe Perches (?:${all}\b) 683ab7e23f3SJoe Perches }x; 6848905a67cSAndy Whitcroft $NonptrType = qr{ 685d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 686cf655043SAndy Whitcroft (?: 6876b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 6888ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 689c45dcabdSAndy Whitcroft (?:${all}\b) 690cf655043SAndy Whitcroft ) 691c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 6928905a67cSAndy Whitcroft }x; 6931813087dSJoe Perches $NonptrTypeMisordered = qr{ 6941813087dSJoe Perches (?:$Modifier\s+|const\s+)* 6951813087dSJoe Perches (?: 6961813087dSJoe Perches (?:${Misordered}\b) 6971813087dSJoe Perches ) 6981813087dSJoe Perches (?:\s+$Modifier|\s+const)* 6991813087dSJoe Perches }x; 7008716de38SJoe Perches $NonptrTypeWithAttr = qr{ 7018716de38SJoe Perches (?:$Modifier\s+|const\s+)* 7028716de38SJoe Perches (?: 7038716de38SJoe Perches (?:typeof|__typeof__)\s*\([^\)]*\)| 7048716de38SJoe Perches (?:$typeTypedefs\b)| 7058716de38SJoe Perches (?:${allWithAttr}\b) 7068716de38SJoe Perches ) 7078716de38SJoe Perches (?:\s+$Modifier|\s+const)* 7088716de38SJoe Perches }x; 7098905a67cSAndy Whitcroft $Type = qr{ 710c45dcabdSAndy Whitcroft $NonptrType 7111574a29fSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 712c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 7138905a67cSAndy Whitcroft }x; 7141813087dSJoe Perches $TypeMisordered = qr{ 7151813087dSJoe Perches $NonptrTypeMisordered 7161813087dSJoe Perches (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? 7171813087dSJoe Perches (?:\s+$Inline|\s+$Modifier)* 7181813087dSJoe Perches }x; 71991cb5195SJoe Perches $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; 7201813087dSJoe Perches $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; 7218905a67cSAndy Whitcroft} 7228905a67cSAndy Whitcroftbuild_types(); 7236c72ffaaSAndy Whitcroft 7247d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 725d1fe9c09SJoe Perches 726d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 727d1fe9c09SJoe Perches# requires at least perl version v5.10.0 728d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 729d1fe9c09SJoe Perches 730d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 7312435880fSJoe Perchesour $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; 732c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; 7337d2367afSJoe Perches 734f8422308SJoe Perchesour $declaration_macros = qr{(?x: 7353e838b6cSJoe Perches (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| 736f8422308SJoe Perches (?:$Storage\s+)?LIST_HEAD\s*\(| 737f8422308SJoe Perches (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( 738f8422308SJoe Perches)}; 739f8422308SJoe Perches 7407d2367afSJoe Perchessub deparenthesize { 7417d2367afSJoe Perches my ($string) = @_; 7427d2367afSJoe Perches return "" if (!defined($string)); 7435b9553abSJoe Perches 7445b9553abSJoe Perches while ($string =~ /^\s*\(.*\)\s*$/) { 7455b9553abSJoe Perches $string =~ s@^\s*\(\s*@@; 7465b9553abSJoe Perches $string =~ s@\s*\)\s*$@@; 7475b9553abSJoe Perches } 7485b9553abSJoe Perches 7497d2367afSJoe Perches $string =~ s@\s+@ @g; 7505b9553abSJoe Perches 7517d2367afSJoe Perches return $string; 7527d2367afSJoe Perches} 7537d2367afSJoe Perches 7543445686aSJoe Perchessub seed_camelcase_file { 7553445686aSJoe Perches my ($file) = @_; 7563445686aSJoe Perches 7573445686aSJoe Perches return if (!(-f $file)); 7583445686aSJoe Perches 7593445686aSJoe Perches local $/; 7603445686aSJoe Perches 7613445686aSJoe Perches open(my $include_file, '<', "$file") 7623445686aSJoe Perches or warn "$P: Can't read '$file' $!\n"; 7633445686aSJoe Perches my $text = <$include_file>; 7643445686aSJoe Perches close($include_file); 7653445686aSJoe Perches 7663445686aSJoe Perches my @lines = split('\n', $text); 7673445686aSJoe Perches 7683445686aSJoe Perches foreach my $line (@lines) { 7693445686aSJoe Perches next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); 7703445686aSJoe Perches if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { 7713445686aSJoe Perches $camelcase{$1} = 1; 77211ea516aSJoe Perches } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { 77311ea516aSJoe Perches $camelcase{$1} = 1; 77411ea516aSJoe Perches } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { 7753445686aSJoe Perches $camelcase{$1} = 1; 7763445686aSJoe Perches } 7773445686aSJoe Perches } 7783445686aSJoe Perches} 7793445686aSJoe Perches 78085b0ee18SJoe Perchessub is_maintained_obsolete { 78185b0ee18SJoe Perches my ($filename) = @_; 78285b0ee18SJoe Perches 783f2c19c2fSJerome Forissier return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); 78485b0ee18SJoe Perches 7850616efa4SJoe Perches my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; 78685b0ee18SJoe Perches 78785b0ee18SJoe Perches return $status =~ /obsolete/i; 78885b0ee18SJoe Perches} 78985b0ee18SJoe Perches 7903445686aSJoe Perchesmy $camelcase_seeded = 0; 7913445686aSJoe Perchessub seed_camelcase_includes { 7923445686aSJoe Perches return if ($camelcase_seeded); 7933445686aSJoe Perches 7943445686aSJoe Perches my $files; 795c707a81dSJoe Perches my $camelcase_cache = ""; 796c707a81dSJoe Perches my @include_files = (); 797c707a81dSJoe Perches 798c707a81dSJoe Perches $camelcase_seeded = 1; 799351b2a1fSJoe Perches 8003645e328SRichard Genoud if (-e ".git") { 801351b2a1fSJoe Perches my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; 802351b2a1fSJoe Perches chomp $git_last_include_commit; 803c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; 804c707a81dSJoe Perches } else { 805c707a81dSJoe Perches my $last_mod_date = 0; 806c707a81dSJoe Perches $files = `find $root/include -name "*.h"`; 807c707a81dSJoe Perches @include_files = split('\n', $files); 808c707a81dSJoe Perches foreach my $file (@include_files) { 809c707a81dSJoe Perches my $date = POSIX::strftime("%Y%m%d%H%M", 810c707a81dSJoe Perches localtime((stat $file)[9])); 811c707a81dSJoe Perches $last_mod_date = $date if ($last_mod_date < $date); 812c707a81dSJoe Perches } 813c707a81dSJoe Perches $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; 814c707a81dSJoe Perches } 815c707a81dSJoe Perches 816c707a81dSJoe Perches if ($camelcase_cache ne "" && -f $camelcase_cache) { 817c707a81dSJoe Perches open(my $camelcase_file, '<', "$camelcase_cache") 818c707a81dSJoe Perches or warn "$P: Can't read '$camelcase_cache' $!\n"; 819351b2a1fSJoe Perches while (<$camelcase_file>) { 820351b2a1fSJoe Perches chomp; 821351b2a1fSJoe Perches $camelcase{$_} = 1; 822351b2a1fSJoe Perches } 823351b2a1fSJoe Perches close($camelcase_file); 824351b2a1fSJoe Perches 825351b2a1fSJoe Perches return; 826351b2a1fSJoe Perches } 827c707a81dSJoe Perches 8283645e328SRichard Genoud if (-e ".git") { 829c707a81dSJoe Perches $files = `git ls-files "include/*.h"`; 830c707a81dSJoe Perches @include_files = split('\n', $files); 8313445686aSJoe Perches } 832c707a81dSJoe Perches 8333445686aSJoe Perches foreach my $file (@include_files) { 8343445686aSJoe Perches seed_camelcase_file($file); 8353445686aSJoe Perches } 836351b2a1fSJoe Perches 837c707a81dSJoe Perches if ($camelcase_cache ne "") { 838351b2a1fSJoe Perches unlink glob ".checkpatch-camelcase.*"; 839c707a81dSJoe Perches open(my $camelcase_file, '>', "$camelcase_cache") 840c707a81dSJoe Perches or warn "$P: Can't write '$camelcase_cache' $!\n"; 841351b2a1fSJoe Perches foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { 842351b2a1fSJoe Perches print $camelcase_file ("$_\n"); 843351b2a1fSJoe Perches } 844351b2a1fSJoe Perches close($camelcase_file); 845351b2a1fSJoe Perches } 8463445686aSJoe Perches} 8473445686aSJoe Perches 848d311cd44SJoe Perchessub git_commit_info { 849d311cd44SJoe Perches my ($commit, $id, $desc) = @_; 850d311cd44SJoe Perches 851d311cd44SJoe Perches return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); 852d311cd44SJoe Perches 853d311cd44SJoe Perches my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; 854d311cd44SJoe Perches $output =~ s/^\s*//gm; 855d311cd44SJoe Perches my @lines = split("\n", $output); 856d311cd44SJoe Perches 8570d7835fcSJoe Perches return ($id, $desc) if ($#lines < 0); 8580d7835fcSJoe Perches 859d311cd44SJoe Perches if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { 860d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns 861d311cd44SJoe Perches# all matching commit ids, but it's very slow... 862d311cd44SJoe Perches# 863d311cd44SJoe Perches# echo "checking commits $1..." 864d311cd44SJoe Perches# git rev-list --remotes | grep -i "^$1" | 865d311cd44SJoe Perches# while read line ; do 866d311cd44SJoe Perches# git log --format='%H %s' -1 $line | 867d311cd44SJoe Perches# echo "commit $(cut -c 1-12,41-)" 868d311cd44SJoe Perches# done 869d311cd44SJoe Perches } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { 870d311cd44SJoe Perches } else { 871d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 872d311cd44SJoe Perches $desc = substr($lines[0], 41); 873d311cd44SJoe Perches } 874d311cd44SJoe Perches 875d311cd44SJoe Perches return ($id, $desc); 876d311cd44SJoe Perches} 877d311cd44SJoe Perches 8786c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 8790a920b5bSAndy Whitcroft 88000df344fSAndy Whitcroftmy @rawlines = (); 881c2fdda0dSAndy Whitcroftmy @lines = (); 8823705ce5bSJoe Perchesmy @fixed = (); 883d752fcc8SJoe Perchesmy @fixed_inserted = (); 884d752fcc8SJoe Perchesmy @fixed_deleted = (); 885194f66fcSJoe Perchesmy $fixlinenr = -1; 886194f66fcSJoe Perches 8874a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 8884a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 8894a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git"); 8904a593c34SDu, Changbin 8914a593c34SDu, Changbinif ($git) { 8924a593c34SDu, Changbin my @commits = (); 8930dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 8944a593c34SDu, Changbin my $git_range; 89528898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 89628898fd1SJoe Perches $git_range = "-$2 $1"; 8974a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 8984a593c34SDu, Changbin $git_range = "$commit_expr"; 8994a593c34SDu, Changbin } else { 9000dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 9010dea9f1eSJoe Perches } 9020dea9f1eSJoe Perches my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 9030dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 90428898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 90528898fd1SJoe Perches next if (!defined($1) || !defined($2)); 9060dea9f1eSJoe Perches my $sha1 = $1; 9070dea9f1eSJoe Perches my $subject = $2; 9080dea9f1eSJoe Perches unshift(@commits, $sha1); 9090dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 9104a593c34SDu, Changbin } 9114a593c34SDu, Changbin } 9124a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 9134a593c34SDu, Changbin @ARGV = @commits; 9144a593c34SDu, Changbin} 9154a593c34SDu, Changbin 916c2fdda0dSAndy Whitcroftmy $vname; 9176c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 91821caa13cSAndy Whitcroft my $FILE; 9194a593c34SDu, Changbin if ($git) { 9204a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 9214a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 9224a593c34SDu, Changbin } elsif ($file) { 92321caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 9246c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 92521caa13cSAndy Whitcroft } elsif ($filename eq '-') { 92621caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 9276c72ffaaSAndy Whitcroft } else { 92821caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 9296c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 9306c72ffaaSAndy Whitcroft } 931c2fdda0dSAndy Whitcroft if ($filename eq '-') { 932c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 9334a593c34SDu, Changbin } elsif ($git) { 9340dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 935c2fdda0dSAndy Whitcroft } else { 936c2fdda0dSAndy Whitcroft $vname = $filename; 937c2fdda0dSAndy Whitcroft } 93821caa13cSAndy Whitcroft while (<$FILE>) { 9390a920b5bSAndy Whitcroft chomp; 94000df344fSAndy Whitcroft push(@rawlines, $_); 9416c72ffaaSAndy Whitcroft } 94221caa13cSAndy Whitcroft close($FILE); 943d8469f16SJoe Perches 944d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 945d8469f16SJoe Perches print '-' x length($vname) . "\n"; 946d8469f16SJoe Perches print "$vname\n"; 947d8469f16SJoe Perches print '-' x length($vname) . "\n"; 948d8469f16SJoe Perches } 949d8469f16SJoe Perches 950c2fdda0dSAndy Whitcroft if (!process($filename)) { 9510a920b5bSAndy Whitcroft $exit = 1; 9520a920b5bSAndy Whitcroft } 95300df344fSAndy Whitcroft @rawlines = (); 95413214adfSAndy Whitcroft @lines = (); 9553705ce5bSJoe Perches @fixed = (); 956d752fcc8SJoe Perches @fixed_inserted = (); 957d752fcc8SJoe Perches @fixed_deleted = (); 958194f66fcSJoe Perches $fixlinenr = -1; 959485ff23eSAlex Dowad @modifierListFile = (); 960485ff23eSAlex Dowad @typeListFile = (); 961485ff23eSAlex Dowad build_types(); 9620a920b5bSAndy Whitcroft} 9630a920b5bSAndy Whitcroft 964d8469f16SJoe Perchesif (!$quiet) { 9653c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 9663c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 9673c816e49SJoe Perches 968d8469f16SJoe Perches if ($^V lt 5.10.0) { 969d8469f16SJoe Perches print << "EOM" 970d8469f16SJoe Perches 971d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 972d8469f16SJoe Perches An upgrade to at least perl v5.10.0 is suggested. 973d8469f16SJoe PerchesEOM 974d8469f16SJoe Perches } 975d8469f16SJoe Perches if ($exit) { 976d8469f16SJoe Perches print << "EOM" 977d8469f16SJoe Perches 978d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 979d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 980d8469f16SJoe PerchesEOM 981d8469f16SJoe Perches } 982d8469f16SJoe Perches} 983d8469f16SJoe Perches 9840a920b5bSAndy Whitcroftexit($exit); 9850a920b5bSAndy Whitcroft 9860a920b5bSAndy Whitcroftsub top_of_kernel_tree { 9876c72ffaaSAndy Whitcroft my ($root) = @_; 9886c72ffaaSAndy Whitcroft 9896c72ffaaSAndy Whitcroft my @tree_check = ( 9906c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 9916c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 9926c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 9936c72ffaaSAndy Whitcroft ); 9946c72ffaaSAndy Whitcroft 9956c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 9966c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 9970a920b5bSAndy Whitcroft return 0; 9980a920b5bSAndy Whitcroft } 9996c72ffaaSAndy Whitcroft } 10006c72ffaaSAndy Whitcroft return 1; 10016c72ffaaSAndy Whitcroft} 10020a920b5bSAndy Whitcroft 100320112475SJoe Perchessub parse_email { 100420112475SJoe Perches my ($formatted_email) = @_; 100520112475SJoe Perches 100620112475SJoe Perches my $name = ""; 100720112475SJoe Perches my $address = ""; 100820112475SJoe Perches my $comment = ""; 100920112475SJoe Perches 101020112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 101120112475SJoe Perches $name = $1; 101220112475SJoe Perches $address = $2; 101320112475SJoe Perches $comment = $3 if defined $3; 101420112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 101520112475SJoe Perches $address = $1; 101620112475SJoe Perches $comment = $2 if defined $2; 101720112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 101820112475SJoe Perches $address = $1; 101920112475SJoe Perches $comment = $2 if defined $2; 102020112475SJoe Perches $formatted_email =~ s/$address.*$//; 102120112475SJoe Perches $name = $formatted_email; 10223705ce5bSJoe Perches $name = trim($name); 102320112475SJoe Perches $name =~ s/^\"|\"$//g; 102420112475SJoe Perches # If there's a name left after stripping spaces and 102520112475SJoe Perches # leading quotes, and the address doesn't have both 102620112475SJoe Perches # leading and trailing angle brackets, the address 102720112475SJoe Perches # is invalid. ie: 102820112475SJoe Perches # "joe smith [email protected]" bad 102920112475SJoe Perches # "joe smith <[email protected]" bad 103020112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 103120112475SJoe Perches $name = ""; 103220112475SJoe Perches $address = ""; 103320112475SJoe Perches $comment = ""; 103420112475SJoe Perches } 103520112475SJoe Perches } 103620112475SJoe Perches 10373705ce5bSJoe Perches $name = trim($name); 103820112475SJoe Perches $name =~ s/^\"|\"$//g; 10393705ce5bSJoe Perches $address = trim($address); 104020112475SJoe Perches $address =~ s/^\<|\>$//g; 104120112475SJoe Perches 104220112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 104320112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 104420112475SJoe Perches $name = "\"$name\""; 104520112475SJoe Perches } 104620112475SJoe Perches 104720112475SJoe Perches return ($name, $address, $comment); 104820112475SJoe Perches} 104920112475SJoe Perches 105020112475SJoe Perchessub format_email { 105120112475SJoe Perches my ($name, $address) = @_; 105220112475SJoe Perches 105320112475SJoe Perches my $formatted_email; 105420112475SJoe Perches 10553705ce5bSJoe Perches $name = trim($name); 105620112475SJoe Perches $name =~ s/^\"|\"$//g; 10573705ce5bSJoe Perches $address = trim($address); 105820112475SJoe Perches 105920112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 106020112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 106120112475SJoe Perches $name = "\"$name\""; 106220112475SJoe Perches } 106320112475SJoe Perches 106420112475SJoe Perches if ("$name" eq "") { 106520112475SJoe Perches $formatted_email = "$address"; 106620112475SJoe Perches } else { 106720112475SJoe Perches $formatted_email = "$name <$address>"; 106820112475SJoe Perches } 106920112475SJoe Perches 107020112475SJoe Perches return $formatted_email; 107120112475SJoe Perches} 107220112475SJoe Perches 1073d311cd44SJoe Perchessub which { 1074d311cd44SJoe Perches my ($bin) = @_; 1075d311cd44SJoe Perches 1076d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1077d311cd44SJoe Perches if (-e "$path/$bin") { 1078d311cd44SJoe Perches return "$path/$bin"; 1079d311cd44SJoe Perches } 1080d311cd44SJoe Perches } 1081d311cd44SJoe Perches 1082d311cd44SJoe Perches return ""; 1083d311cd44SJoe Perches} 1084d311cd44SJoe Perches 1085000d1cc1SJoe Perchessub which_conf { 1086000d1cc1SJoe Perches my ($conf) = @_; 1087000d1cc1SJoe Perches 1088000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1089000d1cc1SJoe Perches if (-e "$path/$conf") { 1090000d1cc1SJoe Perches return "$path/$conf"; 1091000d1cc1SJoe Perches } 1092000d1cc1SJoe Perches } 1093000d1cc1SJoe Perches 1094000d1cc1SJoe Perches return ""; 1095000d1cc1SJoe Perches} 1096000d1cc1SJoe Perches 10970a920b5bSAndy Whitcroftsub expand_tabs { 10980a920b5bSAndy Whitcroft my ($str) = @_; 10990a920b5bSAndy Whitcroft 11000a920b5bSAndy Whitcroft my $res = ''; 11010a920b5bSAndy Whitcroft my $n = 0; 11020a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 11030a920b5bSAndy Whitcroft if ($c eq "\t") { 11040a920b5bSAndy Whitcroft $res .= ' '; 11050a920b5bSAndy Whitcroft $n++; 11060a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 11070a920b5bSAndy Whitcroft $res .= ' '; 11080a920b5bSAndy Whitcroft } 11090a920b5bSAndy Whitcroft next; 11100a920b5bSAndy Whitcroft } 11110a920b5bSAndy Whitcroft $res .= $c; 11120a920b5bSAndy Whitcroft $n++; 11130a920b5bSAndy Whitcroft } 11140a920b5bSAndy Whitcroft 11150a920b5bSAndy Whitcroft return $res; 11160a920b5bSAndy Whitcroft} 11176c72ffaaSAndy Whitcroftsub copy_spacing { 1118773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 11196c72ffaaSAndy Whitcroft return $res; 11206c72ffaaSAndy Whitcroft} 11210a920b5bSAndy Whitcroft 11224a0df2efSAndy Whitcroftsub line_stats { 11234a0df2efSAndy Whitcroft my ($line) = @_; 11244a0df2efSAndy Whitcroft 11254a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 11264a0df2efSAndy Whitcroft $line =~ s/^.//; 11274a0df2efSAndy Whitcroft $line = expand_tabs($line); 11284a0df2efSAndy Whitcroft 11294a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 11304a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 11314a0df2efSAndy Whitcroft 11324a0df2efSAndy Whitcroft return (length($line), length($white)); 11334a0df2efSAndy Whitcroft} 11344a0df2efSAndy Whitcroft 1135773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1136773647a0SAndy Whitcroft 1137773647a0SAndy Whitcroftsub sanitise_line_reset { 1138773647a0SAndy Whitcroft my ($in_comment) = @_; 1139773647a0SAndy Whitcroft 1140773647a0SAndy Whitcroft if ($in_comment) { 1141773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1142773647a0SAndy Whitcroft } else { 1143773647a0SAndy Whitcroft $sanitise_quote = ''; 1144773647a0SAndy Whitcroft } 1145773647a0SAndy Whitcroft} 114600df344fSAndy Whitcroftsub sanitise_line { 114700df344fSAndy Whitcroft my ($line) = @_; 114800df344fSAndy Whitcroft 114900df344fSAndy Whitcroft my $res = ''; 115000df344fSAndy Whitcroft my $l = ''; 115100df344fSAndy Whitcroft 1152c2fdda0dSAndy Whitcroft my $qlen = 0; 1153773647a0SAndy Whitcroft my $off = 0; 1154773647a0SAndy Whitcroft my $c; 115500df344fSAndy Whitcroft 1156773647a0SAndy Whitcroft # Always copy over the diff marker. 1157773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1158773647a0SAndy Whitcroft 1159773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1160773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1161773647a0SAndy Whitcroft 1162773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 1163773647a0SAndy Whitcroft # and end, all to $;. 1164773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1165773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1166773647a0SAndy Whitcroft 1167773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1168773647a0SAndy Whitcroft $off++; 116900df344fSAndy Whitcroft next; 1170773647a0SAndy Whitcroft } 117181bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1172773647a0SAndy Whitcroft $sanitise_quote = ''; 1173773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1174773647a0SAndy Whitcroft $off++; 1175773647a0SAndy Whitcroft next; 1176773647a0SAndy Whitcroft } 1177113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1178113f04a8SDaniel Walker $sanitise_quote = '//'; 1179113f04a8SDaniel Walker 1180113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1181113f04a8SDaniel Walker $off++; 1182113f04a8SDaniel Walker next; 1183113f04a8SDaniel Walker } 1184773647a0SAndy Whitcroft 1185773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1186773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1187773647a0SAndy Whitcroft $c eq "\\") { 1188773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1189773647a0SAndy Whitcroft $off++; 1190773647a0SAndy Whitcroft next; 1191773647a0SAndy Whitcroft } 1192773647a0SAndy Whitcroft # Regular quotes. 1193773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1194773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1195773647a0SAndy Whitcroft $sanitise_quote = $c; 1196773647a0SAndy Whitcroft 1197773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1198773647a0SAndy Whitcroft next; 1199773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1200773647a0SAndy Whitcroft $sanitise_quote = ''; 120100df344fSAndy Whitcroft } 120200df344fSAndy Whitcroft } 1203773647a0SAndy Whitcroft 1204fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1205773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1206773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1207113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1208113f04a8SDaniel Walker substr($res, $off, 1, $;); 1209773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1210773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 121100df344fSAndy Whitcroft } else { 1212773647a0SAndy Whitcroft substr($res, $off, 1, $c); 121300df344fSAndy Whitcroft } 1214c2fdda0dSAndy Whitcroft } 1215c2fdda0dSAndy Whitcroft 1216113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1217113f04a8SDaniel Walker $sanitise_quote = ''; 1218113f04a8SDaniel Walker } 1219113f04a8SDaniel Walker 1220c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1221c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1222c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1223c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1224c2fdda0dSAndy Whitcroft 1225c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1226c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1227c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1228c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1229c2fdda0dSAndy Whitcroft } 1230c2fdda0dSAndy Whitcroft 1231dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1232dadf680dSJoe Perches my $match = $1; 1233dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1234dadf680dSJoe Perches } 1235dadf680dSJoe Perches 123600df344fSAndy Whitcroft return $res; 123700df344fSAndy Whitcroft} 123800df344fSAndy Whitcroft 1239a6962d72SJoe Perchessub get_quoted_string { 1240a6962d72SJoe Perches my ($line, $rawline) = @_; 1241a6962d72SJoe Perches 124233acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1243a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1244a6962d72SJoe Perches} 1245a6962d72SJoe Perches 12468905a67cSAndy Whitcroftsub ctx_statement_block { 12478905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 12488905a67cSAndy Whitcroft my $line = $linenr - 1; 12498905a67cSAndy Whitcroft my $blk = ''; 12508905a67cSAndy Whitcroft my $soff = $off; 12518905a67cSAndy Whitcroft my $coff = $off - 1; 1252773647a0SAndy Whitcroft my $coff_set = 0; 12538905a67cSAndy Whitcroft 125413214adfSAndy Whitcroft my $loff = 0; 125513214adfSAndy Whitcroft 12568905a67cSAndy Whitcroft my $type = ''; 12578905a67cSAndy Whitcroft my $level = 0; 1258a2750645SAndy Whitcroft my @stack = (); 1259cf655043SAndy Whitcroft my $p; 12608905a67cSAndy Whitcroft my $c; 12618905a67cSAndy Whitcroft my $len = 0; 126213214adfSAndy Whitcroft 126313214adfSAndy Whitcroft my $remainder; 12648905a67cSAndy Whitcroft while (1) { 1265a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1266a2750645SAndy Whitcroft 1267773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 12688905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 12698905a67cSAndy Whitcroft # context. 12708905a67cSAndy Whitcroft if ($off >= $len) { 12718905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1272dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1273c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 12748905a67cSAndy Whitcroft $remain--; 127513214adfSAndy Whitcroft $loff = $len; 1276c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 12778905a67cSAndy Whitcroft $len = length($blk); 12788905a67cSAndy Whitcroft $line++; 12798905a67cSAndy Whitcroft last; 12808905a67cSAndy Whitcroft } 12818905a67cSAndy Whitcroft # Bail if there is no further context. 12828905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 128313214adfSAndy Whitcroft if ($off >= $len) { 12848905a67cSAndy Whitcroft last; 12858905a67cSAndy Whitcroft } 1286f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1287f74bd194SAndy Whitcroft $level++; 1288f74bd194SAndy Whitcroft $type = '#'; 1289f74bd194SAndy Whitcroft } 12908905a67cSAndy Whitcroft } 1291cf655043SAndy Whitcroft $p = $c; 12928905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 129313214adfSAndy Whitcroft $remainder = substr($blk, $off); 12948905a67cSAndy Whitcroft 1295773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 12964635f4fbSAndy Whitcroft 12974635f4fbSAndy Whitcroft # Handle nested #if/#else. 12984635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 12994635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 13004635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 13014635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 13024635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 13034635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 13044635f4fbSAndy Whitcroft } 13054635f4fbSAndy Whitcroft 13068905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 13078905a67cSAndy Whitcroft # outermost level. 13088905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 13098905a67cSAndy Whitcroft last; 13108905a67cSAndy Whitcroft } 13118905a67cSAndy Whitcroft 131213214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1313773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1314773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1315773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1316773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1317773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1318773647a0SAndy Whitcroft $coff_set = 1; 1319773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1320773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 132113214adfSAndy Whitcroft } 132213214adfSAndy Whitcroft 13238905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 13248905a67cSAndy Whitcroft $level++; 13258905a67cSAndy Whitcroft $type = '('; 13268905a67cSAndy Whitcroft } 13278905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 13288905a67cSAndy Whitcroft $level--; 13298905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 13308905a67cSAndy Whitcroft 13318905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 13328905a67cSAndy Whitcroft $coff = $off; 1333773647a0SAndy Whitcroft $coff_set = 1; 1334773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 13358905a67cSAndy Whitcroft } 13368905a67cSAndy Whitcroft } 13378905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 13388905a67cSAndy Whitcroft $level++; 13398905a67cSAndy Whitcroft $type = '{'; 13408905a67cSAndy Whitcroft } 13418905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 13428905a67cSAndy Whitcroft $level--; 13438905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 13448905a67cSAndy Whitcroft 13458905a67cSAndy Whitcroft if ($level == 0) { 1346b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1347b998e001SPatrick Pannuto $off++; 1348b998e001SPatrick Pannuto } 13498905a67cSAndy Whitcroft last; 13508905a67cSAndy Whitcroft } 13518905a67cSAndy Whitcroft } 1352f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1353f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1354f74bd194SAndy Whitcroft $level--; 1355f74bd194SAndy Whitcroft $type = ''; 1356f74bd194SAndy Whitcroft $off++; 1357f74bd194SAndy Whitcroft last; 1358f74bd194SAndy Whitcroft } 13598905a67cSAndy Whitcroft $off++; 13608905a67cSAndy Whitcroft } 1361a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 136213214adfSAndy Whitcroft if ($off == $len) { 1363a3bb97a7SAndy Whitcroft $loff = $len + 1; 136413214adfSAndy Whitcroft $line++; 136513214adfSAndy Whitcroft $remain--; 136613214adfSAndy Whitcroft } 13678905a67cSAndy Whitcroft 13688905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 13698905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 13708905a67cSAndy Whitcroft 13718905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 13728905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 13738905a67cSAndy Whitcroft 1374773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 137513214adfSAndy Whitcroft 137613214adfSAndy Whitcroft return ($statement, $condition, 137713214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 137813214adfSAndy Whitcroft} 137913214adfSAndy Whitcroft 1380cf655043SAndy Whitcroftsub statement_lines { 1381cf655043SAndy Whitcroft my ($stmt) = @_; 1382cf655043SAndy Whitcroft 1383cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1384cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1385cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1386cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1387cf655043SAndy Whitcroft 1388cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1389cf655043SAndy Whitcroft 1390cf655043SAndy Whitcroft return $#stmt_lines + 2; 1391cf655043SAndy Whitcroft} 1392cf655043SAndy Whitcroft 1393cf655043SAndy Whitcroftsub statement_rawlines { 1394cf655043SAndy Whitcroft my ($stmt) = @_; 1395cf655043SAndy Whitcroft 1396cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1397cf655043SAndy Whitcroft 1398cf655043SAndy Whitcroft return $#stmt_lines + 2; 1399cf655043SAndy Whitcroft} 1400cf655043SAndy Whitcroft 1401cf655043SAndy Whitcroftsub statement_block_size { 1402cf655043SAndy Whitcroft my ($stmt) = @_; 1403cf655043SAndy Whitcroft 1404cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1405cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1406cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1407cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1408cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1409cf655043SAndy Whitcroft 1410cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1411cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1412cf655043SAndy Whitcroft 1413cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1414cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1415cf655043SAndy Whitcroft 1416cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1417cf655043SAndy Whitcroft return $stmt_lines; 1418cf655043SAndy Whitcroft } else { 1419cf655043SAndy Whitcroft return $stmt_statements; 1420cf655043SAndy Whitcroft } 1421cf655043SAndy Whitcroft} 1422cf655043SAndy Whitcroft 142313214adfSAndy Whitcroftsub ctx_statement_full { 142413214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 142513214adfSAndy Whitcroft my ($statement, $condition, $level); 142613214adfSAndy Whitcroft 142713214adfSAndy Whitcroft my (@chunks); 142813214adfSAndy Whitcroft 1429cf655043SAndy Whitcroft # Grab the first conditional/block pair. 143013214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 143113214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1432773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 143313214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1434cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1435cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1436cf655043SAndy Whitcroft } 1437cf655043SAndy Whitcroft 1438cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1439cf655043SAndy Whitcroft # could continue the statement. 1440cf655043SAndy Whitcroft for (;;) { 144113214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 144213214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1443cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1444773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1445cf655043SAndy Whitcroft #print "C: push\n"; 1446cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 144713214adfSAndy Whitcroft } 144813214adfSAndy Whitcroft 144913214adfSAndy Whitcroft return ($level, $linenr, @chunks); 14508905a67cSAndy Whitcroft} 14518905a67cSAndy Whitcroft 14524a0df2efSAndy Whitcroftsub ctx_block_get { 1453f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 14544a0df2efSAndy Whitcroft my $line; 14554a0df2efSAndy Whitcroft my $start = $linenr - 1; 14564a0df2efSAndy Whitcroft my $blk = ''; 14574a0df2efSAndy Whitcroft my @o; 14584a0df2efSAndy Whitcroft my @c; 14594a0df2efSAndy Whitcroft my @res = (); 14604a0df2efSAndy Whitcroft 1461f0a594c1SAndy Whitcroft my $level = 0; 14624635f4fbSAndy Whitcroft my @stack = ($level); 146300df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 146400df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 146500df344fSAndy Whitcroft $remain--; 146600df344fSAndy Whitcroft 146700df344fSAndy Whitcroft $blk .= $rawlines[$line]; 14684635f4fbSAndy Whitcroft 14694635f4fbSAndy Whitcroft # Handle nested #if/#else. 147001464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 14714635f4fbSAndy Whitcroft push(@stack, $level); 147201464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 14734635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 147401464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 14754635f4fbSAndy Whitcroft $level = pop(@stack); 14764635f4fbSAndy Whitcroft } 14774635f4fbSAndy Whitcroft 147801464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1479f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1480f0a594c1SAndy Whitcroft if ($off > 0) { 1481f0a594c1SAndy Whitcroft $off--; 1482f0a594c1SAndy Whitcroft next; 1483f0a594c1SAndy Whitcroft } 14844a0df2efSAndy Whitcroft 1485f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1486f0a594c1SAndy Whitcroft $level--; 1487f0a594c1SAndy Whitcroft last if ($level == 0); 1488f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1489f0a594c1SAndy Whitcroft $level++; 1490f0a594c1SAndy Whitcroft } 1491f0a594c1SAndy Whitcroft } 14924a0df2efSAndy Whitcroft 1493f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 149400df344fSAndy Whitcroft push(@res, $rawlines[$line]); 14954a0df2efSAndy Whitcroft } 14964a0df2efSAndy Whitcroft 1497f0a594c1SAndy Whitcroft last if ($level == 0); 14984a0df2efSAndy Whitcroft } 14994a0df2efSAndy Whitcroft 1500f0a594c1SAndy Whitcroft return ($level, @res); 15014a0df2efSAndy Whitcroft} 15024a0df2efSAndy Whitcroftsub ctx_block_outer { 15034a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15044a0df2efSAndy Whitcroft 1505f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1506f0a594c1SAndy Whitcroft return @r; 15074a0df2efSAndy Whitcroft} 15084a0df2efSAndy Whitcroftsub ctx_block { 15094a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15104a0df2efSAndy Whitcroft 1511f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1512f0a594c1SAndy Whitcroft return @r; 1513653d4876SAndy Whitcroft} 1514653d4876SAndy Whitcroftsub ctx_statement { 1515f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1516f0a594c1SAndy Whitcroft 1517f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1518f0a594c1SAndy Whitcroft return @r; 1519f0a594c1SAndy Whitcroft} 1520f0a594c1SAndy Whitcroftsub ctx_block_level { 1521653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1522653d4876SAndy Whitcroft 1523f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 15244a0df2efSAndy Whitcroft} 15259c0ca6f9SAndy Whitcroftsub ctx_statement_level { 15269c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 15279c0ca6f9SAndy Whitcroft 15289c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 15299c0ca6f9SAndy Whitcroft} 15304a0df2efSAndy Whitcroft 15314a0df2efSAndy Whitcroftsub ctx_locate_comment { 15324a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15334a0df2efSAndy Whitcroft 15344a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1535beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 15364a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 15374a0df2efSAndy Whitcroft 15384a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 15394a0df2efSAndy Whitcroft # comment. 15404a0df2efSAndy Whitcroft my $in_comment = 0; 15414a0df2efSAndy Whitcroft $current_comment = ''; 15424a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 154300df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 154400df344fSAndy Whitcroft #warn " $line\n"; 15454a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 15464a0df2efSAndy Whitcroft $in_comment = 1; 15474a0df2efSAndy Whitcroft } 15484a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 15494a0df2efSAndy Whitcroft $in_comment = 1; 15504a0df2efSAndy Whitcroft } 15514a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 15524a0df2efSAndy Whitcroft $current_comment = ''; 15534a0df2efSAndy Whitcroft } 15544a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 15554a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 15564a0df2efSAndy Whitcroft $in_comment = 0; 15574a0df2efSAndy Whitcroft } 15584a0df2efSAndy Whitcroft } 15594a0df2efSAndy Whitcroft 15604a0df2efSAndy Whitcroft chomp($current_comment); 15614a0df2efSAndy Whitcroft return($current_comment); 15624a0df2efSAndy Whitcroft} 15634a0df2efSAndy Whitcroftsub ctx_has_comment { 15644a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15654a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 15664a0df2efSAndy Whitcroft 156700df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 15684a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 15694a0df2efSAndy Whitcroft 15704a0df2efSAndy Whitcroft return ($cmt ne ''); 15714a0df2efSAndy Whitcroft} 15724a0df2efSAndy Whitcroft 15734d001e4dSAndy Whitcroftsub raw_line { 15744d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 15754d001e4dSAndy Whitcroft 15764d001e4dSAndy Whitcroft my $offset = $linenr - 1; 15774d001e4dSAndy Whitcroft $cnt++; 15784d001e4dSAndy Whitcroft 15794d001e4dSAndy Whitcroft my $line; 15804d001e4dSAndy Whitcroft while ($cnt) { 15814d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 15824d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 15834d001e4dSAndy Whitcroft $cnt--; 15844d001e4dSAndy Whitcroft } 15854d001e4dSAndy Whitcroft 15864d001e4dSAndy Whitcroft return $line; 15874d001e4dSAndy Whitcroft} 15884d001e4dSAndy Whitcroft 15890a920b5bSAndy Whitcroftsub cat_vet { 15900a920b5bSAndy Whitcroft my ($vet) = @_; 15919c0ca6f9SAndy Whitcroft my ($res, $coded); 15920a920b5bSAndy Whitcroft 15939c0ca6f9SAndy Whitcroft $res = ''; 15946c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 15956c72ffaaSAndy Whitcroft $res .= $1; 15966c72ffaaSAndy Whitcroft if ($2 ne '') { 15979c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 15986c72ffaaSAndy Whitcroft $res .= $coded; 15996c72ffaaSAndy Whitcroft } 16009c0ca6f9SAndy Whitcroft } 16019c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 16020a920b5bSAndy Whitcroft 16039c0ca6f9SAndy Whitcroft return $res; 16040a920b5bSAndy Whitcroft} 16050a920b5bSAndy Whitcroft 1606c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1607cf655043SAndy Whitcroftmy $av_pending; 1608c2fdda0dSAndy Whitcroftmy @av_paren_type; 16091f65f947SAndy Whitcroftmy $av_pend_colon; 1610c2fdda0dSAndy Whitcroft 1611c2fdda0dSAndy Whitcroftsub annotate_reset { 1612c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1613cf655043SAndy Whitcroft $av_pending = '_'; 1614cf655043SAndy Whitcroft @av_paren_type = ('E'); 16151f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1616c2fdda0dSAndy Whitcroft} 1617c2fdda0dSAndy Whitcroft 16186c72ffaaSAndy Whitcroftsub annotate_values { 16196c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 16206c72ffaaSAndy Whitcroft 16216c72ffaaSAndy Whitcroft my $res; 16221f65f947SAndy Whitcroft my $var = '_' x length($stream); 16236c72ffaaSAndy Whitcroft my $cur = $stream; 16246c72ffaaSAndy Whitcroft 1625c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 16266c72ffaaSAndy Whitcroft 16276c72ffaaSAndy Whitcroft while (length($cur)) { 1628773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1629cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1630171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 16316c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1632c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1633c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1634cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1635c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 16366c72ffaaSAndy Whitcroft } 16376c72ffaaSAndy Whitcroft 1638c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 16399446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 16409446ef56SAndy Whitcroft push(@av_paren_type, $type); 1641addcdceaSAndy Whitcroft $type = 'c'; 16429446ef56SAndy Whitcroft 1643e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1644c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 16456c72ffaaSAndy Whitcroft $type = 'T'; 16466c72ffaaSAndy Whitcroft 1647389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1648389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1649389a2fe5SAndy Whitcroft $type = 'T'; 1650389a2fe5SAndy Whitcroft 1651c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1652171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1653c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1654171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1655171ae1a4SAndy Whitcroft if ($2 ne '') { 1656cf655043SAndy Whitcroft $av_pending = 'N'; 1657171ae1a4SAndy Whitcroft } 1658171ae1a4SAndy Whitcroft $type = 'E'; 1659171ae1a4SAndy Whitcroft 1660c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1661171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1662171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1663171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 16646c72ffaaSAndy Whitcroft 1665c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1666cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1667c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1668cf655043SAndy Whitcroft 1669cf655043SAndy Whitcroft push(@av_paren_type, $type); 1670cf655043SAndy Whitcroft push(@av_paren_type, $type); 1671171ae1a4SAndy Whitcroft $type = 'E'; 1672cf655043SAndy Whitcroft 1673c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1674cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1675cf655043SAndy Whitcroft $av_preprocessor = 1; 1676cf655043SAndy Whitcroft 1677cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1678cf655043SAndy Whitcroft 1679171ae1a4SAndy Whitcroft $type = 'E'; 1680cf655043SAndy Whitcroft 1681c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1682cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1683cf655043SAndy Whitcroft 1684cf655043SAndy Whitcroft $av_preprocessor = 1; 1685cf655043SAndy Whitcroft 1686cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1687cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1688cf655043SAndy Whitcroft pop(@av_paren_type); 1689cf655043SAndy Whitcroft push(@av_paren_type, $type); 1690171ae1a4SAndy Whitcroft $type = 'E'; 16916c72ffaaSAndy Whitcroft 16926c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1693c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 16946c72ffaaSAndy Whitcroft 1695171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1696171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1697171ae1a4SAndy Whitcroft $av_pending = $type; 1698171ae1a4SAndy Whitcroft $type = 'N'; 1699171ae1a4SAndy Whitcroft 17006c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1701c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 17026c72ffaaSAndy Whitcroft if (defined $2) { 1703cf655043SAndy Whitcroft $av_pending = 'V'; 17046c72ffaaSAndy Whitcroft } 17056c72ffaaSAndy Whitcroft $type = 'N'; 17066c72ffaaSAndy Whitcroft 170714b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1708c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 170914b111c1SAndy Whitcroft $av_pending = 'E'; 17106c72ffaaSAndy Whitcroft $type = 'N'; 17116c72ffaaSAndy Whitcroft 17121f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 17131f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 17141f65f947SAndy Whitcroft $av_pend_colon = 'C'; 17151f65f947SAndy Whitcroft $type = 'N'; 17161f65f947SAndy Whitcroft 171714b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1718c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 17196c72ffaaSAndy Whitcroft $type = 'N'; 17206c72ffaaSAndy Whitcroft 17216c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1722c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1723cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1724cf655043SAndy Whitcroft $av_pending = '_'; 17256c72ffaaSAndy Whitcroft $type = 'N'; 17266c72ffaaSAndy Whitcroft 17276c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1728cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1729cf655043SAndy Whitcroft if ($new_type ne '_') { 1730cf655043SAndy Whitcroft $type = $new_type; 1731c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1732c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 17336c72ffaaSAndy Whitcroft } else { 1734c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 17356c72ffaaSAndy Whitcroft } 17366c72ffaaSAndy Whitcroft 1737c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1738c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1739c8cb2ca3SAndy Whitcroft $type = 'V'; 1740cf655043SAndy Whitcroft $av_pending = 'V'; 17416c72ffaaSAndy Whitcroft 17428e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 17438e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 17441f65f947SAndy Whitcroft $av_pend_colon = 'B'; 17458e761b04SAndy Whitcroft } elsif ($type eq 'E') { 17468e761b04SAndy Whitcroft $av_pend_colon = 'L'; 17471f65f947SAndy Whitcroft } 17481f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 17491f65f947SAndy Whitcroft $type = 'V'; 17501f65f947SAndy Whitcroft 17516c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1752c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 17536c72ffaaSAndy Whitcroft $type = 'V'; 17546c72ffaaSAndy Whitcroft 17556c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1756c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 17576c72ffaaSAndy Whitcroft $type = 'N'; 17586c72ffaaSAndy Whitcroft 1759cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1760c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 176113214adfSAndy Whitcroft $type = 'E'; 17621f65f947SAndy Whitcroft $av_pend_colon = 'O'; 176313214adfSAndy Whitcroft 17648e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 17658e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 17668e761b04SAndy Whitcroft $type = 'C'; 17678e761b04SAndy Whitcroft 17681f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 17691f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 17701f65f947SAndy Whitcroft $type = 'N'; 17711f65f947SAndy Whitcroft 17721f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 17731f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 17741f65f947SAndy Whitcroft 17751f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 17761f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 17771f65f947SAndy Whitcroft $type = 'E'; 17781f65f947SAndy Whitcroft } else { 17791f65f947SAndy Whitcroft $type = 'N'; 17801f65f947SAndy Whitcroft } 17811f65f947SAndy Whitcroft $av_pend_colon = 'O'; 17821f65f947SAndy Whitcroft 17838e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 178413214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 17856c72ffaaSAndy Whitcroft $type = 'N'; 17866c72ffaaSAndy Whitcroft 17870d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 178874048ed8SAndy Whitcroft my $variant; 178974048ed8SAndy Whitcroft 179074048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 179174048ed8SAndy Whitcroft if ($type eq 'V') { 179274048ed8SAndy Whitcroft $variant = 'B'; 179374048ed8SAndy Whitcroft } else { 179474048ed8SAndy Whitcroft $variant = 'U'; 179574048ed8SAndy Whitcroft } 179674048ed8SAndy Whitcroft 179774048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 179874048ed8SAndy Whitcroft $type = 'N'; 179974048ed8SAndy Whitcroft 18006c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1801c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 18026c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 18036c72ffaaSAndy Whitcroft $type = 'N'; 18046c72ffaaSAndy Whitcroft } 18056c72ffaaSAndy Whitcroft 18066c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1807c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 18086c72ffaaSAndy Whitcroft } 18096c72ffaaSAndy Whitcroft if (defined $1) { 18106c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 18116c72ffaaSAndy Whitcroft $res .= $type x length($1); 18126c72ffaaSAndy Whitcroft } 18136c72ffaaSAndy Whitcroft } 18146c72ffaaSAndy Whitcroft 18151f65f947SAndy Whitcroft return ($res, $var); 18166c72ffaaSAndy Whitcroft} 18176c72ffaaSAndy Whitcroft 18188905a67cSAndy Whitcroftsub possible { 181913214adfSAndy Whitcroft my ($possible, $line) = @_; 18209a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 18210776e594SAndy Whitcroft ^(?: 18220776e594SAndy Whitcroft $Modifier| 18230776e594SAndy Whitcroft $Storage| 18240776e594SAndy Whitcroft $Type| 18259a974fdbSAndy Whitcroft DEFINE_\S+ 18269a974fdbSAndy Whitcroft )$| 18279a974fdbSAndy Whitcroft ^(?: 18280776e594SAndy Whitcroft goto| 18290776e594SAndy Whitcroft return| 18300776e594SAndy Whitcroft case| 18310776e594SAndy Whitcroft else| 18320776e594SAndy Whitcroft asm|__asm__| 183389a88353SAndy Whitcroft do| 183489a88353SAndy Whitcroft \#| 183589a88353SAndy Whitcroft \#\#| 18369a974fdbSAndy Whitcroft )(?:\s|$)| 18370776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 18389a974fdbSAndy Whitcroft )}x; 18399a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 18409a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1841c45dcabdSAndy Whitcroft # Check for modifiers. 1842c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1843c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1844c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1845c45dcabdSAndy Whitcroft 1846c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1847c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1848d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 18499a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1850d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1851485ff23eSAlex Dowad push(@modifierListFile, $modifier); 1852d2506586SAndy Whitcroft } 18539a974fdbSAndy Whitcroft } 1854c45dcabdSAndy Whitcroft 1855c45dcabdSAndy Whitcroft } else { 185613214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1857485ff23eSAlex Dowad push(@typeListFile, $possible); 1858c45dcabdSAndy Whitcroft } 18598905a67cSAndy Whitcroft build_types(); 18600776e594SAndy Whitcroft } else { 18610776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 18628905a67cSAndy Whitcroft } 18638905a67cSAndy Whitcroft} 18648905a67cSAndy Whitcroft 18656c72ffaaSAndy Whitcroftmy $prefix = ''; 18666c72ffaaSAndy Whitcroft 1867000d1cc1SJoe Perchessub show_type { 1868cbec18afSJoe Perches my ($type) = @_; 186991bfe484SJoe Perches 1870522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 1871522b837cSAlexey Dobriyan 1872cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 1873cbec18afSJoe Perches 1874cbec18afSJoe Perches return !defined $ignore_type{$type}; 1875000d1cc1SJoe Perches} 1876000d1cc1SJoe Perches 1877f0a594c1SAndy Whitcroftsub report { 1878cbec18afSJoe Perches my ($level, $type, $msg) = @_; 1879cbec18afSJoe Perches 1880cbec18afSJoe Perches if (!show_type($type) || 1881cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 1882773647a0SAndy Whitcroft return 0; 1883773647a0SAndy Whitcroft } 188457230297SJoe Perches my $output = ''; 188557230297SJoe Perches if (-t STDOUT && $color) { 188657230297SJoe Perches if ($level eq 'ERROR') { 188757230297SJoe Perches $output .= RED; 188857230297SJoe Perches } elsif ($level eq 'WARNING') { 188957230297SJoe Perches $output .= YELLOW; 1890000d1cc1SJoe Perches } else { 189157230297SJoe Perches $output .= GREEN; 1892000d1cc1SJoe Perches } 189357230297SJoe Perches } 189457230297SJoe Perches $output .= $prefix . $level . ':'; 189557230297SJoe Perches if ($show_types) { 189657230297SJoe Perches $output .= BLUE if (-t STDOUT && $color); 189757230297SJoe Perches $output .= "$type:"; 189857230297SJoe Perches } 189957230297SJoe Perches $output .= RESET if (-t STDOUT && $color); 190057230297SJoe Perches $output .= ' ' . $msg . "\n"; 190134d8815fSJoe Perches 190234d8815fSJoe Perches if ($showfile) { 190334d8815fSJoe Perches my @lines = split("\n", $output, -1); 190434d8815fSJoe Perches splice(@lines, 1, 1); 190534d8815fSJoe Perches $output = join("\n", @lines); 190634d8815fSJoe Perches } 190757230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 19088905a67cSAndy Whitcroft 190957230297SJoe Perches push(our @report, $output); 1910773647a0SAndy Whitcroft 1911773647a0SAndy Whitcroft return 1; 1912f0a594c1SAndy Whitcroft} 1913cbec18afSJoe Perches 1914f0a594c1SAndy Whitcroftsub report_dump { 191513214adfSAndy Whitcroft our @report; 1916f0a594c1SAndy Whitcroft} 1917000d1cc1SJoe Perches 1918d752fcc8SJoe Perchessub fixup_current_range { 1919d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 1920d752fcc8SJoe Perches 1921d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 1922d752fcc8SJoe Perches my $o = $1; 1923d752fcc8SJoe Perches my $l = $2; 1924d752fcc8SJoe Perches my $no = $o + $offset; 1925d752fcc8SJoe Perches my $nl = $l + $length; 1926d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 1927d752fcc8SJoe Perches } 1928d752fcc8SJoe Perches} 1929d752fcc8SJoe Perches 1930d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 1931d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 1932d752fcc8SJoe Perches 1933d752fcc8SJoe Perches my $range_last_linenr = 0; 1934d752fcc8SJoe Perches my $delta_offset = 0; 1935d752fcc8SJoe Perches 1936d752fcc8SJoe Perches my $old_linenr = 0; 1937d752fcc8SJoe Perches my $new_linenr = 0; 1938d752fcc8SJoe Perches 1939d752fcc8SJoe Perches my $next_insert = 0; 1940d752fcc8SJoe Perches my $next_delete = 0; 1941d752fcc8SJoe Perches 1942d752fcc8SJoe Perches my @lines = (); 1943d752fcc8SJoe Perches 1944d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 1945d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 1946d752fcc8SJoe Perches 1947d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 1948d752fcc8SJoe Perches my $save_line = 1; 1949d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 1950323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 1951d752fcc8SJoe Perches $delta_offset = 0; 1952d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 1953d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 1954d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 1955d752fcc8SJoe Perches } 1956d752fcc8SJoe Perches 1957d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 1958d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 1959d752fcc8SJoe Perches $save_line = 0; 1960d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 1961d752fcc8SJoe Perches } 1962d752fcc8SJoe Perches 1963d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 1964d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 1965d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 1966d752fcc8SJoe Perches $new_linenr++; 1967d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 1968d752fcc8SJoe Perches } 1969d752fcc8SJoe Perches 1970d752fcc8SJoe Perches if ($save_line) { 1971d752fcc8SJoe Perches push(@lines, $line); 1972d752fcc8SJoe Perches $new_linenr++; 1973d752fcc8SJoe Perches } 1974d752fcc8SJoe Perches 1975d752fcc8SJoe Perches $old_linenr++; 1976d752fcc8SJoe Perches } 1977d752fcc8SJoe Perches 1978d752fcc8SJoe Perches return @lines; 1979d752fcc8SJoe Perches} 1980d752fcc8SJoe Perches 1981f2d7e4d4SJoe Perchessub fix_insert_line { 1982f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1983f2d7e4d4SJoe Perches 1984f2d7e4d4SJoe Perches my $inserted = { 1985f2d7e4d4SJoe Perches LINENR => $linenr, 1986f2d7e4d4SJoe Perches LINE => $line, 1987f2d7e4d4SJoe Perches }; 1988f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 1989f2d7e4d4SJoe Perches} 1990f2d7e4d4SJoe Perches 1991f2d7e4d4SJoe Perchessub fix_delete_line { 1992f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1993f2d7e4d4SJoe Perches 1994f2d7e4d4SJoe Perches my $deleted = { 1995f2d7e4d4SJoe Perches LINENR => $linenr, 1996f2d7e4d4SJoe Perches LINE => $line, 1997f2d7e4d4SJoe Perches }; 1998f2d7e4d4SJoe Perches 1999f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2000f2d7e4d4SJoe Perches} 2001f2d7e4d4SJoe Perches 2002de7d4f0eSAndy Whitcroftsub ERROR { 2003cbec18afSJoe Perches my ($type, $msg) = @_; 2004cbec18afSJoe Perches 2005cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2006de7d4f0eSAndy Whitcroft our $clean = 0; 20076c72ffaaSAndy Whitcroft our $cnt_error++; 20083705ce5bSJoe Perches return 1; 2009de7d4f0eSAndy Whitcroft } 20103705ce5bSJoe Perches return 0; 2011773647a0SAndy Whitcroft} 2012de7d4f0eSAndy Whitcroftsub WARN { 2013cbec18afSJoe Perches my ($type, $msg) = @_; 2014cbec18afSJoe Perches 2015cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2016de7d4f0eSAndy Whitcroft our $clean = 0; 20176c72ffaaSAndy Whitcroft our $cnt_warn++; 20183705ce5bSJoe Perches return 1; 2019de7d4f0eSAndy Whitcroft } 20203705ce5bSJoe Perches return 0; 2021773647a0SAndy Whitcroft} 2022de7d4f0eSAndy Whitcroftsub CHK { 2023cbec18afSJoe Perches my ($type, $msg) = @_; 2024cbec18afSJoe Perches 2025cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2026de7d4f0eSAndy Whitcroft our $clean = 0; 20276c72ffaaSAndy Whitcroft our $cnt_chk++; 20283705ce5bSJoe Perches return 1; 20296c72ffaaSAndy Whitcroft } 20303705ce5bSJoe Perches return 0; 2031de7d4f0eSAndy Whitcroft} 2032de7d4f0eSAndy Whitcroft 20336ecd9674SAndy Whitcroftsub check_absolute_file { 20346ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 20356ecd9674SAndy Whitcroft my $file = $absolute; 20366ecd9674SAndy Whitcroft 20376ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 20386ecd9674SAndy Whitcroft 20396ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 20406ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 20416ecd9674SAndy Whitcroft if (-f "$root/$file") { 20426ecd9674SAndy Whitcroft ##print "file<$file>\n"; 20436ecd9674SAndy Whitcroft last; 20446ecd9674SAndy Whitcroft } 20456ecd9674SAndy Whitcroft } 20466ecd9674SAndy Whitcroft if (! -f _) { 20476ecd9674SAndy Whitcroft return 0; 20486ecd9674SAndy Whitcroft } 20496ecd9674SAndy Whitcroft 20506ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 20516ecd9674SAndy Whitcroft my $prefix = $absolute; 20526ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 20536ecd9674SAndy Whitcroft 20546ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 20556ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2056000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2057000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 20586ecd9674SAndy Whitcroft } 20596ecd9674SAndy Whitcroft} 20606ecd9674SAndy Whitcroft 20613705ce5bSJoe Perchessub trim { 20623705ce5bSJoe Perches my ($string) = @_; 20633705ce5bSJoe Perches 2064b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2065b34c648bSJoe Perches 2066b34c648bSJoe Perches return $string; 2067b34c648bSJoe Perches} 2068b34c648bSJoe Perches 2069b34c648bSJoe Perchessub ltrim { 2070b34c648bSJoe Perches my ($string) = @_; 2071b34c648bSJoe Perches 2072b34c648bSJoe Perches $string =~ s/^\s+//; 2073b34c648bSJoe Perches 2074b34c648bSJoe Perches return $string; 2075b34c648bSJoe Perches} 2076b34c648bSJoe Perches 2077b34c648bSJoe Perchessub rtrim { 2078b34c648bSJoe Perches my ($string) = @_; 2079b34c648bSJoe Perches 2080b34c648bSJoe Perches $string =~ s/\s+$//; 20813705ce5bSJoe Perches 20823705ce5bSJoe Perches return $string; 20833705ce5bSJoe Perches} 20843705ce5bSJoe Perches 208552ea8506SJoe Perchessub string_find_replace { 208652ea8506SJoe Perches my ($string, $find, $replace) = @_; 208752ea8506SJoe Perches 208852ea8506SJoe Perches $string =~ s/$find/$replace/g; 208952ea8506SJoe Perches 209052ea8506SJoe Perches return $string; 209152ea8506SJoe Perches} 209252ea8506SJoe Perches 20933705ce5bSJoe Perchessub tabify { 20943705ce5bSJoe Perches my ($leading) = @_; 20953705ce5bSJoe Perches 20963705ce5bSJoe Perches my $source_indent = 8; 20973705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 20983705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 20993705ce5bSJoe Perches 21003705ce5bSJoe Perches #convert leading spaces to tabs 21013705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 21023705ce5bSJoe Perches #Remove spaces before a tab 21033705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 21043705ce5bSJoe Perches 21053705ce5bSJoe Perches return "$leading"; 21063705ce5bSJoe Perches} 21073705ce5bSJoe Perches 2108d1fe9c09SJoe Perchessub pos_last_openparen { 2109d1fe9c09SJoe Perches my ($line) = @_; 2110d1fe9c09SJoe Perches 2111d1fe9c09SJoe Perches my $pos = 0; 2112d1fe9c09SJoe Perches 2113d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2114d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2115d1fe9c09SJoe Perches 2116d1fe9c09SJoe Perches my $last_openparen = 0; 2117d1fe9c09SJoe Perches 2118d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2119d1fe9c09SJoe Perches return -1; 2120d1fe9c09SJoe Perches } 2121d1fe9c09SJoe Perches 2122d1fe9c09SJoe Perches my $len = length($line); 2123d1fe9c09SJoe Perches 2124d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2125d1fe9c09SJoe Perches my $string = substr($line, $pos); 2126d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2127d1fe9c09SJoe Perches $pos += length($1) - 1; 2128d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2129d1fe9c09SJoe Perches $last_openparen = $pos; 2130d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2131d1fe9c09SJoe Perches last; 2132d1fe9c09SJoe Perches } 2133d1fe9c09SJoe Perches } 2134d1fe9c09SJoe Perches 213591cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2136d1fe9c09SJoe Perches} 2137d1fe9c09SJoe Perches 21380a920b5bSAndy Whitcroftsub process { 21390a920b5bSAndy Whitcroft my $filename = shift; 21400a920b5bSAndy Whitcroft 21410a920b5bSAndy Whitcroft my $linenr=0; 21420a920b5bSAndy Whitcroft my $prevline=""; 2143c2fdda0dSAndy Whitcroft my $prevrawline=""; 21440a920b5bSAndy Whitcroft my $stashline=""; 2145c2fdda0dSAndy Whitcroft my $stashrawline=""; 21460a920b5bSAndy Whitcroft 21474a0df2efSAndy Whitcroft my $length; 21480a920b5bSAndy Whitcroft my $indent; 21490a920b5bSAndy Whitcroft my $previndent=0; 21500a920b5bSAndy Whitcroft my $stashindent=0; 21510a920b5bSAndy Whitcroft 2152de7d4f0eSAndy Whitcroft our $clean = 1; 21530a920b5bSAndy Whitcroft my $signoff = 0; 21540a920b5bSAndy Whitcroft my $is_patch = 0; 215529ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 215615662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 2157ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2158bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 21592a076f40SJoe Perches my $commit_log_long_line = 0; 2160e518e9a5SJoe Perches my $commit_log_has_diff = 0; 216113f1937eSJoe Perches my $reported_maintainer_file = 0; 2162fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2163fa64205dSPasi Savanainen 2164365dd4eaSJoe Perches my $last_blank_line = 0; 21655e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2166365dd4eaSJoe Perches 216713214adfSAndy Whitcroft our @report = (); 21686c72ffaaSAndy Whitcroft our $cnt_lines = 0; 21696c72ffaaSAndy Whitcroft our $cnt_error = 0; 21706c72ffaaSAndy Whitcroft our $cnt_warn = 0; 21716c72ffaaSAndy Whitcroft our $cnt_chk = 0; 21726c72ffaaSAndy Whitcroft 21730a920b5bSAndy Whitcroft # Trace the real file/line as we go. 21740a920b5bSAndy Whitcroft my $realfile = ''; 21750a920b5bSAndy Whitcroft my $realline = 0; 21760a920b5bSAndy Whitcroft my $realcnt = 0; 21770a920b5bSAndy Whitcroft my $here = ''; 217877cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 21790a920b5bSAndy Whitcroft my $in_comment = 0; 2180c2fdda0dSAndy Whitcroft my $comment_edge = 0; 21810a920b5bSAndy Whitcroft my $first_line = 0; 21821e855726SWolfram Sang my $p1_prefix = ''; 21830a920b5bSAndy Whitcroft 218413214adfSAndy Whitcroft my $prev_values = 'E'; 218513214adfSAndy Whitcroft 218613214adfSAndy Whitcroft # suppression flags 2187773647a0SAndy Whitcroft my %suppress_ifbraces; 2188170d3a22SAndy Whitcroft my %suppress_whiletrailers; 21892b474a1aSAndy Whitcroft my %suppress_export; 21903e469cdcSAndy Whitcroft my $suppress_statement = 0; 2191653d4876SAndy Whitcroft 21927e51f197SJoe Perches my %signatures = (); 2193323c1260SJoe Perches 2194c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2195de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2196c2fdda0dSAndy Whitcroft # 2197de7d4f0eSAndy Whitcroft my @setup_docs = (); 2198de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2199773647a0SAndy Whitcroft 2200d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2201d8b07710SJoe Perches 2202773647a0SAndy Whitcroft sanitise_line_reset(); 2203c2fdda0dSAndy Whitcroft my $line; 2204c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2205773647a0SAndy Whitcroft $linenr++; 2206773647a0SAndy Whitcroft $line = $rawline; 2207c2fdda0dSAndy Whitcroft 22083705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 22093705ce5bSJoe Perches 2210773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2211de7d4f0eSAndy Whitcroft $setup_docs = 0; 22128c27ceffSMauro Carvalho Chehab if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2213de7d4f0eSAndy Whitcroft $setup_docs = 1; 2214de7d4f0eSAndy Whitcroft } 2215773647a0SAndy Whitcroft #next; 2216de7d4f0eSAndy Whitcroft } 221774fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2218773647a0SAndy Whitcroft $realline=$1-1; 2219773647a0SAndy Whitcroft if (defined $2) { 2220773647a0SAndy Whitcroft $realcnt=$3+1; 2221773647a0SAndy Whitcroft } else { 2222773647a0SAndy Whitcroft $realcnt=1+1; 2223773647a0SAndy Whitcroft } 2224c45dcabdSAndy Whitcroft $in_comment = 0; 2225773647a0SAndy Whitcroft 2226773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2227773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2228773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2229773647a0SAndy Whitcroft # at context start. 2230773647a0SAndy Whitcroft my $edge; 223101fa9147SAndy Whitcroft my $cnt = $realcnt; 223201fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 223301fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 223401fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 223501fa9147SAndy Whitcroft $cnt--; 223601fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2237721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2238fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2239fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2240fae17daeSAndy Whitcroft ($edge) = $1; 2241fae17daeSAndy Whitcroft last; 2242fae17daeSAndy Whitcroft } 2243773647a0SAndy Whitcroft } 2244773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2245773647a0SAndy Whitcroft $in_comment = 1; 2246773647a0SAndy Whitcroft } 2247773647a0SAndy Whitcroft 2248773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2249773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2250773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2251773647a0SAndy Whitcroft if (!defined $edge && 225283242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2253773647a0SAndy Whitcroft { 2254773647a0SAndy Whitcroft $in_comment = 1; 2255773647a0SAndy Whitcroft } 2256773647a0SAndy Whitcroft 2257773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2258773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2259773647a0SAndy Whitcroft 2260171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2261773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2262171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2263773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2264773647a0SAndy Whitcroft } 2265773647a0SAndy Whitcroft push(@lines, $line); 2266773647a0SAndy Whitcroft 2267773647a0SAndy Whitcroft if ($realcnt > 1) { 2268773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2269773647a0SAndy Whitcroft } else { 2270773647a0SAndy Whitcroft $realcnt = 0; 2271773647a0SAndy Whitcroft } 2272773647a0SAndy Whitcroft 2273773647a0SAndy Whitcroft #print "==>$rawline\n"; 2274773647a0SAndy Whitcroft #print "-->$line\n"; 2275de7d4f0eSAndy Whitcroft 2276de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2277de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2278de7d4f0eSAndy Whitcroft } 2279de7d4f0eSAndy Whitcroft } 2280de7d4f0eSAndy Whitcroft 22816c72ffaaSAndy Whitcroft $prefix = ''; 22826c72ffaaSAndy Whitcroft 2283773647a0SAndy Whitcroft $realcnt = 0; 2284773647a0SAndy Whitcroft $linenr = 0; 2285194f66fcSJoe Perches $fixlinenr = -1; 22860a920b5bSAndy Whitcroft foreach my $line (@lines) { 22870a920b5bSAndy Whitcroft $linenr++; 2288194f66fcSJoe Perches $fixlinenr++; 22891b5539b1SJoe Perches my $sline = $line; #copy of $line 22901b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 22910a920b5bSAndy Whitcroft 2292c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 22936c72ffaaSAndy Whitcroft 22940a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2295e518e9a5SJoe Perches if (!$in_commit_log && 229674fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 229774fd4f34SJoe Perches my $context = $4; 22980a920b5bSAndy Whitcroft $is_patch = 1; 22994a0df2efSAndy Whitcroft $first_line = $linenr + 1; 23000a920b5bSAndy Whitcroft $realline=$1-1; 23010a920b5bSAndy Whitcroft if (defined $2) { 23020a920b5bSAndy Whitcroft $realcnt=$3+1; 23030a920b5bSAndy Whitcroft } else { 23040a920b5bSAndy Whitcroft $realcnt=1+1; 23050a920b5bSAndy Whitcroft } 2306c2fdda0dSAndy Whitcroft annotate_reset(); 230713214adfSAndy Whitcroft $prev_values = 'E'; 230813214adfSAndy Whitcroft 2309773647a0SAndy Whitcroft %suppress_ifbraces = (); 2310170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 23112b474a1aSAndy Whitcroft %suppress_export = (); 23123e469cdcSAndy Whitcroft $suppress_statement = 0; 231374fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 231474fd4f34SJoe Perches $context_function = $1; 231574fd4f34SJoe Perches } else { 231674fd4f34SJoe Perches undef $context_function; 231774fd4f34SJoe Perches } 23180a920b5bSAndy Whitcroft next; 23190a920b5bSAndy Whitcroft 23204a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 23214a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 23224a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2323773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 23240a920b5bSAndy Whitcroft $realline++; 2325d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 23260a920b5bSAndy Whitcroft 23274a0df2efSAndy Whitcroft # Measure the line length and indent. 2328c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 23290a920b5bSAndy Whitcroft 23300a920b5bSAndy Whitcroft # Track the previous line. 23310a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 23320a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2333c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2334c2fdda0dSAndy Whitcroft 2335773647a0SAndy Whitcroft #warn "line<$line>\n"; 23366c72ffaaSAndy Whitcroft 2337d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2338d8aaf121SAndy Whitcroft $realcnt--; 23390a920b5bSAndy Whitcroft } 23400a920b5bSAndy Whitcroft 2341cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2342cc77cdcaSAndy Whitcroft 23436c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 23446c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2345773647a0SAndy Whitcroft 23462ac73b4fSJoe Perches my $found_file = 0; 2347773647a0SAndy Whitcroft # extract the filename as it passes 23483bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 23493bf9a009SRabin Vincent $realfile = $1; 23502b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2351270c49a0SJoe Perches $in_commit_log = 0; 23522ac73b4fSJoe Perches $found_file = 1; 23533bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2354773647a0SAndy Whitcroft $realfile = $1; 23552b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2356270c49a0SJoe Perches $in_commit_log = 0; 23571e855726SWolfram Sang 23581e855726SWolfram Sang $p1_prefix = $1; 2359e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2360e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2361000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2362000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 23631e855726SWolfram Sang } 2364773647a0SAndy Whitcroft 2365c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2366000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2367000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2368773647a0SAndy Whitcroft } 23692ac73b4fSJoe Perches $found_file = 1; 23702ac73b4fSJoe Perches } 23712ac73b4fSJoe Perches 237234d8815fSJoe Perches#make up the handle for any error we report on this line 237334d8815fSJoe Perches if ($showfile) { 237434d8815fSJoe Perches $prefix = "$realfile:$realline: " 237534d8815fSJoe Perches } elsif ($emacs) { 23767d3a9f67SJoe Perches if ($file) { 23777d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 23787d3a9f67SJoe Perches } else { 237934d8815fSJoe Perches $prefix = "$filename:$linenr: "; 238034d8815fSJoe Perches } 23817d3a9f67SJoe Perches } 238234d8815fSJoe Perches 23832ac73b4fSJoe Perches if ($found_file) { 238485b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 238585b0ee18SJoe Perches WARN("OBSOLETE", 238685b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 238785b0ee18SJoe Perches } 23887bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 23892ac73b4fSJoe Perches $check = 1; 23902ac73b4fSJoe Perches } else { 23912ac73b4fSJoe Perches $check = $check_orig; 23922ac73b4fSJoe Perches } 2393773647a0SAndy Whitcroft next; 2394773647a0SAndy Whitcroft } 2395773647a0SAndy Whitcroft 2396389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 23970a920b5bSAndy Whitcroft 2398c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2399c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2400c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 24010a920b5bSAndy Whitcroft 24026c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 24036c72ffaaSAndy Whitcroft 2404e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2405e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 2406e518e9a5SJoe Perches (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2407e518e9a5SJoe Perches $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 2408e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2409e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2410e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2411e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2412e518e9a5SJoe Perches $commit_log_has_diff = 1; 2413e518e9a5SJoe Perches } 2414e518e9a5SJoe Perches 24153bf9a009SRabin Vincent# Check for incorrect file permissions 24163bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 24173bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 241804db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 241904db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2420000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2421000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 24223bf9a009SRabin Vincent } 24233bf9a009SRabin Vincent } 24243bf9a009SRabin Vincent 242520112475SJoe Perches# Check the patch for a signoff: 2426d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 24274a0df2efSAndy Whitcroft $signoff++; 242815662b3eSJoe Perches $in_commit_log = 0; 24290a920b5bSAndy Whitcroft } 243020112475SJoe Perches 2431e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2432e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2433e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2434e0d975b1SJoe Perches $reported_maintainer_file = 1; 2435e0d975b1SJoe Perches } 2436e0d975b1SJoe Perches 243720112475SJoe Perches# Check signature styles 2438270c49a0SJoe Perches if (!$in_header_lines && 2439ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 244020112475SJoe Perches my $space_before = $1; 244120112475SJoe Perches my $sign_off = $2; 244220112475SJoe Perches my $space_after = $3; 244320112475SJoe Perches my $email = $4; 244420112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 244520112475SJoe Perches 2446ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2447ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2448ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2449ce0338dfSJoe Perches } 245020112475SJoe Perches if (defined $space_before && $space_before ne "") { 24513705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24523705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 24533705ce5bSJoe Perches $fix) { 2454194f66fcSJoe Perches $fixed[$fixlinenr] = 24553705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24563705ce5bSJoe Perches } 245720112475SJoe Perches } 245820112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 24593705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24603705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 24613705ce5bSJoe Perches $fix) { 2462194f66fcSJoe Perches $fixed[$fixlinenr] = 24633705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24643705ce5bSJoe Perches } 24653705ce5bSJoe Perches 246620112475SJoe Perches } 246720112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 24683705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24693705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 24703705ce5bSJoe Perches $fix) { 2471194f66fcSJoe Perches $fixed[$fixlinenr] = 24723705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24733705ce5bSJoe Perches } 247420112475SJoe Perches } 247520112475SJoe Perches 247620112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 247720112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 247820112475SJoe Perches if ($suggested_email eq "") { 2479000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2480000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 248120112475SJoe Perches } else { 248220112475SJoe Perches my $dequoted = $suggested_email; 248320112475SJoe Perches $dequoted =~ s/^"//; 248420112475SJoe Perches $dequoted =~ s/" </ </; 248520112475SJoe Perches # Don't force email to have quotes 248620112475SJoe Perches # Allow just an angle bracketed address 248720112475SJoe Perches if ("$dequoted$comment" ne $email && 248820112475SJoe Perches "<$email_address>$comment" ne $email && 248920112475SJoe Perches "$suggested_email$comment" ne $email) { 2490000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2491000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 249220112475SJoe Perches } 24930a920b5bSAndy Whitcroft } 24947e51f197SJoe Perches 24957e51f197SJoe Perches# Check for duplicate signatures 24967e51f197SJoe Perches my $sig_nospace = $line; 24977e51f197SJoe Perches $sig_nospace =~ s/\s//g; 24987e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 24997e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 25007e51f197SJoe Perches WARN("BAD_SIGN_OFF", 25017e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 25027e51f197SJoe Perches } else { 25037e51f197SJoe Perches $signatures{$sig_nospace} = 1; 25047e51f197SJoe Perches } 25050a920b5bSAndy Whitcroft } 25060a920b5bSAndy Whitcroft 2507a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2508a2fe16b9SJoe Perches if ($in_header_lines && 2509a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2510a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2511a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2512a2fe16b9SJoe Perches } 2513a2fe16b9SJoe Perches 25149b3189ebSJoe Perches# Check for old stable address 25159b3189ebSJoe Perches if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { 25169b3189ebSJoe Perches ERROR("STABLE_ADDRESS", 25179b3189ebSJoe Perches "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); 25189b3189ebSJoe Perches } 25199b3189ebSJoe Perches 25207ebd05efSChristopher Covington# Check for unwanted Gerrit info 25217ebd05efSChristopher Covington if ($in_commit_log && $line =~ /^\s*change-id:/i) { 25227ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 25237ebd05efSChristopher Covington "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 25247ebd05efSChristopher Covington } 25257ebd05efSChristopher Covington 2526369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 2527369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2528369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 2529369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 2530369c8dd3SJoe Perches # timestamp 2531369c8dd3SJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { 2532369c8dd3SJoe Perches # stack dump address 2533369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 2534369c8dd3SJoe Perches } 2535369c8dd3SJoe Perches 25362a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 25372a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 2538bf4daf12SJoe Perches length($line) > 75 && 2539bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 2540bf4daf12SJoe Perches # file delta changes 2541bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 2542bf4daf12SJoe Perches # filename then : 2543bf4daf12SJoe Perches $line =~ /^\s*(?:Fixes:|Link:)/i || 2544bf4daf12SJoe Perches # A Fixes: or Link: line 2545bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 25462a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 25472a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 25482a076f40SJoe Perches $commit_log_long_line = 1; 25492a076f40SJoe Perches } 25502a076f40SJoe Perches 2551bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 2552bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 2553bf4daf12SJoe Perches $line =~ /^\s*$/) { 2554bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 2555bf4daf12SJoe Perches } 2556bf4daf12SJoe Perches 25570d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 2558369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2559aab38f51SJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && 2560e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 2561fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 2562aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 2563369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 2564bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 2565fe043ea1SJoe Perches my $init_char = "c"; 2566fe043ea1SJoe Perches my $orig_commit = ""; 25670d7835fcSJoe Perches my $short = 1; 25680d7835fcSJoe Perches my $long = 0; 25690d7835fcSJoe Perches my $case = 1; 25700d7835fcSJoe Perches my $space = 1; 25710d7835fcSJoe Perches my $hasdesc = 0; 257219c146a6SJoe Perches my $hasparens = 0; 25730d7835fcSJoe Perches my $id = '0123456789ab'; 25740d7835fcSJoe Perches my $orig_desc = "commit description"; 25750d7835fcSJoe Perches my $description = ""; 25760d7835fcSJoe Perches 2577fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 2578fe043ea1SJoe Perches $init_char = $1; 2579fe043ea1SJoe Perches $orig_commit = lc($2); 2580fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 2581fe043ea1SJoe Perches $orig_commit = lc($1); 2582fe043ea1SJoe Perches } 2583fe043ea1SJoe Perches 25840d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 25850d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 25860d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 25870d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 25880d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 25890d7835fcSJoe Perches $orig_desc = $1; 259019c146a6SJoe Perches $hasparens = 1; 25910d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 25920d7835fcSJoe Perches defined $rawlines[$linenr] && 25930d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 25940d7835fcSJoe Perches $orig_desc = $1; 259519c146a6SJoe Perches $hasparens = 1; 2596b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2597b671fde0SJoe Perches defined $rawlines[$linenr] && 2598b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2599b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2600b671fde0SJoe Perches $orig_desc = $1; 2601b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2602b671fde0SJoe Perches $orig_desc .= " " . $1; 260319c146a6SJoe Perches $hasparens = 1; 26040d7835fcSJoe Perches } 26050d7835fcSJoe Perches 26060d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 26070d7835fcSJoe Perches $id, $orig_desc); 26080d7835fcSJoe Perches 260919c146a6SJoe Perches if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { 2610d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 26110d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 26120d7835fcSJoe Perches } 2613d311cd44SJoe Perches } 2614d311cd44SJoe Perches 261513f1937eSJoe Perches# Check for added, moved or deleted files 261613f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 261713f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 261813f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 261913f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 262013f1937eSJoe Perches (defined($1) || defined($2))))) { 2621a82603a8SAndrew Jeffery $is_patch = 1; 262213f1937eSJoe Perches $reported_maintainer_file = 1; 262313f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 262413f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 262513f1937eSJoe Perches } 262613f1937eSJoe Perches 262700df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 26288905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2629000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2630000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 26316c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2632de7d4f0eSAndy Whitcroft } 2633de7d4f0eSAndy Whitcroft 2634de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2635de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2636171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2637171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2638171ae1a4SAndy Whitcroft 2639171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2640171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2641171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2642171ae1a4SAndy Whitcroft 264334d99219SJoe Perches CHK("INVALID_UTF8", 2644000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 264500df344fSAndy Whitcroft } 26460a920b5bSAndy Whitcroft 264715662b3eSJoe Perches# Check if it's the start of a commit log 264815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 264915662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 2650eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 2651eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 265215662b3eSJoe Perches $in_header_lines = 0; 265315662b3eSJoe Perches $in_commit_log = 1; 2654ed43c4e5SAllen Hubbe $has_commit_log = 1; 265515662b3eSJoe Perches } 265615662b3eSJoe Perches 2657fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2658fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2659fa64205dSPasi Savanainen if ($in_header_lines && 2660fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2661fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2662fa64205dSPasi Savanainen $non_utf8_charset = 1; 2663fa64205dSPasi Savanainen } 2664fa64205dSPasi Savanainen 2665fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 266615662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2667fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 266815662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 266915662b3eSJoe Perches } 267015662b3eSJoe Perches 2671d6430f71SJoe Perches# Check for absolute kernel paths in commit message 2672d6430f71SJoe Perches if ($tree && $in_commit_log) { 2673d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 2674d6430f71SJoe Perches my $file = $1; 2675d6430f71SJoe Perches 2676d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 2677d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 2678d6430f71SJoe Perches # 2679d6430f71SJoe Perches } else { 2680d6430f71SJoe Perches check_absolute_file($file, $herecurr); 2681d6430f71SJoe Perches } 2682d6430f71SJoe Perches } 2683d6430f71SJoe Perches } 2684d6430f71SJoe Perches 268566b47b4aSKees Cook# Check for various typo / spelling mistakes 268666d7a382SJoe Perches if (defined($misspellings) && 268766d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2688ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 268966b47b4aSKees Cook my $typo = $1; 269066b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 269166b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 269266b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 269366b47b4aSKees Cook my $msg_type = \&WARN; 269466b47b4aSKees Cook $msg_type = \&CHK if ($file); 269566b47b4aSKees Cook if (&{$msg_type}("TYPO_SPELLING", 269666b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 269766b47b4aSKees Cook $fix) { 269866b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 269966b47b4aSKees Cook } 270066b47b4aSKees Cook } 270166b47b4aSKees Cook } 270266b47b4aSKees Cook 270330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 270430670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 270500df344fSAndy Whitcroft 27060a920b5bSAndy Whitcroft#trailing whitespace 27079c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2708c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2709d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2710d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2711d5e616fcSJoe Perches $fix) { 2712194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2713d5e616fcSJoe Perches } 2714c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2715c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27163705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 27173705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 27183705ce5bSJoe Perches $fix) { 2719194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 27203705ce5bSJoe Perches } 27213705ce5bSJoe Perches 2722d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 27230a920b5bSAndy Whitcroft } 27245368df20SAndy Whitcroft 27254783f894SJosh Triplett# Check for FSF mailing addresses. 2726109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 27271bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 27283e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 27293e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 27304783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27314783f894SJosh Triplett my $msg_type = \&ERROR; 27324783f894SJosh Triplett $msg_type = \&CHK if ($file); 27334783f894SJosh Triplett &{$msg_type}("FSF_MAILING_ADDRESS", 27344783f894SJosh 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) 27354783f894SJosh Triplett } 27364783f894SJosh Triplett 27373354957aSAndi Kleen# check for Kconfig help text having a real description 27389fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 27399fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 27403354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 27418d73e0e7SJoe Perches $line =~ /^\+\s*config\s+/) { 27423354957aSAndi Kleen my $length = 0; 27439fe287d7SAndy Whitcroft my $cnt = $realcnt; 27449fe287d7SAndy Whitcroft my $ln = $linenr + 1; 27459fe287d7SAndy Whitcroft my $f; 2746a1385803SAndy Whitcroft my $is_start = 0; 27479fe287d7SAndy Whitcroft my $is_end = 0; 2748a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 27499fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 27509fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 27519fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 27529fe287d7SAndy Whitcroft 27539fe287d7SAndy Whitcroft next if ($f =~ /^-/); 27548d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 2755a1385803SAndy Whitcroft 27568d73e0e7SJoe Perches if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2757a1385803SAndy Whitcroft $is_start = 1; 27588d73e0e7SJoe Perches } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2759a1385803SAndy Whitcroft $length = -1; 2760a1385803SAndy Whitcroft } 2761a1385803SAndy Whitcroft 27629fe287d7SAndy Whitcroft $f =~ s/^.//; 27633354957aSAndi Kleen $f =~ s/#.*//; 27643354957aSAndi Kleen $f =~ s/^\s+//; 27653354957aSAndi Kleen next if ($f =~ /^$/); 27669fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 27679fe287d7SAndy Whitcroft $is_end = 1; 27689fe287d7SAndy Whitcroft last; 27699fe287d7SAndy Whitcroft } 27703354957aSAndi Kleen $length++; 27713354957aSAndi Kleen } 277256193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 2773000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 277456193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 277556193274SVadim Bendebury } 2776a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 27773354957aSAndi Kleen } 27783354957aSAndi Kleen 2779*628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form 2780*628f91a2SJoe Perches if ($realfile =~ /^MAINTAINERS$/ && 2781*628f91a2SJoe Perches $rawline =~ /^\+[A-Z]:/ && 2782*628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 2783*628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 2784*628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 2785*628f91a2SJoe Perches $fix) { 2786*628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 2787*628f91a2SJoe Perches } 2788*628f91a2SJoe Perches } 2789*628f91a2SJoe Perches 2790327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 2791327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 2792327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 2793327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 2794327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2795327953e9SChristoph Jaeger } 2796327953e9SChristoph Jaeger 2797c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2798c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2799c68e5878SArnaud Lacombe my $flag = $1; 2800c68e5878SArnaud Lacombe my $replacement = { 2801c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 2802c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 2803c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 2804c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 2805c68e5878SArnaud Lacombe }; 2806c68e5878SArnaud Lacombe 2807c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 2808c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2809c68e5878SArnaud Lacombe } 2810c68e5878SArnaud Lacombe 2811bff5da43SRob Herring# check for DT compatible documentation 28127dd05b38SFlorian Vaussard if (defined $root && 28137dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 28147dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 28157dd05b38SFlorian Vaussard 2816bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 2817bff5da43SRob Herring 2818cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 2819cc93319bSFlorian Vaussard my $vp_file = $dt_path . "vendor-prefixes.txt"; 2820cc93319bSFlorian Vaussard 2821bff5da43SRob Herring foreach my $compat (@compats) { 2822bff5da43SRob Herring my $compat2 = $compat; 2823185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 2824185d566bSRob Herring my $compat3 = $compat; 2825185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 2826185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 2827bff5da43SRob Herring if ( $? >> 8 ) { 2828bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2829bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 2830bff5da43SRob Herring } 2831bff5da43SRob Herring 28324fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 28334fbf32a6SFlorian Vaussard my $vendor = $1; 2834cc93319bSFlorian Vaussard `grep -Eq "^$vendor\\b" $vp_file`; 2835bff5da43SRob Herring if ( $? >> 8 ) { 2836bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2837cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 2838bff5da43SRob Herring } 2839bff5da43SRob Herring } 2840bff5da43SRob Herring } 2841bff5da43SRob Herring 28425368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 2843d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 28445368df20SAndy Whitcroft 284547e0c88bSJoe Perches# line length limit (with some exclusions) 284647e0c88bSJoe Perches# 284747e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 284847e0c88bSJoe Perches# logging functions like pr_info that end in a string 284947e0c88bSJoe Perches# lines with a single string 285047e0c88bSJoe Perches# #defines that are a single string 285147e0c88bSJoe Perches# 285247e0c88bSJoe Perches# There are 3 different line length message types: 285347e0c88bSJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength 285447e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 285547e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 285647e0c88bSJoe Perches# 285747e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 285847e0c88bSJoe Perches# 285947e0c88bSJoe Perches 2860b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 286147e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 286247e0c88bSJoe Perches 286347e0c88bSJoe Perches # Check the allowed long line types first 286447e0c88bSJoe Perches 286547e0c88bSJoe Perches # logging functions that end in a string that starts 286647e0c88bSJoe Perches # before $max_line_length 286747e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 286847e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 286947e0c88bSJoe Perches $msg_type = ""; 287047e0c88bSJoe Perches 287147e0c88bSJoe Perches # lines with only strings (w/ possible termination) 287247e0c88bSJoe Perches # #defines with only strings 287347e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 287447e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 287547e0c88bSJoe Perches $msg_type = ""; 287647e0c88bSJoe Perches 2877d560a5f8SJoe Perches # EFI_GUID is another special case 2878d560a5f8SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { 2879d560a5f8SJoe Perches $msg_type = ""; 2880d560a5f8SJoe Perches 288147e0c88bSJoe Perches # Otherwise set the alternate message types 288247e0c88bSJoe Perches 288347e0c88bSJoe Perches # a comment starts before $max_line_length 288447e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 288547e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 288647e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 288747e0c88bSJoe Perches 288847e0c88bSJoe Perches # a quoted string starts before $max_line_length 288947e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 289047e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 289147e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 289247e0c88bSJoe Perches } 289347e0c88bSJoe Perches 289447e0c88bSJoe Perches if ($msg_type ne "" && 289547e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 289647e0c88bSJoe Perches WARN($msg_type, 28976cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 28980a920b5bSAndy Whitcroft } 289947e0c88bSJoe Perches } 29000a920b5bSAndy Whitcroft 29018905a67cSAndy Whitcroft# check for adding lines without a newline. 29028905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2903000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 2904000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 29058905a67cSAndy Whitcroft } 29068905a67cSAndy Whitcroft 290742e41c54SMike Frysinger# Blackfin: use hi/lo macros 290842e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 290942e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 291042e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2911000d1cc1SJoe Perches ERROR("LO_MACRO", 2912000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 291342e41c54SMike Frysinger } 291442e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 291542e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2916000d1cc1SJoe Perches ERROR("HI_MACRO", 2917000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 291842e41c54SMike Frysinger } 291942e41c54SMike Frysinger } 292042e41c54SMike Frysinger 2921b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2922de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 29230a920b5bSAndy Whitcroft 29240a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 29250a920b5bSAndy Whitcroft# more than 8 must use tabs. 2926c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2927c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2928c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2929d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29303705ce5bSJoe Perches if (ERROR("CODE_INDENT", 29313705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 29323705ce5bSJoe Perches $fix) { 2933194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 29343705ce5bSJoe Perches } 29350a920b5bSAndy Whitcroft } 29360a920b5bSAndy Whitcroft 293708e44365SAlberto Panizzo# check for space before tabs. 293808e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 293908e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29403705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 29413705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 29423705ce5bSJoe Perches $fix) { 2943194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2944d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 2945194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2946c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 29473705ce5bSJoe Perches } 294808e44365SAlberto Panizzo } 294908e44365SAlberto Panizzo 2950d1fe9c09SJoe Perches# check for && or || at the start of a line 2951d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2952d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2953d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2954d1fe9c09SJoe Perches } 2955d1fe9c09SJoe Perches 2956a91e8994SJoe Perches# check indentation starts on a tab stop 2957a91e8994SJoe Perches if ($^V && $^V ge 5.10.0 && 2958a91e8994SJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { 2959a91e8994SJoe Perches my $indent = length($1); 2960a91e8994SJoe Perches if ($indent % 8) { 2961a91e8994SJoe Perches if (WARN("TABSTOP", 2962a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 2963a91e8994SJoe Perches $fix) { 2964a91e8994SJoe Perches $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 2965a91e8994SJoe Perches } 2966a91e8994SJoe Perches } 2967a91e8994SJoe Perches } 2968a91e8994SJoe Perches 2969d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2970d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 297191cb5195SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2972d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2973d1fe9c09SJoe Perches my $oldindent = $1; 2974d1fe9c09SJoe Perches my $rest = $2; 2975d1fe9c09SJoe Perches 2976d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2977d1fe9c09SJoe Perches if ($pos >= 0) { 2978b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2979b34a26f3SJoe Perches my $newindent = $2; 2980d1fe9c09SJoe Perches 2981d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2982d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2983d1fe9c09SJoe Perches " " x ($pos % 8); 2984d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2985d1fe9c09SJoe Perches 2986d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2987d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 29883705ce5bSJoe Perches 29893705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 29903705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 29913705ce5bSJoe Perches $fix && $line =~ /^\+/) { 2992194f66fcSJoe Perches $fixed[$fixlinenr] =~ 29933705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 29943705ce5bSJoe Perches } 2995d1fe9c09SJoe Perches } 2996d1fe9c09SJoe Perches } 2997d1fe9c09SJoe Perches } 2998d1fe9c09SJoe Perches 29996ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 30006ab3a970SJoe Perches# avoid checking a few false positives: 30016ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 30026ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 30036ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 30046ab3a970SJoe Perches# multiline macros that define functions 30056ab3a970SJoe Perches# known attributes or the __attribute__ keyword 30066ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 30076ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 30083705ce5bSJoe Perches if (CHK("SPACING", 3009f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 30103705ce5bSJoe Perches $fix) { 3011194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3012f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 30133705ce5bSJoe Perches } 3014aad4f614SJoe Perches } 3015aad4f614SJoe Perches 301686406b1cSJoe Perches# Block comment styles 301786406b1cSJoe Perches# Networking with an initial /* 301805880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3019fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 302085ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 302185ad978cSJoe Perches $realline > 2) { 302205880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 302305880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 302405880600SJoe Perches } 302505880600SJoe Perches 302686406b1cSJoe Perches# Block comments use * on subsequent lines 302786406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 302886406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3029a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 303061135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3031a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 303286406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 303386406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3034a605e32eSJoe Perches } 3035a605e32eSJoe Perches 303686406b1cSJoe Perches# Block comments use */ on trailing lines 303786406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3038c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3039c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3040c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 304186406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 304286406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 304305880600SJoe Perches } 304405880600SJoe Perches 304508eb9b80SJoe Perches# Block comment * alignment 304608eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3047af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3048af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3049af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 305008eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3051af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3052af207524SJoe Perches my $oldindent; 305308eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3054af207524SJoe Perches if (defined($1)) { 3055af207524SJoe Perches $oldindent = expand_tabs($1); 3056af207524SJoe Perches } else { 3057af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3058af207524SJoe Perches $oldindent = expand_tabs($1); 3059af207524SJoe Perches } 306008eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 306108eb9b80SJoe Perches my $newindent = $1; 306208eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3063af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 306408eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 306508eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 306608eb9b80SJoe Perches } 306708eb9b80SJoe Perches } 306808eb9b80SJoe Perches 30697f619191SJoe Perches# check for missing blank lines after struct/union declarations 30707f619191SJoe Perches# with exceptions for various attributes and macros 30717f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 30727f619191SJoe Perches $line =~ /^\+/ && 30737f619191SJoe Perches !($line =~ /^\+\s*$/ || 30747f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 30757f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 30767f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 30777f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 30787f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 30797f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 30807f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3081d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3082d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3083d752fcc8SJoe Perches $fix) { 3084f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3085d752fcc8SJoe Perches } 30867f619191SJoe Perches } 30877f619191SJoe Perches 3088365dd4eaSJoe Perches# check for multiple consecutive blank lines 3089365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3090365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3091365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3092d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3093d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3094d752fcc8SJoe Perches $fix) { 3095f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3096d752fcc8SJoe Perches } 3097d752fcc8SJoe Perches 3098365dd4eaSJoe Perches $last_blank_line = $linenr; 3099365dd4eaSJoe Perches } 3100365dd4eaSJoe Perches 31013b617e3bSJoe Perches# check for missing blank lines after declarations 31023f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 31033f7bac03SJoe Perches # actual declarations 31043f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31055a4e1fd3SJoe Perches # function pointer declarations 31065a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31073f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31083f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31093f7bac03SJoe Perches # known declaration macros 31103f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 31113f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 31123f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 31133f7bac03SJoe Perches # other possible extensions of declaration lines 31143f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 31153f7bac03SJoe Perches # not starting a section or a macro "\" extended line 31163f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 31173f7bac03SJoe Perches # looks like a declaration 31183f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31195a4e1fd3SJoe Perches # function pointer declarations 31205a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31213f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31223f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31233f7bac03SJoe Perches # known declaration macros 31243f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 31253f7bac03SJoe Perches # start of struct or union or enum 31263b617e3bSJoe Perches $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 31273f7bac03SJoe Perches # start or end of block or continuation of declaration 31283f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 31293f7bac03SJoe Perches # bitfield continuation 31303f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 31313f7bac03SJoe Perches # other possible extensions of declaration lines 31323f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 31333f7bac03SJoe Perches # indentation of previous and current line are the same 31343f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3135d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3136d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3137d752fcc8SJoe Perches $fix) { 3138f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3139d752fcc8SJoe Perches } 31403b617e3bSJoe Perches } 31413b617e3bSJoe Perches 31425f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 31436b4c5bebSAndy Whitcroft# Exceptions: 31446b4c5bebSAndy Whitcroft# 1) within comments 31456b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 31466b4c5bebSAndy Whitcroft# 3) hanging labels 31473705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 31485f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 31493705ce5bSJoe Perches if (WARN("LEADING_SPACE", 31503705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 31513705ce5bSJoe Perches $fix) { 3152194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31533705ce5bSJoe Perches } 31545f7ddae6SRaffaele Recalcati } 31555f7ddae6SRaffaele Recalcati 3156b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3157b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3158b9ea10d6SAndy Whitcroft 31594dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 31604dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 31614dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 31624dbed76fSJoe Perches $context_function = $1; 31634dbed76fSJoe Perches } 31644dbed76fSJoe Perches 31654dbed76fSJoe Perches# check if this appears to be the end of function declaration 31664dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 31674dbed76fSJoe Perches undef $context_function; 31684dbed76fSJoe Perches } 31694dbed76fSJoe Perches 3170032a4c0fSJoe Perches# check indentation of any line with a bare else 3171840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3172032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3173032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3174032a4c0fSJoe Perches my $tabs = length($1) + 1; 3175840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3176840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3177840080a0SJoe Perches defined $lines[$linenr] && 3178840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3179032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3180032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3181032a4c0fSJoe Perches } 3182032a4c0fSJoe Perches } 3183032a4c0fSJoe Perches 3184c00df19aSJoe Perches# check indentation of a line with a break; 3185c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3186c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3187c00df19aSJoe Perches my $tabs = $1; 3188c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3189c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3190c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3191c00df19aSJoe Perches } 3192c00df19aSJoe Perches } 3193c00df19aSJoe Perches 3194c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3195cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3196000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3197000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3198c2fdda0dSAndy Whitcroft } 319922f2a2efSAndy Whitcroft 320042e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 320142e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 320242e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3203000d1cc1SJoe Perches ERROR("CSYNC", 3204000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 320542e41c54SMike Frysinger } 320642e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 320742e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3208000d1cc1SJoe Perches ERROR("SSYNC", 3209000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 321042e41c54SMike Frysinger } 321142e41c54SMike Frysinger 321256e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 321356e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 321456e77d70SJoe Perches WARN("HOTPLUG_SECTION", 321556e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 321656e77d70SJoe Perches } 321756e77d70SJoe Perches 32189c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 32192b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 32202b474a1aSAndy Whitcroft $realline_next); 32213e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 32223e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 32231b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3224170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3225f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3226171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3227171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3228171ae1a4SAndy Whitcroft 32293e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 32303e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 32313e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 32323e469cdcSAndy Whitcroft # until we hit end of it. 32333e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 32343e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 32353e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 32363e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 32373e469cdcSAndy Whitcroft } 3238f74bd194SAndy Whitcroft 32392b474a1aSAndy Whitcroft # Find the real next line. 32402b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 32412b474a1aSAndy Whitcroft if (defined $realline_next && 32422b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 32432b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 32442b474a1aSAndy Whitcroft $realline_next++; 32452b474a1aSAndy Whitcroft } 32462b474a1aSAndy Whitcroft 3247171ae1a4SAndy Whitcroft my $s = $stat; 3248171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3249cf655043SAndy Whitcroft 3250c2fdda0dSAndy Whitcroft # Ignore goto labels. 3251171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3252c2fdda0dSAndy Whitcroft 3253c2fdda0dSAndy Whitcroft # Ignore functions being called 3254171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3255c2fdda0dSAndy Whitcroft 3256463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3257463f2864SAndy Whitcroft 3258c45dcabdSAndy Whitcroft # declarations always start with types 3259d2506586SAndy 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) { 3260c45dcabdSAndy Whitcroft my $type = $1; 3261c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3262c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3263c45dcabdSAndy Whitcroft 32646c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3265a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3266c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3267c2fdda0dSAndy Whitcroft } 32688905a67cSAndy Whitcroft 32696c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 327065863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3271c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 32729c0ca6f9SAndy Whitcroft } 32738905a67cSAndy Whitcroft 32748905a67cSAndy Whitcroft # Check for any sort of function declaration. 32758905a67cSAndy Whitcroft # int foo(something bar, other baz); 32768905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3277171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 32788905a67cSAndy Whitcroft my ($name_len) = length($1); 32798905a67cSAndy Whitcroft 3280cf655043SAndy Whitcroft my $ctx = $s; 3281773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 32828905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3283cf655043SAndy Whitcroft 32848905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3285c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 32868905a67cSAndy Whitcroft 3287c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 32888905a67cSAndy Whitcroft } 32898905a67cSAndy Whitcroft } 32908905a67cSAndy Whitcroft } 32918905a67cSAndy Whitcroft 32929c0ca6f9SAndy Whitcroft } 32939c0ca6f9SAndy Whitcroft 329400df344fSAndy Whitcroft# 329500df344fSAndy Whitcroft# Checks which may be anchored in the context. 329600df344fSAndy Whitcroft# 329700df344fSAndy Whitcroft 329800df344fSAndy Whitcroft# Check for switch () and associated case and default 329900df344fSAndy Whitcroft# statements should be at the same indent. 330000df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 330100df344fSAndy Whitcroft my $err = ''; 330200df344fSAndy Whitcroft my $sep = ''; 330300df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 330400df344fSAndy Whitcroft shift(@ctx); 330500df344fSAndy Whitcroft for my $ctx (@ctx) { 330600df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 330700df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 330800df344fSAndy Whitcroft $indent != $cindent) { 330900df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 331000df344fSAndy Whitcroft $sep = ''; 331100df344fSAndy Whitcroft } else { 331200df344fSAndy Whitcroft $sep = "[...]\n"; 331300df344fSAndy Whitcroft } 331400df344fSAndy Whitcroft } 331500df344fSAndy Whitcroft if ($err ne '') { 3316000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3317000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3318de7d4f0eSAndy Whitcroft } 3319de7d4f0eSAndy Whitcroft } 3320de7d4f0eSAndy Whitcroft 3321de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3322de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 33230fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3324773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3325773647a0SAndy Whitcroft 33269c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 33278eef05ddSJoe Perches 33288eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 33298eef05ddSJoe Perches WARN("DEEP_INDENTATION", 33308eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 33318eef05ddSJoe Perches } 33328eef05ddSJoe Perches 3333de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3334de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3335de7d4f0eSAndy Whitcroft 3336548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3337548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3338de7d4f0eSAndy Whitcroft 3339548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3340548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3341548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3342548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3343548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3344773647a0SAndy Whitcroft $ctx_ln++; 3345773647a0SAndy Whitcroft } 3346548596d5SAndy Whitcroft 334753210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 334853210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3349773647a0SAndy Whitcroft 3350773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3351000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3352000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 335301464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 335400df344fSAndy Whitcroft } 3355773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3356773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3357773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3358773647a0SAndy Whitcroft { 33599c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 33609c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3361000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3362000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 336301464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 33649c0ca6f9SAndy Whitcroft } 33659c0ca6f9SAndy Whitcroft } 336600df344fSAndy Whitcroft } 336700df344fSAndy Whitcroft 33684d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3369f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 33703e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 33713e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 33723e469cdcSAndy Whitcroft if (!defined $stat); 33734d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 33744d001e4dSAndy Whitcroft 33754d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 33764d001e4dSAndy Whitcroft 33779f5af480SJoe Perches # remove inline comments 33789f5af480SJoe Perches $s =~ s/$;/ /g; 33799f5af480SJoe Perches $c =~ s/$;/ /g; 33804d001e4dSAndy Whitcroft 33814d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 33826f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 33836f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 33844d001e4dSAndy Whitcroft 33859f5af480SJoe Perches # Make sure we remove the line prefixes as we have 33869f5af480SJoe Perches # none on the first line, and are going to readd them 33879f5af480SJoe Perches # where necessary. 33889f5af480SJoe Perches $s =~ s/\n./\n/gs; 33899f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 33909f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 33919f5af480SJoe Perches } 33929f5af480SJoe Perches 33934d001e4dSAndy Whitcroft # We want to check the first line inside the block 33944d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 33954d001e4dSAndy Whitcroft # 1) any blank line termination 33964d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 33974d001e4dSAndy Whitcroft # 3) any do (...) { 33984d001e4dSAndy Whitcroft my $continuation = 0; 33994d001e4dSAndy Whitcroft my $check = 0; 34004d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 34014d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 34024d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 34034d001e4dSAndy Whitcroft $continuation = 1; 34044d001e4dSAndy Whitcroft } 34059bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 34064d001e4dSAndy Whitcroft $check = 1; 34074d001e4dSAndy Whitcroft $cond_lines++; 34084d001e4dSAndy Whitcroft } 34094d001e4dSAndy Whitcroft 34104d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 34114d001e4dSAndy Whitcroft # preprocessor statement. 34124d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 34134d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 34144d001e4dSAndy Whitcroft $check = 0; 34154d001e4dSAndy Whitcroft } 34164d001e4dSAndy Whitcroft 34179bd49efeSAndy Whitcroft my $cond_ptr = -1; 3418740504c6SAndy Whitcroft $continuation = 0; 34199bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 34209bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 34214d001e4dSAndy Whitcroft 3422f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3423f16fa28fSAndy Whitcroft # is not linear. 3424f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3425f16fa28fSAndy Whitcroft $check = 0; 3426f16fa28fSAndy Whitcroft } 3427f16fa28fSAndy Whitcroft 34289bd49efeSAndy Whitcroft # Ignore: 34299bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 34309bd49efeSAndy Whitcroft # 2) preprocessor lines, and 34319bd49efeSAndy Whitcroft # 3) labels. 3432740504c6SAndy Whitcroft if ($continuation || 3433740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 34349bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 34359bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3436740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 343730dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 34389bd49efeSAndy Whitcroft $cond_lines++; 34399bd49efeSAndy Whitcroft } 34404d001e4dSAndy Whitcroft } 344130dad6ebSAndy Whitcroft } 34424d001e4dSAndy Whitcroft 34434d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 34444d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 34454d001e4dSAndy Whitcroft 34464d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 34474d001e4dSAndy Whitcroft # this is not this patch's fault. 34484d001e4dSAndy Whitcroft if (!defined($stat_real) || 34494d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 34504d001e4dSAndy Whitcroft $check = 0; 34514d001e4dSAndy Whitcroft } 34524d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 34534d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 34544d001e4dSAndy Whitcroft } 34554d001e4dSAndy Whitcroft 34569bd49efeSAndy 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"; 34574d001e4dSAndy Whitcroft 34589f5af480SJoe Perches if ($check && $s ne '' && 34599f5af480SJoe Perches (($sindent % 8) != 0 || 34609f5af480SJoe Perches ($sindent < $indent) || 3461f6950a73SJoe Perches ($sindent == $indent && 3462f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 34639f5af480SJoe Perches ($sindent > $indent + 8))) { 3464000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3465000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 34664d001e4dSAndy Whitcroft } 34674d001e4dSAndy Whitcroft } 34684d001e4dSAndy Whitcroft 34696c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 34706c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 34711f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 34721f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 34736c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3474c2fdda0dSAndy Whitcroft if ($dbg_values) { 3475c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3476cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3477cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 34781f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3479c2fdda0dSAndy Whitcroft } 34806c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 34816c72ffaaSAndy Whitcroft 348200df344fSAndy Whitcroft#ignore lines not being added 34833705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 348400df344fSAndy Whitcroft 348511ca40a0SJoe Perches# check for dereferences that span multiple lines 348611ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 348711ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 348811ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 348911ca40a0SJoe Perches my $ref = $1; 349011ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 349111ca40a0SJoe Perches $ref .= $1; 349211ca40a0SJoe Perches $ref =~ s/\s//g; 349311ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 349411ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 349511ca40a0SJoe Perches } 349611ca40a0SJoe Perches 3497a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3498c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3499a1ce18e4SJoe Perches my $type = $1; 3500a1ce18e4SJoe Perches my $var = $2; 3501207a8e84SJoe Perches $var = "" if (!defined $var); 3502207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3503a1ce18e4SJoe Perches my $sign = $1; 3504a1ce18e4SJoe Perches my $pointer = $2; 3505a1ce18e4SJoe Perches 3506a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3507a1ce18e4SJoe Perches 3508a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3509a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3510a1ce18e4SJoe Perches $fix) { 3511a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3512207a8e84SJoe Perches my $comp_pointer = $pointer; 3513207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3514207a8e84SJoe Perches $decl .= $comp_pointer; 3515207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3516207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3517a1ce18e4SJoe Perches } 3518a1ce18e4SJoe Perches } 3519a1ce18e4SJoe Perches } 3520a1ce18e4SJoe Perches 3521653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 35227429c690SAndy Whitcroft if ($dbg_type) { 35237429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3524000d1cc1SJoe Perches ERROR("TEST_TYPE", 3525000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 35267429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3527000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3528000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 35297429c690SAndy Whitcroft } 3530653d4876SAndy Whitcroft next; 3531653d4876SAndy Whitcroft } 3532a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3533a1ef277eSAndy Whitcroft if ($dbg_attr) { 35349360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3535000d1cc1SJoe Perches ERROR("TEST_ATTR", 3536000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 35379360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3538000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3539000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3540a1ef277eSAndy Whitcroft } 3541a1ef277eSAndy Whitcroft next; 3542a1ef277eSAndy Whitcroft } 3543653d4876SAndy Whitcroft 3544f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 354599423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 354699423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3547d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3548d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3549f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3550f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3551f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3552d752fcc8SJoe Perches my $fixedline = $prevrawline; 3553d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3554f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3555d752fcc8SJoe Perches $fixedline = $line; 3556d752fcc8SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1/; 3557f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3558d752fcc8SJoe Perches } 3559f0a594c1SAndy Whitcroft } 3560f0a594c1SAndy Whitcroft 356100df344fSAndy Whitcroft# 356200df344fSAndy Whitcroft# Checks which are anchored on the added line. 356300df344fSAndy Whitcroft# 356400df344fSAndy Whitcroft 3565653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3566c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3567653d4876SAndy Whitcroft my $path = $1; 3568653d4876SAndy Whitcroft if ($path =~ m{//}) { 3569000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3570495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3571495e9d84SJoe Perches } 3572495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3573495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3574495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3575653d4876SAndy Whitcroft } 3576653d4876SAndy Whitcroft } 3577653d4876SAndy Whitcroft 357800df344fSAndy Whitcroft# no C99 // comments 357900df344fSAndy Whitcroft if ($line =~ m{//}) { 35803705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 35813705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 35823705ce5bSJoe Perches $fix) { 3583194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 35843705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 35853705ce5bSJoe Perches my $comment = trim($1); 3586194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 35873705ce5bSJoe Perches } 35883705ce5bSJoe Perches } 358900df344fSAndy Whitcroft } 359000df344fSAndy Whitcroft # Remove C99 comments. 35910a920b5bSAndy Whitcroft $line =~ s@//.*@@; 35926c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 35930a920b5bSAndy Whitcroft 35942b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 35952b474a1aSAndy Whitcroft# the whole statement. 35962b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 35972b474a1aSAndy Whitcroft if (defined $realline_next && 35982b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 35992b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 36002b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36012b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36023cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 36033cbf62dfSAndy Whitcroft # a prefix: 36043cbf62dfSAndy Whitcroft # XXX(foo); 36053cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3606653d4876SAndy Whitcroft my $name = $1; 360787a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 36083cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 36093cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 36103cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 36113cbf62dfSAndy Whitcroft 36123cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 36132b474a1aSAndy Whitcroft \n.}\s*$| 361448012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 361548012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 361648012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 36172b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 36182b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 361948012058SAndy Whitcroft )/x) { 36202b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 36212b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 36222b474a1aSAndy Whitcroft } else { 36232b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 36240a920b5bSAndy Whitcroft } 36250a920b5bSAndy Whitcroft } 36262b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 36272b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 36282b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36292b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36302b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 36312b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 36322b474a1aSAndy Whitcroft } 36332b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 36342b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3635000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3636000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 36372b474a1aSAndy Whitcroft } 36380a920b5bSAndy Whitcroft 36395150bda4SJoe Eloff# check for global initialisers. 36406d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3641d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 36426d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3643d5e616fcSJoe Perches $fix) { 36446d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3645d5e616fcSJoe Perches } 3646f0a594c1SAndy Whitcroft } 36470a920b5bSAndy Whitcroft# check for static initialisers. 36486d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3649d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 36506d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3651d5e616fcSJoe Perches $herecurr) && 3652d5e616fcSJoe Perches $fix) { 36536d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3654d5e616fcSJoe Perches } 36550a920b5bSAndy Whitcroft } 36560a920b5bSAndy Whitcroft 36571813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 36581813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36591813087dSJoe Perches my $tmp = trim($1); 36601813087dSJoe Perches WARN("MISORDERED_TYPE", 36611813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36621813087dSJoe Perches } 36631813087dSJoe Perches 3664cb710ecaSJoe Perches# check for static const char * arrays. 3665cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3666000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3667000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3668cb710ecaSJoe Perches $herecurr); 3669cb710ecaSJoe Perches } 3670cb710ecaSJoe Perches 3671cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3672cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3673000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3674000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3675cb710ecaSJoe Perches $herecurr); 3676cb710ecaSJoe Perches } 3677cb710ecaSJoe Perches 3678ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3679ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3680ab7e23f3SJoe Perches my $found = $1; 3681ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3682ab7e23f3SJoe Perches WARN("CONST_CONST", 3683ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3684ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3685ab7e23f3SJoe Perches WARN("CONST_CONST", 3686ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3687ab7e23f3SJoe Perches } 3688ab7e23f3SJoe Perches } 3689ab7e23f3SJoe Perches 36909b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 36919b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 36929b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 36939b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 36949b0fa60dSJoe Perches $herecurr); 36959b0fa60dSJoe Perches } 36969b0fa60dSJoe Perches 3697b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3698b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3699b598b670SJoe Perches my $array = $1; 3700b598b670SJoe 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*\))@) { 3701b598b670SJoe Perches my $array_div = $1; 3702b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3703b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3704b598b670SJoe Perches $fix) { 3705b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3706b598b670SJoe Perches } 3707b598b670SJoe Perches } 3708b598b670SJoe Perches } 3709b598b670SJoe Perches 3710b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3711b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3712b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3713b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3714b36190c5SJoe Perches $fix) { 3715194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3716b36190c5SJoe Perches } 3717b36190c5SJoe Perches } 3718b36190c5SJoe Perches 3719653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3720653d4876SAndy Whitcroft# make sense. 3721653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 37228054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3723c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 37248ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 372546d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 3726000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3727000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 37280a920b5bSAndy Whitcroft } 37290a920b5bSAndy Whitcroft 37300a920b5bSAndy Whitcroft# * goes on variable not on type 373165863862SAndy Whitcroft # (char*[ const]) 3732bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3733bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 37343705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3735d8aaf121SAndy Whitcroft 373665863862SAndy Whitcroft # Should start with a space. 373765863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 373865863862SAndy Whitcroft # Should not end with a space. 373965863862SAndy Whitcroft $to =~ s/\s+$//; 374065863862SAndy Whitcroft # '*'s should not have spaces between. 3741f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 374265863862SAndy Whitcroft } 3743d8aaf121SAndy Whitcroft 37443705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 374565863862SAndy Whitcroft if ($from ne $to) { 37463705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37473705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37483705ce5bSJoe Perches $fix) { 37493705ce5bSJoe Perches my $sub_from = $ident; 37503705ce5bSJoe Perches my $sub_to = $ident; 37513705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3752194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37533705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37543705ce5bSJoe Perches } 375565863862SAndy Whitcroft } 3756bfcb2cc7SAndy Whitcroft } 3757bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3758bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 37593705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3760d8aaf121SAndy Whitcroft 376165863862SAndy Whitcroft # Should start with a space. 376265863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 376365863862SAndy Whitcroft # Should not end with a space. 376465863862SAndy Whitcroft $to =~ s/\s+$//; 376565863862SAndy Whitcroft # '*'s should not have spaces between. 3766f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 376765863862SAndy Whitcroft } 376865863862SAndy Whitcroft # Modifiers should have spaces. 376965863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 377065863862SAndy Whitcroft 37713705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3772667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 37733705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37743705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 37753705ce5bSJoe Perches $fix) { 37763705ce5bSJoe Perches 37773705ce5bSJoe Perches my $sub_from = $match; 37783705ce5bSJoe Perches my $sub_to = $match; 37793705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3780194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37813705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37823705ce5bSJoe Perches } 378365863862SAndy Whitcroft } 37840a920b5bSAndy Whitcroft } 37850a920b5bSAndy Whitcroft 37869d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 37879d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 37889d3e3c70SJoe Perches my $msg_type = \&WARN; 37899d3e3c70SJoe Perches $msg_type = \&CHK if ($file); 37909d3e3c70SJoe Perches &{$msg_type}("AVOID_BUG", 37919d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 37929d3e3c70SJoe Perches } 37930a920b5bSAndy Whitcroft 37949d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 37958905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3796000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3797000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 37988905a67cSAndy Whitcroft } 37998905a67cSAndy Whitcroft 380017441227SJoe Perches# check for uses of printk_ratelimit 380117441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3802000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3803000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 380417441227SJoe Perches } 380517441227SJoe Perches 380600df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 380700df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 380800df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 380925985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 381000df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3811f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 381200df344fSAndy Whitcroft my $ok = 0; 381300df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 381400df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 381525985edcSLucas De Marchi # we have a preceding printk if it ends 381600df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 381700df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 381800df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 381900df344fSAndy Whitcroft $ok = 1; 382000df344fSAndy Whitcroft } 382100df344fSAndy Whitcroft last; 382200df344fSAndy Whitcroft } 382300df344fSAndy Whitcroft } 382400df344fSAndy Whitcroft if ($ok == 0) { 3825000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3826000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 38270a920b5bSAndy Whitcroft } 382800df344fSAndy Whitcroft } 38290a920b5bSAndy Whitcroft 3830243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3831243f3803SJoe Perches my $orig = $1; 3832243f3803SJoe Perches my $level = lc($orig); 3833243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 38348f26b837SJoe Perches my $level2 = $level; 38358f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3836243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3837daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3838243f3803SJoe Perches } 3839243f3803SJoe Perches 3840243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3841d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3842d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3843d5e616fcSJoe Perches $fix) { 3844194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3845d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3846d5e616fcSJoe Perches } 3847243f3803SJoe Perches } 3848243f3803SJoe Perches 3849dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3850dc139313SJoe Perches my $orig = $1; 3851dc139313SJoe Perches my $level = lc($orig); 3852dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3853dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3854dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3855dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3856dc139313SJoe Perches } 3857dc139313SJoe Perches 385891c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 385991c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 386091c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 386191c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 386291c9afafSAndy Lutomirski WARN("ENOSYS", 386391c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 386491c9afafSAndy Lutomirski } 386591c9afafSAndy Lutomirski 3866653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3867653d4876SAndy Whitcroft# or if closed on same line 38688d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 38694e5d56bdSEddie Kovsky !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38708d182478SJoe Perches if (ERROR("OPEN_BRACE", 38718d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38728d182478SJoe Perches $fix) { 38738d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38748d182478SJoe Perches my $fixed_line = $rawline; 38758d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 38768d182478SJoe Perches my $line1 = $1; 38778d182478SJoe Perches my $line2 = $2; 38788d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 38798d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 38808d182478SJoe Perches if ($line2 !~ /^\s*$/) { 38818d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 38828d182478SJoe Perches } 38838d182478SJoe Perches } 38840a920b5bSAndy Whitcroft } 3885653d4876SAndy Whitcroft 38868905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 38878905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 38888905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 38898d182478SJoe Perches if (ERROR("OPEN_BRACE", 38908d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 38918d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 38928d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 38938d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38948d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 38958d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38968d182478SJoe Perches $fixedline = $rawline; 38978d182478SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1\t/; 38988d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 38998d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 39008d182478SJoe Perches } 39018d182478SJoe Perches } 39028905a67cSAndy Whitcroft } 39038905a67cSAndy Whitcroft 39040c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 39053705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 39063705ce5bSJoe Perches if (WARN("SPACING", 39073705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 39083705ce5bSJoe Perches $fix) { 3909194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39103705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 39113705ce5bSJoe Perches } 39120c73b4ebSAndy Whitcroft } 39130c73b4ebSAndy Whitcroft 391431070b5dSJoe Perches# Function pointer declarations 391531070b5dSJoe Perches# check spacing between type, funcptr, and args 391631070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 391791f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 391831070b5dSJoe Perches my $declare = $1; 391931070b5dSJoe Perches my $pre_pointer_space = $2; 392031070b5dSJoe Perches my $post_pointer_space = $3; 392131070b5dSJoe Perches my $funcname = $4; 392231070b5dSJoe Perches my $post_funcname_space = $5; 392331070b5dSJoe Perches my $pre_args_space = $6; 392431070b5dSJoe Perches 392591f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 392691f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 392791f72e9cSJoe Perches# don't need a space so don't warn for those. 392891f72e9cSJoe Perches my $post_declare_space = ""; 392991f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 393091f72e9cSJoe Perches $post_declare_space = $1; 393191f72e9cSJoe Perches $declare = rtrim($declare); 393291f72e9cSJoe Perches } 393391f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 393431070b5dSJoe Perches WARN("SPACING", 393531070b5dSJoe Perches "missing space after return type\n" . $herecurr); 393691f72e9cSJoe Perches $post_declare_space = " "; 393731070b5dSJoe Perches } 393831070b5dSJoe Perches 393931070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 394091f72e9cSJoe Perches# This test is not currently implemented because these declarations are 394191f72e9cSJoe Perches# equivalent to 394291f72e9cSJoe Perches# int foo(int bar, ...) 394391f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 394491f72e9cSJoe Perches# 394591f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 394691f72e9cSJoe Perches# WARN("SPACING", 394791f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 394891f72e9cSJoe Perches# } 394931070b5dSJoe Perches 395031070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 395131070b5dSJoe Perches if (defined $pre_pointer_space && 395231070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 395331070b5dSJoe Perches WARN("SPACING", 395431070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 395531070b5dSJoe Perches } 395631070b5dSJoe Perches 395731070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 395831070b5dSJoe Perches if (defined $post_pointer_space && 395931070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 396031070b5dSJoe Perches WARN("SPACING", 396131070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 396231070b5dSJoe Perches } 396331070b5dSJoe Perches 396431070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 396531070b5dSJoe Perches if (defined $post_funcname_space && 396631070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 396731070b5dSJoe Perches WARN("SPACING", 396831070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 396931070b5dSJoe Perches } 397031070b5dSJoe Perches 397131070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 397231070b5dSJoe Perches if (defined $pre_args_space && 397331070b5dSJoe Perches $pre_args_space =~ /^\s/) { 397431070b5dSJoe Perches WARN("SPACING", 397531070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 397631070b5dSJoe Perches } 397731070b5dSJoe Perches 397831070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3979194f66fcSJoe Perches $fixed[$fixlinenr] =~ 398091f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 398131070b5dSJoe Perches } 398231070b5dSJoe Perches } 398331070b5dSJoe Perches 39848d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 39858d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3986fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3987fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 39888d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 39898d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 39908d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3991fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3992daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 39933705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 39943705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 39953705ce5bSJoe Perches $fix) { 3996194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39973705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 39983705ce5bSJoe Perches } 39998d31cfceSAndy Whitcroft } 40008d31cfceSAndy Whitcroft } 40018d31cfceSAndy Whitcroft 4002f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 40036c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4004c2fdda0dSAndy Whitcroft my $name = $1; 4005773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4006773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4007c2fdda0dSAndy Whitcroft 4008c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4009773647a0SAndy Whitcroft if ($name =~ /^(?: 4010773647a0SAndy Whitcroft if|for|while|switch|return|case| 4011773647a0SAndy Whitcroft volatile|__volatile__| 4012773647a0SAndy Whitcroft __attribute__|format|__extension__| 4013773647a0SAndy Whitcroft asm|__asm__)$/x) 4014773647a0SAndy Whitcroft { 4015c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4016c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4017c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4018c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4019773647a0SAndy Whitcroft 4020773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4021c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4022c2fdda0dSAndy Whitcroft 4023c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4024c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4025773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4026c2fdda0dSAndy Whitcroft 4027c2fdda0dSAndy Whitcroft } else { 40283705ce5bSJoe Perches if (WARN("SPACING", 40293705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40303705ce5bSJoe Perches $fix) { 4031194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40323705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 40333705ce5bSJoe Perches } 4034f0a594c1SAndy Whitcroft } 40356c72ffaaSAndy Whitcroft } 40369a4cad4eSEric Nelson 4037653d4876SAndy Whitcroft# Check operator spacing. 40380a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 40393705ce5bSJoe Perches my $fixed_line = ""; 40403705ce5bSJoe Perches my $line_fixed = 0; 40413705ce5bSJoe Perches 40429c0ca6f9SAndy Whitcroft my $ops = qr{ 40439c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 40449c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 40459c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 40461f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 404784731623SJoe Perches \?:|\?|: 40489c0ca6f9SAndy Whitcroft }x; 4049cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 40503705ce5bSJoe Perches 40513705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 40523705ce5bSJoe Perches## foreach my $el (@elements) { 40533705ce5bSJoe Perches## print("el: <$el>\n"); 40543705ce5bSJoe Perches## } 40553705ce5bSJoe Perches 40563705ce5bSJoe Perches my @fix_elements = (); 405700df344fSAndy Whitcroft my $off = 0; 40586c72ffaaSAndy Whitcroft 40593705ce5bSJoe Perches foreach my $el (@elements) { 40603705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 40613705ce5bSJoe Perches $off += length($el); 40623705ce5bSJoe Perches } 40633705ce5bSJoe Perches 40643705ce5bSJoe Perches $off = 0; 40653705ce5bSJoe Perches 40666c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4067b34c648bSJoe Perches my $last_after = -1; 40686c72ffaaSAndy Whitcroft 40690a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 40703705ce5bSJoe Perches 40713705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40723705ce5bSJoe Perches 40733705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 40743705ce5bSJoe Perches 40754a0df2efSAndy Whitcroft $off += length($elements[$n]); 40764a0df2efSAndy Whitcroft 407725985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4078773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4079773647a0SAndy Whitcroft my $cc = ''; 4080773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4081773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4082773647a0SAndy Whitcroft } 4083773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4084773647a0SAndy Whitcroft 40854a0df2efSAndy Whitcroft my $a = ''; 40864a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 40874a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4088cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 40894a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 40904a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4091773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 40924a0df2efSAndy Whitcroft 40930a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 40944a0df2efSAndy Whitcroft 40954a0df2efSAndy Whitcroft my $c = ''; 40960a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 40974a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 40984a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4099cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 41004a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 41014a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 41028b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 41034a0df2efSAndy Whitcroft } else { 41044a0df2efSAndy Whitcroft $c = 'E'; 41050a920b5bSAndy Whitcroft } 41060a920b5bSAndy Whitcroft 41074a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 41084a0df2efSAndy Whitcroft 41094a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 41104a0df2efSAndy Whitcroft 41116c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4112de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 41130a920b5bSAndy Whitcroft 411474048ed8SAndy Whitcroft # Pull out the value of this operator. 41156c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 41160a920b5bSAndy Whitcroft 41171f65f947SAndy Whitcroft # Get the full operator variant. 41181f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 41191f65f947SAndy Whitcroft 412013214adfSAndy Whitcroft # Ignore operators passed as parameters. 412113214adfSAndy Whitcroft if ($op_type ne 'V' && 4122d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 412313214adfSAndy Whitcroft 4124cf655043SAndy Whitcroft# # Ignore comments 4125cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 412613214adfSAndy Whitcroft 4127d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 412813214adfSAndy Whitcroft } elsif ($op eq ';') { 4129cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4130cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 41313705ce5bSJoe Perches if (ERROR("SPACING", 41323705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4133b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41343705ce5bSJoe Perches $line_fixed = 1; 41353705ce5bSJoe Perches } 4136d8aaf121SAndy Whitcroft } 4137d8aaf121SAndy Whitcroft 4138d8aaf121SAndy Whitcroft # // is a comment 4139d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 41400a920b5bSAndy Whitcroft 4141b00e4814SJoe Perches # : when part of a bitfield 4142b00e4814SJoe Perches } elsif ($opv eq ':B') { 4143b00e4814SJoe Perches # skip the bitfield test for now 4144b00e4814SJoe Perches 41451f65f947SAndy Whitcroft # No spaces for: 41461f65f947SAndy Whitcroft # -> 4147b00e4814SJoe Perches } elsif ($op eq '->') { 41484a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 41493705ce5bSJoe Perches if (ERROR("SPACING", 41503705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4151b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41523705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 41533705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 41543705ce5bSJoe Perches } 4155b34c648bSJoe Perches $line_fixed = 1; 41563705ce5bSJoe Perches } 41570a920b5bSAndy Whitcroft } 41580a920b5bSAndy Whitcroft 41592381097bSJoe Perches # , must not have a space before and must have a space on the right. 41600a920b5bSAndy Whitcroft } elsif ($op eq ',') { 41612381097bSJoe Perches my $rtrim_before = 0; 41622381097bSJoe Perches my $space_after = 0; 41632381097bSJoe Perches if ($ctx =~ /Wx./) { 41642381097bSJoe Perches if (ERROR("SPACING", 41652381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 41662381097bSJoe Perches $line_fixed = 1; 41672381097bSJoe Perches $rtrim_before = 1; 41682381097bSJoe Perches } 41692381097bSJoe Perches } 4170cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41713705ce5bSJoe Perches if (ERROR("SPACING", 41723705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 41733705ce5bSJoe Perches $line_fixed = 1; 4174b34c648bSJoe Perches $last_after = $n; 41752381097bSJoe Perches $space_after = 1; 41762381097bSJoe Perches } 41772381097bSJoe Perches } 41782381097bSJoe Perches if ($rtrim_before || $space_after) { 41792381097bSJoe Perches if ($rtrim_before) { 41802381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41812381097bSJoe Perches } else { 41822381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 41832381097bSJoe Perches } 41842381097bSJoe Perches if ($space_after) { 41852381097bSJoe Perches $good .= " "; 41863705ce5bSJoe Perches } 41870a920b5bSAndy Whitcroft } 41880a920b5bSAndy Whitcroft 41899c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 419074048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 41919c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 41929c0ca6f9SAndy Whitcroft 41939c0ca6f9SAndy Whitcroft # unary operators should have a space before and 41949c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 41959c0ca6f9SAndy Whitcroft # unary operator, or a cast 41969c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 419774048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 41980d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4199cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 42003705ce5bSJoe Perches if (ERROR("SPACING", 42013705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4202b34c648bSJoe Perches if ($n != $last_after + 2) { 4203b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 42043705ce5bSJoe Perches $line_fixed = 1; 42053705ce5bSJoe Perches } 42060a920b5bSAndy Whitcroft } 4207b34c648bSJoe Perches } 4208a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4209171ae1a4SAndy Whitcroft # A unary '*' may be const 4210171ae1a4SAndy Whitcroft 4211171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 42123705ce5bSJoe Perches if (ERROR("SPACING", 42133705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4214b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42153705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42163705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 42173705ce5bSJoe Perches } 4218b34c648bSJoe Perches $line_fixed = 1; 42193705ce5bSJoe Perches } 42200a920b5bSAndy Whitcroft } 42210a920b5bSAndy Whitcroft 42220a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 42230a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4224773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42253705ce5bSJoe Perches if (ERROR("SPACING", 42263705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4227b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42283705ce5bSJoe Perches $line_fixed = 1; 42293705ce5bSJoe Perches } 42300a920b5bSAndy Whitcroft } 4231773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4232773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42333705ce5bSJoe Perches if (ERROR("SPACING", 42343705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4235b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42363705ce5bSJoe Perches $line_fixed = 1; 42373705ce5bSJoe Perches } 4238653d4876SAndy Whitcroft } 4239773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 42403705ce5bSJoe Perches if (ERROR("SPACING", 42413705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4242b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42433705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42443705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4245773647a0SAndy Whitcroft } 4246b34c648bSJoe Perches $line_fixed = 1; 42473705ce5bSJoe Perches } 42483705ce5bSJoe Perches } 42490a920b5bSAndy Whitcroft 42500a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 42519c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 42529c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 42539c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4254c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4255c2fdda0dSAndy Whitcroft $op eq '%') 42560a920b5bSAndy Whitcroft { 4257d2e025f3SJoe Perches if ($check) { 4258d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4259d2e025f3SJoe Perches if (CHK("SPACING", 4260d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4261d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4262d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4263d2e025f3SJoe Perches $line_fixed = 1; 4264d2e025f3SJoe Perches } 4265d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4266d2e025f3SJoe Perches if (CHK("SPACING", 4267d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4268d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4269d2e025f3SJoe Perches $line_fixed = 1; 4270d2e025f3SJoe Perches } 4271d2e025f3SJoe Perches } 4272d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42733705ce5bSJoe Perches if (ERROR("SPACING", 42743705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4275b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4276b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4277b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4278b34c648bSJoe Perches } 42793705ce5bSJoe Perches $line_fixed = 1; 42803705ce5bSJoe Perches } 42810a920b5bSAndy Whitcroft } 42820a920b5bSAndy Whitcroft 42831f65f947SAndy Whitcroft # A colon needs no spaces before when it is 42841f65f947SAndy Whitcroft # terminating a case value or a label. 42851f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 42861f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 42873705ce5bSJoe Perches if (ERROR("SPACING", 42883705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4289b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42903705ce5bSJoe Perches $line_fixed = 1; 42913705ce5bSJoe Perches } 42921f65f947SAndy Whitcroft } 42931f65f947SAndy Whitcroft 42940a920b5bSAndy Whitcroft # All the others need spaces both sides. 4295cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 42961f65f947SAndy Whitcroft my $ok = 0; 42971f65f947SAndy Whitcroft 429822f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 42991f65f947SAndy Whitcroft if (($op eq '<' && 43001f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 43011f65f947SAndy Whitcroft ($op eq '>' && 43021f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 43031f65f947SAndy Whitcroft { 43041f65f947SAndy Whitcroft $ok = 1; 43051f65f947SAndy Whitcroft } 43061f65f947SAndy Whitcroft 4307e0df7e1fSJoe Perches # for asm volatile statements 4308e0df7e1fSJoe Perches # ignore a colon with another 4309e0df7e1fSJoe Perches # colon immediately before or after 4310e0df7e1fSJoe Perches if (($op eq ':') && 4311e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4312e0df7e1fSJoe Perches $ok = 1; 4313e0df7e1fSJoe Perches } 4314e0df7e1fSJoe Perches 431584731623SJoe Perches # messages are ERROR, but ?: are CHK 43161f65f947SAndy Whitcroft if ($ok == 0) { 431784731623SJoe Perches my $msg_type = \&ERROR; 431884731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 431984731623SJoe Perches 432084731623SJoe Perches if (&{$msg_type}("SPACING", 43213705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4322b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4323b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4324b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4325b34c648bSJoe Perches } 43263705ce5bSJoe Perches $line_fixed = 1; 43273705ce5bSJoe Perches } 43280a920b5bSAndy Whitcroft } 432922f2a2efSAndy Whitcroft } 43304a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 43313705ce5bSJoe Perches 43323705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 43333705ce5bSJoe Perches 43343705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 43350a920b5bSAndy Whitcroft } 43363705ce5bSJoe Perches 43373705ce5bSJoe Perches if (($#elements % 2) == 0) { 43383705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 43393705ce5bSJoe Perches } 43403705ce5bSJoe Perches 4341194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4342194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 43433705ce5bSJoe Perches } 43443705ce5bSJoe Perches 43453705ce5bSJoe Perches 43460a920b5bSAndy Whitcroft } 43470a920b5bSAndy Whitcroft 4348786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4349d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4350786b6326SJoe Perches if (WARN("SPACING", 4351786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4352786b6326SJoe Perches $fix) { 4353194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4354786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4355786b6326SJoe Perches } 4356786b6326SJoe Perches } 4357786b6326SJoe Perches 4358f0a594c1SAndy Whitcroft# check for multiple assignments 4359f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4360000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4361000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4362f0a594c1SAndy Whitcroft } 4363f0a594c1SAndy Whitcroft 436422f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 436522f2a2efSAndy Whitcroft## # continuation. 436622f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 436722f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 436822f2a2efSAndy Whitcroft## 436922f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 437022f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 437122f2a2efSAndy Whitcroft## my $ln = $line; 437222f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 437322f2a2efSAndy Whitcroft## } 437422f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4375000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4376000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 437722f2a2efSAndy Whitcroft## } 437822f2a2efSAndy Whitcroft## } 4379f0a594c1SAndy Whitcroft 43800a920b5bSAndy Whitcroft#need space before brace following if, while, etc 43816b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 43824e5d56bdSEddie Kovsky $line =~ /do\{/) { 43833705ce5bSJoe Perches if (ERROR("SPACING", 43843705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 43853705ce5bSJoe Perches $fix) { 4386194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; 43873705ce5bSJoe Perches } 4388de7d4f0eSAndy Whitcroft } 4389de7d4f0eSAndy Whitcroft 4390c4a62ef9SJoe Perches## # check for blank lines before declarations 4391c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4392c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4393c4a62ef9SJoe Perches## WARN("SPACING", 4394c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4395c4a62ef9SJoe Perches## } 4396c4a62ef9SJoe Perches## 4397c4a62ef9SJoe Perches 4398de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4399de7d4f0eSAndy Whitcroft# on the line 4400de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 4401d5e616fcSJoe Perches if (ERROR("SPACING", 4402d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4403d5e616fcSJoe Perches $fix) { 4404194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4405d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4406d5e616fcSJoe Perches } 44070a920b5bSAndy Whitcroft } 44080a920b5bSAndy Whitcroft 440922f2a2efSAndy Whitcroft# check spacing on square brackets 441022f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 44113705ce5bSJoe Perches if (ERROR("SPACING", 44123705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 44133705ce5bSJoe Perches $fix) { 4414194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44153705ce5bSJoe Perches s/\[\s+/\[/; 44163705ce5bSJoe Perches } 441722f2a2efSAndy Whitcroft } 441822f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 44193705ce5bSJoe Perches if (ERROR("SPACING", 44203705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 44213705ce5bSJoe Perches $fix) { 4422194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44233705ce5bSJoe Perches s/\s+\]/\]/; 44243705ce5bSJoe Perches } 442522f2a2efSAndy Whitcroft } 442622f2a2efSAndy Whitcroft 4427c45dcabdSAndy Whitcroft# check spacing on parentheses 44289c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 44299c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 44303705ce5bSJoe Perches if (ERROR("SPACING", 44313705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 44323705ce5bSJoe Perches $fix) { 4433194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44343705ce5bSJoe Perches s/\(\s+/\(/; 44353705ce5bSJoe Perches } 443622f2a2efSAndy Whitcroft } 443713214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4438c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4439c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 44403705ce5bSJoe Perches if (ERROR("SPACING", 44413705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44423705ce5bSJoe Perches $fix) { 4443194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44443705ce5bSJoe Perches s/\s+\)/\)/; 44453705ce5bSJoe Perches } 444622f2a2efSAndy Whitcroft } 444722f2a2efSAndy Whitcroft 4448e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4449e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4450e2826fd0SJoe Perches 4451e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4452ea4acbb1SJoe Perches my $var = $1; 4453ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4454ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4455ea4acbb1SJoe Perches $fix) { 4456ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4457ea4acbb1SJoe Perches } 4458ea4acbb1SJoe Perches } 4459ea4acbb1SJoe Perches 4460ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4461ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4462ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4463ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4464ea4acbb1SJoe Perches my $var = $2; 4465ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4466ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4467ea4acbb1SJoe Perches $fix) { 4468ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4469ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4470ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4471ea4acbb1SJoe Perches } 4472e2826fd0SJoe Perches } 4473e2826fd0SJoe Perches 44740a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 44754a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 44760a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 44773705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 44783705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 44793705ce5bSJoe Perches $fix) { 4480194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44813705ce5bSJoe Perches s/^(.)\s+/$1/; 44823705ce5bSJoe Perches } 44830a920b5bSAndy Whitcroft } 44840a920b5bSAndy Whitcroft 44855b9553abSJoe Perches# return is not a function 4486507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4487c45dcabdSAndy Whitcroft my $spacing = $1; 4488507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 44895b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 44905b9553abSJoe Perches my $value = $1; 44915b9553abSJoe Perches $value = deparenthesize($value); 44925b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4493000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4494000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 44955b9553abSJoe Perches } 4496c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4497000d1cc1SJoe Perches ERROR("SPACING", 4498000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4499c45dcabdSAndy Whitcroft } 4500c45dcabdSAndy Whitcroft } 4501507e5141SJoe Perches 4502b43ae21bSJoe Perches# unnecessary return in a void function 4503b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4504b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4505b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4506b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4507b43ae21bSJoe Perches $linenr >= 3 && 4508b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4509b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 45109819cf25SJoe Perches WARN("RETURN_VOID", 4511b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 45129819cf25SJoe Perches } 45139819cf25SJoe Perches 4514189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4515189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4516189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4517189248d8SJoe Perches my $openparens = $1; 4518189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4519189248d8SJoe Perches my $msg = ""; 4520189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4521189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4522189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4523189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4524189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4525189248d8SJoe Perches } 4526189248d8SJoe Perches } 4527189248d8SJoe Perches 4528c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4529c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4530c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4531c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4532c5595fa2SJoe Perches if ($^V && $^V ge 5.10.0 && 4533c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4534c5595fa2SJoe Perches my $lead = $1; 4535c5595fa2SJoe Perches my $const = $2; 4536c5595fa2SJoe Perches my $comp = $3; 4537c5595fa2SJoe Perches my $to = $4; 4538c5595fa2SJoe Perches my $newcomp = $comp; 4539f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4540c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4541c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4542c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4543c5595fa2SJoe Perches $fix) { 4544c5595fa2SJoe Perches if ($comp eq "<") { 4545c5595fa2SJoe Perches $newcomp = ">"; 4546c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4547c5595fa2SJoe Perches $newcomp = ">="; 4548c5595fa2SJoe Perches } elsif ($comp eq ">") { 4549c5595fa2SJoe Perches $newcomp = "<"; 4550c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4551c5595fa2SJoe Perches $newcomp = "<="; 4552c5595fa2SJoe Perches } 4553c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4554c5595fa2SJoe Perches } 4555c5595fa2SJoe Perches } 4556c5595fa2SJoe Perches 4557f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4558f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 455953a3c448SAndy Whitcroft my $name = $1; 456053a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4561000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4562f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 456353a3c448SAndy Whitcroft } 456453a3c448SAndy Whitcroft } 4565c45dcabdSAndy Whitcroft 45660a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 45674a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 45683705ce5bSJoe Perches if (ERROR("SPACING", 45693705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 45703705ce5bSJoe Perches $fix) { 4571194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45723705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 45733705ce5bSJoe Perches } 45740a920b5bSAndy Whitcroft } 45750a920b5bSAndy Whitcroft 4576f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4577f5fe35ddSAndy Whitcroft# statements after the conditional. 4578170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 45793e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 45803e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 45813e469cdcSAndy Whitcroft if (!defined $stat); 4582170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4583170d3a22SAndy Whitcroft $remain_next, $off_next); 4584170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4585170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4586170d3a22SAndy Whitcroft 4587170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4588170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4589170d3a22SAndy Whitcroft # then count those as offsets. 4590170d3a22SAndy Whitcroft my ($whitespace) = 4591170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4592170d3a22SAndy Whitcroft my $offset = 4593170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4594170d3a22SAndy Whitcroft 4595170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4596170d3a22SAndy Whitcroft $offset} = 1; 4597170d3a22SAndy Whitcroft } 4598170d3a22SAndy Whitcroft } 4599170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4600c11230f4SJoe Perches defined($stat) && defined($cond) && 4601170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4602171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 46038905a67cSAndy Whitcroft 4604b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4605000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4606000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 46078905a67cSAndy Whitcroft } 46088905a67cSAndy Whitcroft 46098905a67cSAndy Whitcroft # Find out what is on the end of the line after the 46108905a67cSAndy Whitcroft # conditional. 4611773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 46128905a67cSAndy Whitcroft $s =~ s/\n.*//g; 461313214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 461453210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 461553210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4616773647a0SAndy Whitcroft { 4617bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4618bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4619bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 462042bdf74cSHidetoshi Seto my $stat_real = ''; 4621bb44ad39SAndy Whitcroft 462242bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 462342bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4624bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4625bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4626bb44ad39SAndy Whitcroft } 4627bb44ad39SAndy Whitcroft 4628000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4629000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 46308905a67cSAndy Whitcroft } 46318905a67cSAndy Whitcroft } 46328905a67cSAndy Whitcroft 463313214adfSAndy Whitcroft# Check for bitwise tests written as boolean 463413214adfSAndy Whitcroft if ($line =~ / 463513214adfSAndy Whitcroft (?: 463613214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 463713214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 463813214adfSAndy Whitcroft (?:\&\&|\|\|) 463913214adfSAndy Whitcroft | 464013214adfSAndy Whitcroft (?:\&\&|\|\|) 464113214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 464213214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 464313214adfSAndy Whitcroft )/x) 464413214adfSAndy Whitcroft { 4645000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4646000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 464713214adfSAndy Whitcroft } 464813214adfSAndy Whitcroft 46498905a67cSAndy Whitcroft# if and else should not have general statements after it 465013214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 465113214adfSAndy Whitcroft my $s = $1; 465213214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 465313214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4654000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4655000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 46560a920b5bSAndy Whitcroft } 465713214adfSAndy Whitcroft } 465839667782SAndy Whitcroft# if should not continue a brace 465939667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4660000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4661048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 466239667782SAndy Whitcroft $herecurr); 466339667782SAndy Whitcroft } 4664a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4665a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4666a1080bf8SAndy Whitcroft $line !~ /\G(?: 46673fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4668a1080bf8SAndy Whitcroft \s*return\s+ 4669a1080bf8SAndy Whitcroft )/xg) 4670a1080bf8SAndy Whitcroft { 4671000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4672000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4673a1080bf8SAndy Whitcroft } 46740a920b5bSAndy Whitcroft 46750a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 46760a920b5bSAndy Whitcroft # indent level to be relevant to each other. 46778b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 46780a920b5bSAndy Whitcroft $previndent == $indent) { 46798b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 46808b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 46818b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46828b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46838b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46848b8856f4SJoe Perches my $fixedline = $prevrawline; 46858b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 46868b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46878b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46888b8856f4SJoe Perches } 46898b8856f4SJoe Perches $fixedline = $rawline; 46908b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 46918b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46928b8856f4SJoe Perches } 46930a920b5bSAndy Whitcroft } 46940a920b5bSAndy Whitcroft 46958b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4696c2fdda0dSAndy Whitcroft $previndent == $indent) { 4697c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4698c2fdda0dSAndy Whitcroft 4699c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4700c2fdda0dSAndy Whitcroft # conditional. 4701773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4702c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4703c2fdda0dSAndy Whitcroft 4704c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 47058b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 47068b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 47078b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47088b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 47098b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 47108b8856f4SJoe Perches my $fixedline = $prevrawline; 47118b8856f4SJoe Perches my $trailing = $rawline; 47128b8856f4SJoe Perches $trailing =~ s/^\+//; 47138b8856f4SJoe Perches $trailing = trim($trailing); 47148b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 47158b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47168b8856f4SJoe Perches } 4717c2fdda0dSAndy Whitcroft } 4718c2fdda0dSAndy Whitcroft } 4719c2fdda0dSAndy Whitcroft 472095e2c602SJoe Perches#Specific variable tests 4721323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4722323c1260SJoe Perches my $var = $1; 472395e2c602SJoe Perches 472495e2c602SJoe Perches#gcc binary extension 472595e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4726d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4727d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4728d5e616fcSJoe Perches $fix) { 4729d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4730194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4731d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4732d5e616fcSJoe Perches } 473395e2c602SJoe Perches } 473495e2c602SJoe Perches 473595e2c602SJoe Perches#CamelCase 4736807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4737be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 473822735ce8SJoe Perches#Ignore Page<foo> variants 4739807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 474022735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4741f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4742f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4743f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47447e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 47457e781f67SJoe Perches my $word = $1; 47467e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4747d8b07710SJoe Perches if ($check) { 4748d8b07710SJoe Perches seed_camelcase_includes(); 4749d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4750d8b07710SJoe Perches seed_camelcase_file($realfile); 4751d8b07710SJoe Perches $camelcase_file_seeded = 1; 4752d8b07710SJoe Perches } 4753d8b07710SJoe Perches } 47547e781f67SJoe Perches if (!defined $camelcase{$word}) { 47557e781f67SJoe Perches $camelcase{$word} = 1; 4756be79794bSJoe Perches CHK("CAMELCASE", 47577e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 47587e781f67SJoe Perches } 4759323c1260SJoe Perches } 4760323c1260SJoe Perches } 47613445686aSJoe Perches } 47620a920b5bSAndy Whitcroft 47630a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4764d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4765d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4766d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4767d5e616fcSJoe Perches $fix) { 4768194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4769d5e616fcSJoe Perches } 47700a920b5bSAndy Whitcroft } 47710a920b5bSAndy Whitcroft 47720e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47730e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4774c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4775e09dec48SAndy Whitcroft my $file = "$1.h"; 4776e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4777e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4778e09dec48SAndy Whitcroft $realfile ne $checkfile && 47797840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4780c45dcabdSAndy Whitcroft { 47810e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 47820e212e0aSFabian Frederick if ($asminclude > 0) { 4783e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4784000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4785000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4786e09dec48SAndy Whitcroft } else { 4787000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4788000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4789e09dec48SAndy Whitcroft } 47900a920b5bSAndy Whitcroft } 47910a920b5bSAndy Whitcroft } 47920e212e0aSFabian Frederick } 47930a920b5bSAndy Whitcroft 4794653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4795653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4796cf655043SAndy Whitcroft# in a known good container 4797b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4798b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4799d8aaf121SAndy Whitcroft my $ln = $linenr; 4800d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4801c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4802c45dcabdSAndy Whitcroft my $ctx = ''; 480308a2843eSJoe Perches my $has_flow_statement = 0; 480408a2843eSJoe Perches my $has_arg_concat = 0; 4805c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4806f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4807f74bd194SAndy Whitcroft $ctx = $dstat; 4808c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4809a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4810c45dcabdSAndy Whitcroft 481108a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 481262e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 481308a2843eSJoe Perches 4814f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 4815f59b64bfSJoe Perches my $define_args = $1; 4816f59b64bfSJoe Perches my $define_stmt = $dstat; 4817f59b64bfSJoe Perches my @def_args = (); 4818f59b64bfSJoe Perches 4819f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 4820f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 4821f59b64bfSJoe Perches $define_args =~ s/\s*//g; 4822f59b64bfSJoe Perches @def_args = split(",", $define_args); 4823f59b64bfSJoe Perches } 4824f59b64bfSJoe Perches 4825292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4826c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4827c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4828c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4829c45dcabdSAndy Whitcroft 4830c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4831bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4832bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 48336b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 4834bf30d6edSAndy Whitcroft { 4835c45dcabdSAndy Whitcroft } 4836c45dcabdSAndy Whitcroft 4837e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 483833acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 483933acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 4840e45bab8eSAndy Whitcroft { 4841e45bab8eSAndy Whitcroft } 4842e45bab8eSAndy Whitcroft 484342e15293SJoe Perches # Make asm volatile uses seem like a generic function 484442e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 484542e15293SJoe Perches 4846c45dcabdSAndy Whitcroft my $exceptions = qr{ 4847c45dcabdSAndy Whitcroft $Declare| 4848c45dcabdSAndy Whitcroft module_param_named| 4849a0a0a7a9SKees Cook MODULE_PARM_DESC| 4850c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4851c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4852383099fdSAndy Whitcroft __typeof__\(| 485322fd2d3eSStefani Seibold union| 485422fd2d3eSStefani Seibold struct| 4855ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 48566b10df42SVladimir Zapolskiy ^\"|\"$| 48576b10df42SVladimir Zapolskiy ^\[ 4858c45dcabdSAndy Whitcroft }x; 48595eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4860f59b64bfSJoe Perches 4861f59b64bfSJoe Perches $ctx =~ s/\n*$//; 4862f59b64bfSJoe Perches my $herectx = $here . "\n"; 4863f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 4864f59b64bfSJoe Perches 4865f59b64bfSJoe Perches for (my $n = 0; $n < $stmt_cnt; $n++) { 4866f59b64bfSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4867f59b64bfSJoe Perches } 4868f59b64bfSJoe Perches 4869f74bd194SAndy Whitcroft if ($dstat ne '' && 4870f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4871f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48723cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4873356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4874f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4875f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4876e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 487772f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4878f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4879f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4880f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 48814e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 4882f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4883c45dcabdSAndy Whitcroft { 4884e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 4885e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4886e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 4887e795556aSJoe Perches } elsif ($dstat =~ /;/) { 4888f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4889f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4890f74bd194SAndy Whitcroft } else { 4891000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4892388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4893d8aaf121SAndy Whitcroft } 4894f59b64bfSJoe Perches 4895f59b64bfSJoe Perches } 48965207649bSJoe Perches 48975207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 48985207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 48995207649bSJoe Perches my $first = 1; 49005207649bSJoe Perches $define_stmt = ""; 49015207649bSJoe Perches foreach my $l (@stmt_array) { 49025207649bSJoe Perches $l =~ s/\\$//; 49035207649bSJoe Perches if ($first) { 49045207649bSJoe Perches $define_stmt = $l; 49055207649bSJoe Perches $first = 0; 49065207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 49075207649bSJoe Perches $define_stmt .= substr($l, 1); 49085207649bSJoe Perches } 49095207649bSJoe Perches } 49105207649bSJoe Perches $define_stmt =~ s/$;//g; 49115207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 49125207649bSJoe Perches $define_stmt = trim($define_stmt); 49135207649bSJoe Perches 4914f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 4915f59b64bfSJoe Perches foreach my $arg (@def_args) { 4916f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 49179192d41aSJoe Perches next if ($arg =~ /^type$/i); 4918f59b64bfSJoe Perches my $tmp = $define_stmt; 4919f59b64bfSJoe Perches $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49205207649bSJoe Perches $tmp =~ s/\#+\s*$arg\b//g; 4921f59b64bfSJoe Perches $tmp =~ s/\b$arg\s*\#\#//g; 4922f59b64bfSJoe Perches my $use_cnt = $tmp =~ s/\b$arg\b//g; 4923f59b64bfSJoe Perches if ($use_cnt > 1) { 4924f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 4925f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 4926f59b64bfSJoe Perches } 49279192d41aSJoe Perches# check if any macro arguments may have other precedence issues 49289192d41aSJoe Perches if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49299192d41aSJoe Perches ((defined($1) && $1 ne ',') || 49309192d41aSJoe Perches (defined($2) && $2 ne ','))) { 49319192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 49329192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49339192d41aSJoe Perches } 49340a920b5bSAndy Whitcroft } 49355023d347SJoe Perches 493608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 493708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 493808a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 493908a2843eSJoe Perches my $herectx = $here . "\n"; 494008a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 494108a2843eSJoe Perches 494208a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 494308a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 494408a2843eSJoe Perches } 494508a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 494608a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 494708a2843eSJoe Perches } 494808a2843eSJoe Perches 4949481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 49505023d347SJoe Perches 49515023d347SJoe Perches } else { 49525023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4953481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4954481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 49555023d347SJoe Perches $line =~ /^\+.*\\$/) { 49565023d347SJoe Perches WARN("LINE_CONTINUATIONS", 49575023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 49585023d347SJoe Perches } 4959653d4876SAndy Whitcroft } 49600a920b5bSAndy Whitcroft 4961b13edf7fSJoe Perches# do {} while (0) macro tests: 4962b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4963b13edf7fSJoe Perches# macro should not end with a semicolon 4964b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4965b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4966b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4967b13edf7fSJoe Perches my $ln = $linenr; 4968b13edf7fSJoe Perches my $cnt = $realcnt; 4969b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4970b13edf7fSJoe Perches my $ctx = ''; 4971b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4972b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4973b13edf7fSJoe Perches $ctx = $dstat; 4974b13edf7fSJoe Perches 4975b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 49761b36b201SJoe Perches $dstat =~ s/$;/ /g; 4977b13edf7fSJoe Perches 4978b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4979b13edf7fSJoe Perches my $stmts = $2; 4980b13edf7fSJoe Perches my $semis = $3; 4981b13edf7fSJoe Perches 4982b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4983b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4984b13edf7fSJoe Perches my $herectx = $here . "\n"; 4985b13edf7fSJoe Perches 4986b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4987b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4988b13edf7fSJoe Perches } 4989b13edf7fSJoe Perches 4990ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4991ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4992b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4993b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4994b13edf7fSJoe Perches } 4995b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4996b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4997b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 4998b13edf7fSJoe Perches } 4999f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5000f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5001f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5002f5ef95b1SJoe Perches my $herectx = $here . "\n"; 5003f5ef95b1SJoe Perches 5004f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 5005f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 5006f5ef95b1SJoe Perches } 5007f5ef95b1SJoe Perches 5008f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5009f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5010b13edf7fSJoe Perches } 5011b13edf7fSJoe Perches } 5012b13edf7fSJoe Perches 5013080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5014080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 5015080ba929SMike Frysinger# . 5016080ba929SMike Frysinger# ALIGN(...) 5017080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 5018080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5019000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 5020000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5021080ba929SMike Frysinger } 5022080ba929SMike Frysinger 5023f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 502413214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 502513214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5026cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 502713214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5028cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5029cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5030aad4f614SJoe Perches my @allowed = (); 5031aad4f614SJoe Perches my $allow = 0; 503213214adfSAndy Whitcroft my $seen = 0; 5033773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5034cf655043SAndy Whitcroft my $ln = $linenr - 1; 503513214adfSAndy Whitcroft for my $chunk (@chunks) { 503613214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 503713214adfSAndy Whitcroft 5038773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5039773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5040773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5041773647a0SAndy Whitcroft 5042aad4f614SJoe Perches $allowed[$allow] = 0; 5043773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5044773647a0SAndy Whitcroft 5045773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5046773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5047773647a0SAndy Whitcroft 5048773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5049cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5050cf655043SAndy Whitcroft 5051773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 505213214adfSAndy Whitcroft 505313214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 505413214adfSAndy Whitcroft 5055aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5056cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5057cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5058aad4f614SJoe Perches $allowed[$allow] = 1; 505913214adfSAndy Whitcroft } 506013214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5061cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5062aad4f614SJoe Perches $allowed[$allow] = 1; 506313214adfSAndy Whitcroft } 5064cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5065cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5066aad4f614SJoe Perches $allowed[$allow] = 1; 506713214adfSAndy Whitcroft } 5068aad4f614SJoe Perches $allow++; 506913214adfSAndy Whitcroft } 5070aad4f614SJoe Perches if ($seen) { 5071aad4f614SJoe Perches my $sum_allowed = 0; 5072aad4f614SJoe Perches foreach (@allowed) { 5073aad4f614SJoe Perches $sum_allowed += $_; 5074aad4f614SJoe Perches } 5075aad4f614SJoe Perches if ($sum_allowed == 0) { 5076000d1cc1SJoe Perches WARN("BRACES", 5077000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5078aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5079aad4f614SJoe Perches $seen != $allow) { 5080aad4f614SJoe Perches CHK("BRACES", 5081aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5082aad4f614SJoe Perches } 508313214adfSAndy Whitcroft } 508413214adfSAndy Whitcroft } 508513214adfSAndy Whitcroft } 5086773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 508713214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5088cf655043SAndy Whitcroft my $allowed = 0; 5089f0a594c1SAndy Whitcroft 5090cf655043SAndy Whitcroft # Check the pre-context. 5091cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5092cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5093cf655043SAndy Whitcroft $allowed = 1; 5094f0a594c1SAndy Whitcroft } 5095773647a0SAndy Whitcroft 5096773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5097773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5098773647a0SAndy Whitcroft 5099cf655043SAndy Whitcroft # Check the condition. 5100cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5101773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5102cf655043SAndy Whitcroft if (defined $cond) { 5103773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5104cf655043SAndy Whitcroft } 5105cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5106cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5107cf655043SAndy Whitcroft $allowed = 1; 5108cf655043SAndy Whitcroft } 5109cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5110cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5111cf655043SAndy Whitcroft $allowed = 1; 5112cf655043SAndy Whitcroft } 5113cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5114cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5115cf655043SAndy Whitcroft $allowed = 1; 5116cf655043SAndy Whitcroft } 5117cf655043SAndy Whitcroft # Check the post-context. 5118cf655043SAndy Whitcroft if (defined $chunks[1]) { 5119cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5120cf655043SAndy Whitcroft if (defined $cond) { 5121773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5122cf655043SAndy Whitcroft } 5123cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5124cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5125cf655043SAndy Whitcroft $allowed = 1; 5126cf655043SAndy Whitcroft } 5127cf655043SAndy Whitcroft } 5128cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 512969932487SJustin P. Mattock my $herectx = $here . "\n"; 5130f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5131cf655043SAndy Whitcroft 5132f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 513369932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 5134cf655043SAndy Whitcroft } 5135cf655043SAndy Whitcroft 5136000d1cc1SJoe Perches WARN("BRACES", 5137000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5138f0a594c1SAndy Whitcroft } 5139f0a594c1SAndy Whitcroft } 5140f0a594c1SAndy Whitcroft 5141e4c5babdSJoe Perches# check for single line unbalanced braces 514295330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 514395330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5144e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5145e4c5babdSJoe Perches } 5146e4c5babdSJoe Perches 51470979ae66SJoe Perches# check for unnecessary blank lines around braces 514877b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5149f8e58219SJoe Perches if (CHK("BRACES", 5150f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5151f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5152f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5153f8e58219SJoe Perches } 51540979ae66SJoe Perches } 515577b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5156f8e58219SJoe Perches if (CHK("BRACES", 5157f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5158f8e58219SJoe Perches $fix) { 5159f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5160f8e58219SJoe Perches } 51610979ae66SJoe Perches } 51620979ae66SJoe Perches 51634a0df2efSAndy Whitcroft# no volatiles please 51646c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 51656c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5166000d1cc1SJoe Perches WARN("VOLATILE", 51678c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51684a0df2efSAndy Whitcroft } 51694a0df2efSAndy Whitcroft 51705e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 51715e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 51725e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51735e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 517433acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 51755e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 51765e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 51775e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 51785e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 51795e4f6ba5SJoe Perches $fix && 51805e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 51815e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 51825e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 51835e4f6ba5SJoe Perches my $comma_close = ""; 51845e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 51855e4f6ba5SJoe Perches $comma_close = $1; 51865e4f6ba5SJoe Perches } 51875e4f6ba5SJoe Perches 51885e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51895e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 51905e4f6ba5SJoe Perches my $fixedline = $prevrawline; 51915e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 51925e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 51935e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 51945e4f6ba5SJoe Perches $fixedline = $rawline; 51955e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 51965e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 51975e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51985e4f6ba5SJoe Perches } 51995e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 52005e4f6ba5SJoe Perches } 52015e4f6ba5SJoe Perches } 52025e4f6ba5SJoe Perches 52035e4f6ba5SJoe Perches# check for missing a space in a string concatenation 52045e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 52055e4f6ba5SJoe Perches WARN('MISSING_SPACE', 52065e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 52075e4f6ba5SJoe Perches } 52085e4f6ba5SJoe Perches 520977cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5210e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5211e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5212e4b7d309SJoe Perches# function declarations 521377cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 521477cb8546SJoe Perches defined($context_function) && 5215e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5216e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 521777cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5218e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 521977cb8546SJoe Perches } 522077cb8546SJoe Perches 52215e4f6ba5SJoe Perches# check for spaces before a quoted newline 52225e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 52235e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52245e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52255e4f6ba5SJoe Perches $fix) { 52265e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52275e4f6ba5SJoe Perches } 52285e4f6ba5SJoe Perches 52295e4f6ba5SJoe Perches } 52305e4f6ba5SJoe Perches 5231f17dba4fSJoe Perches# concatenated string without spaces between elements 523233acb54aSJoe Perches if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5233f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 5234f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 5235f17dba4fSJoe Perches } 5236f17dba4fSJoe Perches 523790ad30e5SJoe Perches# uncoalesced string fragments 523833acb54aSJoe Perches if ($line =~ /$String\s*"/) { 523990ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 524090ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 524190ad30e5SJoe Perches } 524290ad30e5SJoe Perches 5243522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5244522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5245522b837cSAlexey Dobriyan my $show_Z = 1; 52465e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5247522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52485e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5249522b837cSAlexey Dobriyan # check for %L 5250522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52515e4f6ba5SJoe Perches WARN("PRINTF_L", 5252522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5253522b837cSAlexey Dobriyan $show_L = 0; 52545e4f6ba5SJoe Perches } 5255522b837cSAlexey Dobriyan # check for %Z 5256522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5257522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5258522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5259522b837cSAlexey Dobriyan $show_Z = 0; 5260522b837cSAlexey Dobriyan } 5261522b837cSAlexey Dobriyan # check for 0x<decimal> 5262522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5263522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 52646e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 52656e300757SJoe Perches } 52665e4f6ba5SJoe Perches } 52675e4f6ba5SJoe Perches 52685e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 52695e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52705e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 52715e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 52725e4f6ba5SJoe Perches } 52735e4f6ba5SJoe Perches 527400df344fSAndy Whitcroft# warn about #if 0 5275c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5276000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 5277000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 5278de7d4f0eSAndy Whitcroft $herecurr); 52794a0df2efSAndy Whitcroft } 52804a0df2efSAndy Whitcroft 528103df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 528203df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5283100425deSJoe Perches my $tested = quotemeta($1); 5284100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5285100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5286100425deSJoe Perches my $func = $1; 5287100425deSJoe Perches if (WARN('NEEDLESS_IF', 5288100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5289100425deSJoe Perches $fix) { 5290100425deSJoe Perches my $do_fix = 1; 5291100425deSJoe Perches my $leading_tabs = ""; 5292100425deSJoe Perches my $new_leading_tabs = ""; 5293100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5294100425deSJoe Perches $leading_tabs = $1; 5295100425deSJoe Perches } else { 5296100425deSJoe Perches $do_fix = 0; 5297100425deSJoe Perches } 5298100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5299100425deSJoe Perches $new_leading_tabs = $1; 5300100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5301100425deSJoe Perches $do_fix = 0; 5302100425deSJoe Perches } 5303100425deSJoe Perches } else { 5304100425deSJoe Perches $do_fix = 0; 5305100425deSJoe Perches } 5306100425deSJoe Perches if ($do_fix) { 5307100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5308100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5309100425deSJoe Perches } 5310100425deSJoe Perches } 53114c432a8fSGreg Kroah-Hartman } 53124c432a8fSGreg Kroah-Hartman } 5313f0a594c1SAndy Whitcroft 5314ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5315ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5316ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5317ebfdc409SJoe Perches (defined $1 || defined $3) && 5318ebfdc409SJoe Perches $linenr > 3) { 5319ebfdc409SJoe Perches my $testval = $2; 5320ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5321ebfdc409SJoe Perches 5322ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5323ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5324ebfdc409SJoe Perches 5325fb0d0e08SJoe Perches if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { 5326ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5327ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5328ebfdc409SJoe Perches } 5329ebfdc409SJoe Perches } 5330ebfdc409SJoe Perches 5331f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5332dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5333f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5334f78d98f6SJoe Perches my $level = $1; 5335f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5336f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5337f78d98f6SJoe Perches $fix) { 5338f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5339f78d98f6SJoe Perches } 5340f78d98f6SJoe Perches } 5341f78d98f6SJoe Perches 534245c55e92SJoe Perches# check for logging continuations 534345c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 534445c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 534545c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 534645c55e92SJoe Perches } 534745c55e92SJoe Perches 5348abb08a53SJoe Perches# check for mask then right shift without a parentheses 5349abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 5350abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5351abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5352abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5353abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5354abb08a53SJoe Perches } 5355abb08a53SJoe Perches 5356b75ac618SJoe Perches# check for pointer comparisons to NULL 5357b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 5358b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5359b75ac618SJoe Perches my $val = $1; 5360b75ac618SJoe Perches my $equal = "!"; 5361b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5362b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5363b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5364b75ac618SJoe Perches $fix) { 5365b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5366b75ac618SJoe Perches } 5367b75ac618SJoe Perches } 5368b75ac618SJoe Perches } 5369b75ac618SJoe Perches 53708716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 53718716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 53728716de38SJoe Perches my $attr = $1; 53738716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 53748716de38SJoe Perches my $ptr = $1; 53758716de38SJoe Perches my $var = $2; 53768716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 53778716de38SJoe Perches ERROR("MISPLACED_INIT", 53788716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 53798716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 53808716de38SJoe Perches WARN("MISPLACED_INIT", 53818716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 53828716de38SJoe Perches $fix) { 5383194f66fcSJoe 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; 53848716de38SJoe Perches } 53858716de38SJoe Perches } 53868716de38SJoe Perches } 53878716de38SJoe Perches 5388e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5389e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5390e970b884SJoe Perches my $attr = $1; 5391e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5392e970b884SJoe Perches my $attr_prefix = $1; 5393e970b884SJoe Perches my $attr_type = $2; 5394e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5395e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5396e970b884SJoe Perches $fix) { 5397194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5398e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5399e970b884SJoe Perches } 5400e970b884SJoe Perches } 5401e970b884SJoe Perches 5402e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5403e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5404e970b884SJoe Perches my $attr = $1; 5405e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5406e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5407e970b884SJoe Perches $fix) { 5408194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5409e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5410e970b884SJoe Perches $lead = rtrim($1); 5411e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5412e970b884SJoe Perches $lead = "${lead}const "; 5413194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5414e970b884SJoe Perches } 5415e970b884SJoe Perches } 5416e970b884SJoe Perches 5417c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5418c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5419c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5420c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5421c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5422c17893c7SJoe Perches $fix) { 5423c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5424c17893c7SJoe Perches } 5425c17893c7SJoe Perches } 5426c17893c7SJoe Perches 5427fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5428fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5429fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5430fbdb8138SJoe Perches my $constant_func = $1; 5431fbdb8138SJoe Perches my $func = $constant_func; 5432fbdb8138SJoe Perches $func =~ s/^__constant_//; 5433fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5434fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5435fbdb8138SJoe Perches $fix) { 5436194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5437fbdb8138SJoe Perches } 5438fbdb8138SJoe Perches } 5439fbdb8138SJoe Perches 54401a15a250SPatrick Pannuto# prefer usleep_range over udelay 544137581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 544243c1d77cSJoe Perches my $delay = $1; 54431a15a250SPatrick Pannuto # ignore udelay's < 10, however 544443c1d77cSJoe Perches if (! ($delay < 10) ) { 5445000d1cc1SJoe Perches CHK("USLEEP_RANGE", 544643c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 544743c1d77cSJoe Perches } 544843c1d77cSJoe Perches if ($delay > 2000) { 544943c1d77cSJoe Perches WARN("LONG_UDELAY", 545043c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 54511a15a250SPatrick Pannuto } 54521a15a250SPatrick Pannuto } 54531a15a250SPatrick Pannuto 545409ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 545509ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 545609ef8725SPatrick Pannuto if ($1 < 20) { 5457000d1cc1SJoe Perches WARN("MSLEEP", 545843c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 545909ef8725SPatrick Pannuto } 546009ef8725SPatrick Pannuto } 546109ef8725SPatrick Pannuto 546236ec1939SJoe Perches# check for comparisons of jiffies 546336ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 546436ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 546536ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 546636ec1939SJoe Perches } 546736ec1939SJoe Perches 54689d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 54699d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54709d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 54719d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54729d7a34a5SJoe Perches } 54739d7a34a5SJoe Perches 547400df344fSAndy Whitcroft# warn about #ifdefs in C files 5475c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 547600df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 547700df344fSAndy Whitcroft# print "$herecurr"; 547800df344fSAndy Whitcroft# $clean = 0; 547900df344fSAndy Whitcroft# } 548000df344fSAndy Whitcroft 548122f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5482c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 54833705ce5bSJoe Perches if (ERROR("SPACING", 54843705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 54853705ce5bSJoe Perches $fix) { 5486194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54873705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 54883705ce5bSJoe Perches } 54893705ce5bSJoe Perches 549022f2a2efSAndy Whitcroft } 549122f2a2efSAndy Whitcroft 54924a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5493171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5494171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 54954a0df2efSAndy Whitcroft my $which = $1; 54964a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5497000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5498000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 54994a0df2efSAndy Whitcroft } 55004a0df2efSAndy Whitcroft } 55014a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5502402c2553SMichael S. Tsirkin 5503402c2553SMichael S. Tsirkin my $barriers = qr{ 5504402c2553SMichael S. Tsirkin mb| 5505402c2553SMichael S. Tsirkin rmb| 5506402c2553SMichael S. Tsirkin wmb| 5507402c2553SMichael S. Tsirkin read_barrier_depends 5508402c2553SMichael S. Tsirkin }x; 5509402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5510402c2553SMichael S. Tsirkin mb__before_atomic| 5511402c2553SMichael S. Tsirkin mb__after_atomic| 5512402c2553SMichael S. Tsirkin store_release| 5513402c2553SMichael S. Tsirkin load_acquire| 5514402c2553SMichael S. Tsirkin store_mb| 5515402c2553SMichael S. Tsirkin (?:$barriers) 5516402c2553SMichael S. Tsirkin }x; 5517402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5518402c2553SMichael S. Tsirkin (?:$barriers)| 551943e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 552043e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5521402c2553SMichael S. Tsirkin }x; 5522402c2553SMichael S. Tsirkin 5523402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 55244a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5525c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5526000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 55274a0df2efSAndy Whitcroft } 55284a0df2efSAndy Whitcroft } 55293ad81779SPaul E. McKenney 5530f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5531f4073b0fSMichael S. Tsirkin 5532f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5533f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5534f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5535f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5536f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5537f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5538f4073b0fSMichael S. Tsirkin } 5539f4073b0fSMichael S. Tsirkin 5540cb426e99SJoe Perches# check for waitqueue_active without a comment. 5541cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5542cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5543cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5544cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5545cb426e99SJoe Perches } 5546cb426e99SJoe Perches } 55473ad81779SPaul E. McKenney 55484a0df2efSAndy Whitcroft# check of hardware specific defines 5549c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5550000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5551000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 55520a920b5bSAndy Whitcroft } 5553653d4876SAndy Whitcroft 5554d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 5555d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 5556000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5557000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 5558d4977c78STobias Klauser } 5559d4977c78STobias Klauser 5560de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5561de7d4f0eSAndy Whitcroft# storage class and type. 55629c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 55639c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5564000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5565000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5566de7d4f0eSAndy Whitcroft } 5567de7d4f0eSAndy Whitcroft 55688905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 55692b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55702b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5571d5e616fcSJoe Perches if (WARN("INLINE", 5572d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5573d5e616fcSJoe Perches $fix) { 5574194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5575d5e616fcSJoe Perches 5576d5e616fcSJoe Perches } 55778905a67cSAndy Whitcroft } 55788905a67cSAndy Whitcroft 55793d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 55802b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55812b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5582000d1cc1SJoe Perches WARN("PREFER_PACKED", 5583000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 55843d130fd0SJoe Perches } 55853d130fd0SJoe Perches 558639b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 55872b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55882b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5589000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5590000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 559139b7e287SJoe Perches } 559239b7e287SJoe Perches 55935f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 55942b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55952b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5596d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5597d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5598d5e616fcSJoe Perches $fix) { 5599194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5600d5e616fcSJoe Perches 5601d5e616fcSJoe Perches } 56025f14d3bdSJoe Perches } 56035f14d3bdSJoe Perches 56046061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 56052b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 56062b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5607d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5608d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5609d5e616fcSJoe Perches $fix) { 5610194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5611d5e616fcSJoe Perches } 56126061d949SJoe Perches } 56136061d949SJoe Perches 5614619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 5615619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 5616619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5617619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5618619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5619619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5620619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5621619a908aSJoe Perches } 5622619a908aSJoe Perches 5623fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5624e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5625fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5626e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5627e6176fa4SJoe Perches my $type = $1; 5628e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5629e6176fa4SJoe Perches $type = $1; 5630e6176fa4SJoe Perches my $kernel_type = 'u'; 5631e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5632e6176fa4SJoe Perches $type =~ /(\d+)/; 5633e6176fa4SJoe Perches $kernel_type .= $1; 5634e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5635e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5636e6176fa4SJoe Perches $fix) { 5637e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5638e6176fa4SJoe Perches } 5639e6176fa4SJoe Perches } 5640e6176fa4SJoe Perches } 5641e6176fa4SJoe Perches 5642938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5643938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5644938224b5SJoe Perches my $cast = $1; 5645938224b5SJoe Perches my $const = $2; 5646938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5647938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5648938224b5SJoe Perches $fix) { 5649938224b5SJoe Perches my $suffix = ""; 5650938224b5SJoe Perches my $newconst = $const; 5651938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5652938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5653938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5654938224b5SJoe Perches $suffix .= 'LL'; 5655938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5656938224b5SJoe Perches $suffix .= 'L'; 5657938224b5SJoe Perches } 5658938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5659938224b5SJoe Perches } 5660938224b5SJoe Perches } 5661938224b5SJoe Perches 56628f53a9b8SJoe Perches# check for sizeof(&) 56638f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5664000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5665000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 56668f53a9b8SJoe Perches } 56678f53a9b8SJoe Perches 566866c80b60SJoe Perches# check for sizeof without parenthesis 566966c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5670d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5671d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5672d5e616fcSJoe Perches $fix) { 5673194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5674d5e616fcSJoe Perches } 567566c80b60SJoe Perches } 567666c80b60SJoe Perches 567788982feaSJoe Perches# check for struct spinlock declarations 567888982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 567988982feaSJoe Perches WARN("USE_SPINLOCK_T", 568088982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 568188982feaSJoe Perches } 568288982feaSJoe Perches 5683a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 568406668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5685a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5686caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5687caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5688d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5689d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5690d5e616fcSJoe Perches $fix) { 5691194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5692d5e616fcSJoe Perches } 5693a6962d72SJoe Perches } 5694a6962d72SJoe Perches } 5695a6962d72SJoe Perches 56960b523769SJoe Perches # check for vsprintf extension %p<foo> misuses 56970b523769SJoe Perches if ($^V && $^V ge 5.10.0 && 56980b523769SJoe Perches defined $stat && 56990b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 57000b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 57010b523769SJoe Perches my $bad_extension = ""; 57020b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 57030b523769SJoe Perches $lc = $lc + $linenr; 57040b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 57050b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 57060b523769SJoe Perches $fmt =~ s/%%//g; 5707ce4fecf1SPantelis Antoniou if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 57080b523769SJoe Perches $bad_extension = $1; 57090b523769SJoe Perches last; 57100b523769SJoe Perches } 57110b523769SJoe Perches } 57120b523769SJoe Perches if ($bad_extension ne "") { 57130b523769SJoe Perches my $stat_real = raw_line($linenr, 0); 57140b523769SJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 57150b523769SJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 57160b523769SJoe Perches } 57170b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 57180b523769SJoe Perches "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57190b523769SJoe Perches } 57200b523769SJoe Perches } 57210b523769SJoe Perches 5722554e165cSAndy Whitcroft# Check for misused memsets 5723d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5724d1fe9c09SJoe Perches defined $stat && 57259e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5726554e165cSAndy Whitcroft 5727d7c76ba7SJoe Perches my $ms_addr = $2; 5728d1fe9c09SJoe Perches my $ms_val = $7; 5729d1fe9c09SJoe Perches my $ms_size = $12; 5730d7c76ba7SJoe Perches 5731554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5732554e165cSAndy Whitcroft ERROR("MEMSET", 5733d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5734554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5735554e165cSAndy Whitcroft WARN("MEMSET", 5736d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5737d7c76ba7SJoe Perches } 5738d7c76ba7SJoe Perches } 5739d7c76ba7SJoe Perches 574098a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5741f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5742f333195dSJoe Perches# defined $stat && 5743f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5744f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 5745f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 5746f333195dSJoe Perches# $fix) { 5747f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 5748f333195dSJoe Perches# } 5749f333195dSJoe Perches# } 575098a9bba5SJoe Perches 5751b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5752f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5753f333195dSJoe Perches# defined $stat && 5754f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5755f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 5756f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 5757f333195dSJoe Perches# } 5758b6117d17SMateusz Kulikowski 57598617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 57608617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5761f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5762f333195dSJoe Perches# defined $stat && 5763f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5764f333195dSJoe Perches# 5765f333195dSJoe Perches# my $ms_val = $7; 5766f333195dSJoe Perches# 5767f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 5768f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 5769f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 5770f333195dSJoe Perches# $fix) { 5771f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 5772f333195dSJoe Perches# } 5773f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 5774f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 5775f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 5776f333195dSJoe Perches# $fix) { 5777f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 5778f333195dSJoe Perches# } 5779f333195dSJoe Perches# } 5780f333195dSJoe Perches# } 57818617cd09SMateusz Kulikowski 5782d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5783d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5784d1fe9c09SJoe Perches defined $stat && 5785d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5786d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5787d7c76ba7SJoe Perches my $call = $1; 5788d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5789d7c76ba7SJoe Perches my $arg1 = $3; 5790d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5791d1fe9c09SJoe Perches my $arg2 = $8; 5792d7c76ba7SJoe Perches my $cast; 5793d7c76ba7SJoe Perches 5794d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5795d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5796d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5797d7c76ba7SJoe Perches $cast = $cast1; 5798d7c76ba7SJoe Perches } else { 5799d7c76ba7SJoe Perches $cast = $cast2; 5800d7c76ba7SJoe Perches } 5801d7c76ba7SJoe Perches WARN("MINMAX", 5802d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5803554e165cSAndy Whitcroft } 5804554e165cSAndy Whitcroft } 5805554e165cSAndy Whitcroft 58064a273195SJoe Perches# check usleep_range arguments 58074a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 58084a273195SJoe Perches defined $stat && 58094a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 58104a273195SJoe Perches my $min = $1; 58114a273195SJoe Perches my $max = $7; 58124a273195SJoe Perches if ($min eq $max) { 58134a273195SJoe Perches WARN("USLEEP_RANGE", 58144a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58154a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 58164a273195SJoe Perches $min > $max) { 58174a273195SJoe Perches WARN("USLEEP_RANGE", 58184a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58194a273195SJoe Perches } 58204a273195SJoe Perches } 58214a273195SJoe Perches 5822823b794cSJoe Perches# check for naked sscanf 5823823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5824823b794cSJoe Perches defined $stat && 58256c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5826823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5827823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5828823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5829823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5830823b794cSJoe Perches $lc = $lc + $linenr; 5831823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5832823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5833823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5834823b794cSJoe Perches } 5835823b794cSJoe Perches WARN("NAKED_SSCANF", 5836823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5837823b794cSJoe Perches } 5838823b794cSJoe Perches 5839afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5840afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5841afc819abSJoe Perches defined $stat && 5842afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5843afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5844afc819abSJoe Perches $lc = $lc + $linenr; 5845afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5846afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5847afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5848afc819abSJoe Perches } 5849afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5850afc819abSJoe Perches my $format = $6; 5851afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5852afc819abSJoe Perches if ($count == 1 && 5853afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5854afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5855afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5856afc819abSJoe Perches } 5857afc819abSJoe Perches } 5858afc819abSJoe Perches } 5859afc819abSJoe Perches 586070dc8a48SJoe Perches# check for new externs in .h files. 586170dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 586270dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5863d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 586470dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 586570dc8a48SJoe Perches $fix) { 5866194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 586770dc8a48SJoe Perches } 586870dc8a48SJoe Perches } 586970dc8a48SJoe Perches 5870de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5871171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5872c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5873171ae1a4SAndy Whitcroft { 5874c45dcabdSAndy Whitcroft my $function_name = $1; 5875c45dcabdSAndy Whitcroft my $paren_space = $2; 5876171ae1a4SAndy Whitcroft 5877171ae1a4SAndy Whitcroft my $s = $stat; 5878171ae1a4SAndy Whitcroft if (defined $cond) { 5879171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5880171ae1a4SAndy Whitcroft } 5881c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5882c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5883c45dcabdSAndy Whitcroft { 5884000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5885000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5886de7d4f0eSAndy Whitcroft } 5887de7d4f0eSAndy Whitcroft 5888171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5889000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5890000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5891171ae1a4SAndy Whitcroft } 58929c9ba34eSAndy Whitcroft 58939c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 58949c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 58959c9ba34eSAndy Whitcroft { 5896000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5897000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5898171ae1a4SAndy Whitcroft } 5899171ae1a4SAndy Whitcroft 5900ca0d8929SJoe Perches if ($realfile =~ /\.[ch]$/ && defined $stat && 5901ca0d8929SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 5902ca0d8929SJoe Perches $1 ne "void") { 5903ca0d8929SJoe Perches my $args = trim($1); 5904ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 5905ca0d8929SJoe Perches my $arg = trim($1); 5906ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 5907ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 5908ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 5909ca0d8929SJoe Perches } 5910ca0d8929SJoe Perches } 5911ca0d8929SJoe Perches } 5912ca0d8929SJoe Perches 5913de7d4f0eSAndy Whitcroft# checks for new __setup's 5914de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5915de7d4f0eSAndy Whitcroft my $name = $1; 5916de7d4f0eSAndy Whitcroft 5917de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5918000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 59198c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5920de7d4f0eSAndy Whitcroft } 5921653d4876SAndy Whitcroft } 59229c0ca6f9SAndy Whitcroft 59239c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5924caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5925000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5926000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 59279c0ca6f9SAndy Whitcroft } 592813214adfSAndy Whitcroft 5929a640d25cSJoe Perches# alloc style 5930a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5931a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5932a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5933a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5934a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5935a640d25cSJoe Perches } 5936a640d25cSJoe Perches 593760a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 593860a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 59391b4a2ed4SJoe Perches defined $stat && 59401b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 594160a55369SJoe Perches my $oldfunc = $3; 594260a55369SJoe Perches my $a1 = $4; 594360a55369SJoe Perches my $a2 = $10; 594460a55369SJoe Perches my $newfunc = "kmalloc_array"; 594560a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 594660a55369SJoe Perches my $r1 = $a1; 594760a55369SJoe Perches my $r2 = $a2; 594860a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 594960a55369SJoe Perches $r1 = $a2; 595060a55369SJoe Perches $r2 = $a1; 595160a55369SJoe Perches } 5952e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5953e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 59541b4a2ed4SJoe Perches my $ctx = ''; 59551b4a2ed4SJoe Perches my $herectx = $here . "\n"; 59561b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 59571b4a2ed4SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 59581b4a2ed4SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 59591b4a2ed4SJoe Perches } 5960e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 59611b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 59621b4a2ed4SJoe Perches $cnt == 1 && 5963e367455aSJoe Perches $fix) { 5964194f66fcSJoe 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; 596560a55369SJoe Perches } 596660a55369SJoe Perches } 596760a55369SJoe Perches } 596860a55369SJoe Perches 5969972fdea2SJoe Perches# check for krealloc arg reuse 5970972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5971972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5972972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5973972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 5974972fdea2SJoe Perches } 5975972fdea2SJoe Perches 59765ce59ae0SJoe Perches# check for alloc argument mismatch 59775ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 59785ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 59795ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 59805ce59ae0SJoe Perches } 59815ce59ae0SJoe Perches 5982caf2a54fSJoe Perches# check for multiple semicolons 5983caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 5984d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 5985d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 5986d5e616fcSJoe Perches $fix) { 5987194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 5988d5e616fcSJoe Perches } 5989d1e2ad07SJoe Perches } 5990d1e2ad07SJoe Perches 5991cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 5992cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 5993cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 59940ab90191SJoe Perches my $ull = ""; 59950ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 59960ab90191SJoe Perches if (CHK("BIT_MACRO", 59970ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 59980ab90191SJoe Perches $fix) { 59990ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 60000ab90191SJoe Perches } 60010ab90191SJoe Perches } 60020ab90191SJoe Perches 60032d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 60042d632745SJoe 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*$/) { 60052d632745SJoe Perches my $config = $1; 60062d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 60072d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 60082d632745SJoe Perches $fix) { 60092d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 60102d632745SJoe Perches } 60112d632745SJoe Perches } 60122d632745SJoe Perches 6013e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6014c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6015c34c09a8SJoe Perches my $has_break = 0; 6016c34c09a8SJoe Perches my $has_statement = 0; 6017c34c09a8SJoe Perches my $count = 0; 6018c34c09a8SJoe Perches my $prevline = $linenr; 6019e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6020c34c09a8SJoe Perches $prevline--; 6021c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6022c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6023c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6024c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6025c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6026c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6027c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6028c34c09a8SJoe Perches $has_statement = 1; 6029c34c09a8SJoe Perches $count++; 6030c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 6031c34c09a8SJoe Perches } 6032c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6033c34c09a8SJoe Perches WARN("MISSING_BREAK", 6034224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6035c34c09a8SJoe Perches } 6036c34c09a8SJoe Perches } 6037c34c09a8SJoe Perches 6038d1e2ad07SJoe Perches# check for switch/default statements without a break; 6039d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 6040d1e2ad07SJoe Perches defined $stat && 6041d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6042d1e2ad07SJoe Perches my $ctx = ''; 6043d1e2ad07SJoe Perches my $herectx = $here . "\n"; 6044d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6045d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6046d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 6047d1e2ad07SJoe Perches } 6048d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6049d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6050caf2a54fSJoe Perches } 6051caf2a54fSJoe Perches 605213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6053d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6054d5e616fcSJoe Perches if (WARN("USE_FUNC", 6055d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6056d5e616fcSJoe Perches $fix) { 6057194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6058d5e616fcSJoe Perches } 605913214adfSAndy Whitcroft } 6060773647a0SAndy Whitcroft 606162ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 606262ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 606362ec818fSJoe Perches ERROR("DATE_TIME", 606462ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 606562ec818fSJoe Perches } 606662ec818fSJoe Perches 60672c92488aSJoe Perches# check for use of yield() 60682c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 60692c92488aSJoe Perches WARN("YIELD", 60702c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 60712c92488aSJoe Perches } 60722c92488aSJoe Perches 6073179f8f40SJoe Perches# check for comparisons against true and false 6074179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6075179f8f40SJoe Perches my $lead = $1; 6076179f8f40SJoe Perches my $arg = $2; 6077179f8f40SJoe Perches my $test = $3; 6078179f8f40SJoe Perches my $otype = $4; 6079179f8f40SJoe Perches my $trail = $5; 6080179f8f40SJoe Perches my $op = "!"; 6081179f8f40SJoe Perches 6082179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6083179f8f40SJoe Perches 6084179f8f40SJoe Perches my $type = lc($otype); 6085179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6086179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6087179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6088179f8f40SJoe Perches $op = ""; 6089179f8f40SJoe Perches } 6090179f8f40SJoe Perches 6091179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6092179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6093179f8f40SJoe Perches 6094179f8f40SJoe Perches## maybe suggesting a correct construct would better 6095179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6096179f8f40SJoe Perches 6097179f8f40SJoe Perches } 6098179f8f40SJoe Perches } 6099179f8f40SJoe Perches 61004882720bSThomas Gleixner# check for semaphores initialized locked 61014882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6102000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6103000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6104773647a0SAndy Whitcroft } 61056712d858SJoe Perches 610667d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 610767d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6108000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 610967d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6110773647a0SAndy Whitcroft } 61116712d858SJoe Perches 6112ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6113f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6114000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6115ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6116f3db6639SMichael Ellerman } 61176712d858SJoe Perches 61180f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6119d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 61206903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6121d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6122000d1cc1SJoe Perches WARN("CONST_STRUCT", 6123d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 61242b6db5cbSAndy Whitcroft } 6125773647a0SAndy Whitcroft 6126773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6127773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6128773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6129c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6130c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6131171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6132171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6133171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6134773647a0SAndy Whitcroft { 6135000d1cc1SJoe Perches WARN("NR_CPUS", 6136000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6137773647a0SAndy Whitcroft } 61389c9ba34eSAndy Whitcroft 613952ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 614052ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 614152ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 614252ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 614352ea8506SJoe Perches } 614452ea8506SJoe Perches 6145acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6146acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 6147acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6148acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6149acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6150acd9362cSJoe Perches } 6151acd9362cSJoe Perches 6152691d77b6SAndy Whitcroft# whine mightly about in_atomic 6153691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6154691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6155000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6156000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6157f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6158000d1cc1SJoe Perches WARN("IN_ATOMIC", 6159000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6160691d77b6SAndy Whitcroft } 6161691d77b6SAndy Whitcroft } 61621704f47bSPeter Zijlstra 6163481aea5cSJoe Perches# whine about ACCESS_ONCE 6164481aea5cSJoe Perches if ($^V && $^V ge 5.10.0 && 6165481aea5cSJoe Perches $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 6166481aea5cSJoe Perches my $par = $1; 6167481aea5cSJoe Perches my $eq = $2; 6168481aea5cSJoe Perches my $fun = $3; 6169481aea5cSJoe Perches $par =~ s/^\(\s*(.*)\s*\)$/$1/; 6170481aea5cSJoe Perches if (defined($eq)) { 6171481aea5cSJoe Perches if (WARN("PREFER_WRITE_ONCE", 6172481aea5cSJoe Perches "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 6173481aea5cSJoe Perches $fix) { 6174481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 6175481aea5cSJoe Perches } 6176481aea5cSJoe Perches } else { 6177481aea5cSJoe Perches if (WARN("PREFER_READ_ONCE", 6178481aea5cSJoe Perches "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 6179481aea5cSJoe Perches $fix) { 6180481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 6181481aea5cSJoe Perches } 6182481aea5cSJoe Perches } 6183481aea5cSJoe Perches } 6184481aea5cSJoe Perches 61850f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 61860f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 61870f5225b0SPeter Zijlstra ERROR("LOCKING", 61880f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 61890f5225b0SPeter Zijlstra } 61900f5225b0SPeter Zijlstra 61911704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 61921704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 61931704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 61941704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 61951704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 61961704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6197000d1cc1SJoe Perches ERROR("LOCKDEP", 6198000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 61991704f47bSPeter Zijlstra } 62001704f47bSPeter Zijlstra } 620188f8831cSDave Jones 6202b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6203b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6204000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6205000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 620688f8831cSDave Jones } 62072435880fSJoe Perches 6208515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6209515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 6210515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 6211459cf0aeSJoe Perches defined $stat && 6212515a235eSJoe Perches $line =~ /$mode_perms_search/) { 62132435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 62142435880fSJoe Perches my $func = $entry->[0]; 62152435880fSJoe Perches my $arg_pos = $entry->[1]; 62162435880fSJoe Perches 6217459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6218459cf0aeSJoe Perches $lc = $lc + $linenr; 6219459cf0aeSJoe Perches my $stat_real = raw_line($linenr, 0); 6220459cf0aeSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 6221459cf0aeSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 6222459cf0aeSJoe Perches } 6223459cf0aeSJoe Perches 62242435880fSJoe Perches my $skip_args = ""; 62252435880fSJoe Perches if ($arg_pos > 1) { 62262435880fSJoe Perches $arg_pos--; 62272435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62282435880fSJoe Perches } 6229f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6230459cf0aeSJoe Perches if ($stat =~ /$test/) { 62312435880fSJoe Perches my $val = $1; 62322435880fSJoe Perches $val = $6 if ($skip_args ne ""); 6233f90774e1SJoe Perches if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 6234f90774e1SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4)) { 62352435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6236459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6237f90774e1SJoe Perches } 6238f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6239c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6240459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 62412435880fSJoe Perches } 6242459cf0aeSJoe Perches } 6243459cf0aeSJoe Perches } 6244459cf0aeSJoe Perches } 6245459cf0aeSJoe Perches 6246459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6247459cf0aeSJoe Perches if ($line =~ /\b$mode_perms_string_search\b/) { 6248459cf0aeSJoe Perches my $val = ""; 6249459cf0aeSJoe Perches my $oval = ""; 6250f90774e1SJoe Perches my $to = 0; 6251459cf0aeSJoe Perches my $curpos = 0; 6252459cf0aeSJoe Perches my $lastpos = 0; 6253459cf0aeSJoe Perches while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 6254459cf0aeSJoe Perches $curpos = pos($line); 6255459cf0aeSJoe Perches my $match = $2; 6256459cf0aeSJoe Perches my $omatch = $1; 6257459cf0aeSJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 6258459cf0aeSJoe Perches $lastpos = $curpos; 6259459cf0aeSJoe Perches $to |= $mode_permission_string_types{$match}; 6260459cf0aeSJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 6261459cf0aeSJoe Perches $val .= $match; 6262459cf0aeSJoe Perches $oval .= $omatch; 6263f90774e1SJoe Perches } 6264459cf0aeSJoe Perches $oval =~ s/^\s*\|\s*//; 6265459cf0aeSJoe Perches $oval =~ s/\s*\|\s*$//; 6266459cf0aeSJoe Perches my $octal = sprintf("%04o", $to); 6267f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6268459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6269f90774e1SJoe Perches $fix) { 6270459cf0aeSJoe Perches $fixed[$fixlinenr] =~ s/$val/$octal/; 62712435880fSJoe Perches } 627213214adfSAndy Whitcroft } 62735a6d20ceSBjorn Andersson 62745a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 62755a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 62765a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 62775a6d20ceSBjorn Andersson my $valid_licenses = qr{ 62785a6d20ceSBjorn Andersson GPL| 62795a6d20ceSBjorn Andersson GPL\ v2| 62805a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 62815a6d20ceSBjorn Andersson Dual\ BSD/GPL| 62825a6d20ceSBjorn Andersson Dual\ MIT/GPL| 62835a6d20ceSBjorn Andersson Dual\ MPL/GPL| 62845a6d20ceSBjorn Andersson Proprietary 62855a6d20ceSBjorn Andersson }x; 62865a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 62875a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 62885a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 62895a6d20ceSBjorn Andersson } 62905a6d20ceSBjorn Andersson } 6291515a235eSJoe Perches } 629213214adfSAndy Whitcroft 629313214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 629413214adfSAndy Whitcroft # so just keep quiet. 629513214adfSAndy Whitcroft if ($#rawlines == -1) { 629613214adfSAndy Whitcroft exit(0); 62970a920b5bSAndy Whitcroft } 62980a920b5bSAndy Whitcroft 62998905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 63008905a67cSAndy Whitcroft # things that appear to be patches. 63018905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 63028905a67cSAndy Whitcroft exit(0); 63038905a67cSAndy Whitcroft } 63048905a67cSAndy Whitcroft 63058905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 63068905a67cSAndy Whitcroft # just keep quiet. 63078905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 63088905a67cSAndy Whitcroft exit(0); 63098905a67cSAndy Whitcroft } 63108905a67cSAndy Whitcroft 631106330fc4SJoe Perches if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6312000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6313000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 63140a920b5bSAndy Whitcroft } 6315ed43c4e5SAllen Hubbe if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6316000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6317000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 63180a920b5bSAndy Whitcroft } 63190a920b5bSAndy Whitcroft 6320f0a594c1SAndy Whitcroft print report_dump(); 632113214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 632213214adfSAndy Whitcroft print "$filename " if ($summary_file); 63236c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 63246c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 63256c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 63266c72ffaaSAndy Whitcroft } 63278905a67cSAndy Whitcroft 6328d2c0a235SAndy Whitcroft if ($quiet == 0) { 6329ef212196SJoe Perches # If there were any defects found and not already fixing them 6330ef212196SJoe Perches if (!$clean and !$fix) { 6331ef212196SJoe Perches print << "EOM" 6332ef212196SJoe Perches 6333ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6334ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6335ef212196SJoe PerchesEOM 6336ef212196SJoe Perches } 6337d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6338d2c0a235SAndy Whitcroft # then suggest that. 6339d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6340b0781216SMike Frysinger $rpt_cleaners = 0; 6341d8469f16SJoe Perches print << "EOM" 6342d8469f16SJoe Perches 6343d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6344d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6345d8469f16SJoe PerchesEOM 6346d2c0a235SAndy Whitcroft } 6347d2c0a235SAndy Whitcroft } 6348d2c0a235SAndy Whitcroft 6349d752fcc8SJoe Perches if ($clean == 0 && $fix && 6350d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6351d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 63529624b8d6SJoe Perches my $newfile = $filename; 63539624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 63543705ce5bSJoe Perches my $linecount = 0; 63553705ce5bSJoe Perches my $f; 63563705ce5bSJoe Perches 6357d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6358d752fcc8SJoe Perches 63593705ce5bSJoe Perches open($f, '>', $newfile) 63603705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 63613705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 63623705ce5bSJoe Perches $linecount++; 63633705ce5bSJoe Perches if ($file) { 63643705ce5bSJoe Perches if ($linecount > 3) { 63653705ce5bSJoe Perches $fixed_line =~ s/^\+//; 63663705ce5bSJoe Perches print $f $fixed_line . "\n"; 63673705ce5bSJoe Perches } 63683705ce5bSJoe Perches } else { 63693705ce5bSJoe Perches print $f $fixed_line . "\n"; 63703705ce5bSJoe Perches } 63713705ce5bSJoe Perches } 63723705ce5bSJoe Perches close($f); 63733705ce5bSJoe Perches 63743705ce5bSJoe Perches if (!$quiet) { 63753705ce5bSJoe Perches print << "EOM"; 6376d8469f16SJoe Perches 63773705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 63783705ce5bSJoe Perches 63793705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 63803705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 63813705ce5bSJoe Perches 63823705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 63833705ce5bSJoe PerchesNo warranties, expressed or implied... 63843705ce5bSJoe PerchesEOM 63853705ce5bSJoe Perches } 63863705ce5bSJoe Perches } 63873705ce5bSJoe Perches 6388d8469f16SJoe Perches if ($quiet == 0) { 6389d8469f16SJoe Perches print "\n"; 6390d8469f16SJoe Perches if ($clean == 1) { 6391d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6392d8469f16SJoe Perches } else { 6393d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 63940a920b5bSAndy Whitcroft } 63950a920b5bSAndy Whitcroft } 63960a920b5bSAndy Whitcroft return $clean; 63970a920b5bSAndy Whitcroft} 6398