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 2779327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 2780327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 2781327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 2782327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 2783327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2784327953e9SChristoph Jaeger } 2785327953e9SChristoph Jaeger 2786c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2787c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2788c68e5878SArnaud Lacombe my $flag = $1; 2789c68e5878SArnaud Lacombe my $replacement = { 2790c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 2791c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 2792c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 2793c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 2794c68e5878SArnaud Lacombe }; 2795c68e5878SArnaud Lacombe 2796c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 2797c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2798c68e5878SArnaud Lacombe } 2799c68e5878SArnaud Lacombe 2800bff5da43SRob Herring# check for DT compatible documentation 28017dd05b38SFlorian Vaussard if (defined $root && 28027dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 28037dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 28047dd05b38SFlorian Vaussard 2805bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 2806bff5da43SRob Herring 2807cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 2808cc93319bSFlorian Vaussard my $vp_file = $dt_path . "vendor-prefixes.txt"; 2809cc93319bSFlorian Vaussard 2810bff5da43SRob Herring foreach my $compat (@compats) { 2811bff5da43SRob Herring my $compat2 = $compat; 2812185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 2813185d566bSRob Herring my $compat3 = $compat; 2814185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 2815185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 2816bff5da43SRob Herring if ( $? >> 8 ) { 2817bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2818bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 2819bff5da43SRob Herring } 2820bff5da43SRob Herring 28214fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 28224fbf32a6SFlorian Vaussard my $vendor = $1; 2823cc93319bSFlorian Vaussard `grep -Eq "^$vendor\\b" $vp_file`; 2824bff5da43SRob Herring if ( $? >> 8 ) { 2825bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2826cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 2827bff5da43SRob Herring } 2828bff5da43SRob Herring } 2829bff5da43SRob Herring } 2830bff5da43SRob Herring 28315368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 2832d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 28335368df20SAndy Whitcroft 283447e0c88bSJoe Perches# line length limit (with some exclusions) 283547e0c88bSJoe Perches# 283647e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 283747e0c88bSJoe Perches# logging functions like pr_info that end in a string 283847e0c88bSJoe Perches# lines with a single string 283947e0c88bSJoe Perches# #defines that are a single string 284047e0c88bSJoe Perches# 284147e0c88bSJoe Perches# There are 3 different line length message types: 284247e0c88bSJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength 284347e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 284447e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 284547e0c88bSJoe Perches# 284647e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 284747e0c88bSJoe Perches# 284847e0c88bSJoe Perches 2849b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 285047e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 285147e0c88bSJoe Perches 285247e0c88bSJoe Perches # Check the allowed long line types first 285347e0c88bSJoe Perches 285447e0c88bSJoe Perches # logging functions that end in a string that starts 285547e0c88bSJoe Perches # before $max_line_length 285647e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 285747e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 285847e0c88bSJoe Perches $msg_type = ""; 285947e0c88bSJoe Perches 286047e0c88bSJoe Perches # lines with only strings (w/ possible termination) 286147e0c88bSJoe Perches # #defines with only strings 286247e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 286347e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 286447e0c88bSJoe Perches $msg_type = ""; 286547e0c88bSJoe Perches 2866d560a5f8SJoe Perches # EFI_GUID is another special case 2867d560a5f8SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { 2868d560a5f8SJoe Perches $msg_type = ""; 2869d560a5f8SJoe Perches 287047e0c88bSJoe Perches # Otherwise set the alternate message types 287147e0c88bSJoe Perches 287247e0c88bSJoe Perches # a comment starts before $max_line_length 287347e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 287447e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 287547e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 287647e0c88bSJoe Perches 287747e0c88bSJoe Perches # a quoted string starts before $max_line_length 287847e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 287947e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 288047e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 288147e0c88bSJoe Perches } 288247e0c88bSJoe Perches 288347e0c88bSJoe Perches if ($msg_type ne "" && 288447e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 288547e0c88bSJoe Perches WARN($msg_type, 28866cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 28870a920b5bSAndy Whitcroft } 288847e0c88bSJoe Perches } 28890a920b5bSAndy Whitcroft 28908905a67cSAndy Whitcroft# check for adding lines without a newline. 28918905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2892000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 2893000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 28948905a67cSAndy Whitcroft } 28958905a67cSAndy Whitcroft 289642e41c54SMike Frysinger# Blackfin: use hi/lo macros 289742e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 289842e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 289942e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2900000d1cc1SJoe Perches ERROR("LO_MACRO", 2901000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 290242e41c54SMike Frysinger } 290342e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 290442e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2905000d1cc1SJoe Perches ERROR("HI_MACRO", 2906000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 290742e41c54SMike Frysinger } 290842e41c54SMike Frysinger } 290942e41c54SMike Frysinger 2910b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2911de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 29120a920b5bSAndy Whitcroft 29130a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 29140a920b5bSAndy Whitcroft# more than 8 must use tabs. 2915c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2916c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2917c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2918d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29193705ce5bSJoe Perches if (ERROR("CODE_INDENT", 29203705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 29213705ce5bSJoe Perches $fix) { 2922194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 29233705ce5bSJoe Perches } 29240a920b5bSAndy Whitcroft } 29250a920b5bSAndy Whitcroft 292608e44365SAlberto Panizzo# check for space before tabs. 292708e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 292808e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29293705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 29303705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 29313705ce5bSJoe Perches $fix) { 2932194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2933d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 2934194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2935c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 29363705ce5bSJoe Perches } 293708e44365SAlberto Panizzo } 293808e44365SAlberto Panizzo 2939d1fe9c09SJoe Perches# check for && or || at the start of a line 2940d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2941d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2942d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2943d1fe9c09SJoe Perches } 2944d1fe9c09SJoe Perches 2945a91e8994SJoe Perches# check indentation starts on a tab stop 2946a91e8994SJoe Perches if ($^V && $^V ge 5.10.0 && 2947a91e8994SJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { 2948a91e8994SJoe Perches my $indent = length($1); 2949a91e8994SJoe Perches if ($indent % 8) { 2950a91e8994SJoe Perches if (WARN("TABSTOP", 2951a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 2952a91e8994SJoe Perches $fix) { 2953a91e8994SJoe Perches $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 2954a91e8994SJoe Perches } 2955a91e8994SJoe Perches } 2956a91e8994SJoe Perches } 2957a91e8994SJoe Perches 2958d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2959d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 296091cb5195SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2961d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2962d1fe9c09SJoe Perches my $oldindent = $1; 2963d1fe9c09SJoe Perches my $rest = $2; 2964d1fe9c09SJoe Perches 2965d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2966d1fe9c09SJoe Perches if ($pos >= 0) { 2967b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2968b34a26f3SJoe Perches my $newindent = $2; 2969d1fe9c09SJoe Perches 2970d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2971d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2972d1fe9c09SJoe Perches " " x ($pos % 8); 2973d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2974d1fe9c09SJoe Perches 2975d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2976d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 29773705ce5bSJoe Perches 29783705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 29793705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 29803705ce5bSJoe Perches $fix && $line =~ /^\+/) { 2981194f66fcSJoe Perches $fixed[$fixlinenr] =~ 29823705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 29833705ce5bSJoe Perches } 2984d1fe9c09SJoe Perches } 2985d1fe9c09SJoe Perches } 2986d1fe9c09SJoe Perches } 2987d1fe9c09SJoe Perches 29886ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 29896ab3a970SJoe Perches# avoid checking a few false positives: 29906ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 29916ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 29926ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 29936ab3a970SJoe Perches# multiline macros that define functions 29946ab3a970SJoe Perches# known attributes or the __attribute__ keyword 29956ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 29966ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 29973705ce5bSJoe Perches if (CHK("SPACING", 2998f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 29993705ce5bSJoe Perches $fix) { 3000194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3001f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 30023705ce5bSJoe Perches } 3003aad4f614SJoe Perches } 3004aad4f614SJoe Perches 300586406b1cSJoe Perches# Block comment styles 300686406b1cSJoe Perches# Networking with an initial /* 300705880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3008fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 300985ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 301085ad978cSJoe Perches $realline > 2) { 301105880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 301205880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 301305880600SJoe Perches } 301405880600SJoe Perches 301586406b1cSJoe Perches# Block comments use * on subsequent lines 301686406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 301786406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3018a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 301961135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3020a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 302186406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 302286406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3023a605e32eSJoe Perches } 3024a605e32eSJoe Perches 302586406b1cSJoe Perches# Block comments use */ on trailing lines 302686406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3027c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3028c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3029c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 303086406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 303186406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 303205880600SJoe Perches } 303305880600SJoe Perches 303408eb9b80SJoe Perches# Block comment * alignment 303508eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3036af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3037af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3038af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 303908eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3040af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3041af207524SJoe Perches my $oldindent; 304208eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3043af207524SJoe Perches if (defined($1)) { 3044af207524SJoe Perches $oldindent = expand_tabs($1); 3045af207524SJoe Perches } else { 3046af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3047af207524SJoe Perches $oldindent = expand_tabs($1); 3048af207524SJoe Perches } 304908eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 305008eb9b80SJoe Perches my $newindent = $1; 305108eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3052af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 305308eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 305408eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 305508eb9b80SJoe Perches } 305608eb9b80SJoe Perches } 305708eb9b80SJoe Perches 30587f619191SJoe Perches# check for missing blank lines after struct/union declarations 30597f619191SJoe Perches# with exceptions for various attributes and macros 30607f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 30617f619191SJoe Perches $line =~ /^\+/ && 30627f619191SJoe Perches !($line =~ /^\+\s*$/ || 30637f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 30647f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 30657f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 30667f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 30677f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 30687f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 30697f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3070d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3071d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3072d752fcc8SJoe Perches $fix) { 3073f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3074d752fcc8SJoe Perches } 30757f619191SJoe Perches } 30767f619191SJoe Perches 3077365dd4eaSJoe Perches# check for multiple consecutive blank lines 3078365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3079365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3080365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3081d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3082d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3083d752fcc8SJoe Perches $fix) { 3084f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3085d752fcc8SJoe Perches } 3086d752fcc8SJoe Perches 3087365dd4eaSJoe Perches $last_blank_line = $linenr; 3088365dd4eaSJoe Perches } 3089365dd4eaSJoe Perches 30903b617e3bSJoe Perches# check for missing blank lines after declarations 30913f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 30923f7bac03SJoe Perches # actual declarations 30933f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 30945a4e1fd3SJoe Perches # function pointer declarations 30955a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 30963f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 30973f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 30983f7bac03SJoe Perches # known declaration macros 30993f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 31003f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 31013f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 31023f7bac03SJoe Perches # other possible extensions of declaration lines 31033f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 31043f7bac03SJoe Perches # not starting a section or a macro "\" extended line 31053f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 31063f7bac03SJoe Perches # looks like a declaration 31073f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31085a4e1fd3SJoe Perches # function pointer declarations 31095a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31103f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31113f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31123f7bac03SJoe Perches # known declaration macros 31133f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 31143f7bac03SJoe Perches # start of struct or union or enum 31153b617e3bSJoe Perches $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 31163f7bac03SJoe Perches # start or end of block or continuation of declaration 31173f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 31183f7bac03SJoe Perches # bitfield continuation 31193f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 31203f7bac03SJoe Perches # other possible extensions of declaration lines 31213f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 31223f7bac03SJoe Perches # indentation of previous and current line are the same 31233f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3124d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3125d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3126d752fcc8SJoe Perches $fix) { 3127f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3128d752fcc8SJoe Perches } 31293b617e3bSJoe Perches } 31303b617e3bSJoe Perches 31315f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 31326b4c5bebSAndy Whitcroft# Exceptions: 31336b4c5bebSAndy Whitcroft# 1) within comments 31346b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 31356b4c5bebSAndy Whitcroft# 3) hanging labels 31363705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 31375f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 31383705ce5bSJoe Perches if (WARN("LEADING_SPACE", 31393705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 31403705ce5bSJoe Perches $fix) { 3141194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31423705ce5bSJoe Perches } 31435f7ddae6SRaffaele Recalcati } 31445f7ddae6SRaffaele Recalcati 3145b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3146b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3147b9ea10d6SAndy Whitcroft 31484dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 31494dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 31504dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 31514dbed76fSJoe Perches $context_function = $1; 31524dbed76fSJoe Perches } 31534dbed76fSJoe Perches 31544dbed76fSJoe Perches# check if this appears to be the end of function declaration 31554dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 31564dbed76fSJoe Perches undef $context_function; 31574dbed76fSJoe Perches } 31584dbed76fSJoe Perches 3159032a4c0fSJoe Perches# check indentation of any line with a bare else 3160840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3161032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3162032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3163032a4c0fSJoe Perches my $tabs = length($1) + 1; 3164840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3165840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3166840080a0SJoe Perches defined $lines[$linenr] && 3167840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3168032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3169032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3170032a4c0fSJoe Perches } 3171032a4c0fSJoe Perches } 3172032a4c0fSJoe Perches 3173c00df19aSJoe Perches# check indentation of a line with a break; 3174c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3175c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3176c00df19aSJoe Perches my $tabs = $1; 3177c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3178c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3179c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3180c00df19aSJoe Perches } 3181c00df19aSJoe Perches } 3182c00df19aSJoe Perches 3183c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3184cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3185000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3186000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3187c2fdda0dSAndy Whitcroft } 318822f2a2efSAndy Whitcroft 318942e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 319042e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 319142e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3192000d1cc1SJoe Perches ERROR("CSYNC", 3193000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 319442e41c54SMike Frysinger } 319542e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 319642e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3197000d1cc1SJoe Perches ERROR("SSYNC", 3198000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 319942e41c54SMike Frysinger } 320042e41c54SMike Frysinger 320156e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 320256e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 320356e77d70SJoe Perches WARN("HOTPLUG_SECTION", 320456e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 320556e77d70SJoe Perches } 320656e77d70SJoe Perches 32079c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 32082b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 32092b474a1aSAndy Whitcroft $realline_next); 32103e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 32113e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 32121b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3213170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3214f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3215171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3216171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3217171ae1a4SAndy Whitcroft 32183e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 32193e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 32203e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 32213e469cdcSAndy Whitcroft # until we hit end of it. 32223e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 32233e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 32243e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 32253e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 32263e469cdcSAndy Whitcroft } 3227f74bd194SAndy Whitcroft 32282b474a1aSAndy Whitcroft # Find the real next line. 32292b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 32302b474a1aSAndy Whitcroft if (defined $realline_next && 32312b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 32322b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 32332b474a1aSAndy Whitcroft $realline_next++; 32342b474a1aSAndy Whitcroft } 32352b474a1aSAndy Whitcroft 3236171ae1a4SAndy Whitcroft my $s = $stat; 3237171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3238cf655043SAndy Whitcroft 3239c2fdda0dSAndy Whitcroft # Ignore goto labels. 3240171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3241c2fdda0dSAndy Whitcroft 3242c2fdda0dSAndy Whitcroft # Ignore functions being called 3243171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3244c2fdda0dSAndy Whitcroft 3245463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3246463f2864SAndy Whitcroft 3247c45dcabdSAndy Whitcroft # declarations always start with types 3248d2506586SAndy 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) { 3249c45dcabdSAndy Whitcroft my $type = $1; 3250c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3251c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3252c45dcabdSAndy Whitcroft 32536c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3254a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3255c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3256c2fdda0dSAndy Whitcroft } 32578905a67cSAndy Whitcroft 32586c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 325965863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3260c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 32619c0ca6f9SAndy Whitcroft } 32628905a67cSAndy Whitcroft 32638905a67cSAndy Whitcroft # Check for any sort of function declaration. 32648905a67cSAndy Whitcroft # int foo(something bar, other baz); 32658905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3266171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 32678905a67cSAndy Whitcroft my ($name_len) = length($1); 32688905a67cSAndy Whitcroft 3269cf655043SAndy Whitcroft my $ctx = $s; 3270773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 32718905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3272cf655043SAndy Whitcroft 32738905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3274c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 32758905a67cSAndy Whitcroft 3276c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 32778905a67cSAndy Whitcroft } 32788905a67cSAndy Whitcroft } 32798905a67cSAndy Whitcroft } 32808905a67cSAndy Whitcroft 32819c0ca6f9SAndy Whitcroft } 32829c0ca6f9SAndy Whitcroft 328300df344fSAndy Whitcroft# 328400df344fSAndy Whitcroft# Checks which may be anchored in the context. 328500df344fSAndy Whitcroft# 328600df344fSAndy Whitcroft 328700df344fSAndy Whitcroft# Check for switch () and associated case and default 328800df344fSAndy Whitcroft# statements should be at the same indent. 328900df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 329000df344fSAndy Whitcroft my $err = ''; 329100df344fSAndy Whitcroft my $sep = ''; 329200df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 329300df344fSAndy Whitcroft shift(@ctx); 329400df344fSAndy Whitcroft for my $ctx (@ctx) { 329500df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 329600df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 329700df344fSAndy Whitcroft $indent != $cindent) { 329800df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 329900df344fSAndy Whitcroft $sep = ''; 330000df344fSAndy Whitcroft } else { 330100df344fSAndy Whitcroft $sep = "[...]\n"; 330200df344fSAndy Whitcroft } 330300df344fSAndy Whitcroft } 330400df344fSAndy Whitcroft if ($err ne '') { 3305000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3306000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3307de7d4f0eSAndy Whitcroft } 3308de7d4f0eSAndy Whitcroft } 3309de7d4f0eSAndy Whitcroft 3310de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3311de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 33120fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3313773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3314773647a0SAndy Whitcroft 33159c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 33168eef05ddSJoe Perches 33178eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 33188eef05ddSJoe Perches WARN("DEEP_INDENTATION", 33198eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 33208eef05ddSJoe Perches } 33218eef05ddSJoe Perches 3322de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3323de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3324de7d4f0eSAndy Whitcroft 3325548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3326548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3327de7d4f0eSAndy Whitcroft 3328548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3329548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3330548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3331548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3332548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3333773647a0SAndy Whitcroft $ctx_ln++; 3334773647a0SAndy Whitcroft } 3335548596d5SAndy Whitcroft 333653210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 333753210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3338773647a0SAndy Whitcroft 3339773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3340000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3341000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 334201464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 334300df344fSAndy Whitcroft } 3344773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3345773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3346773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3347773647a0SAndy Whitcroft { 33489c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 33499c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3350000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3351000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 335201464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 33539c0ca6f9SAndy Whitcroft } 33549c0ca6f9SAndy Whitcroft } 335500df344fSAndy Whitcroft } 335600df344fSAndy Whitcroft 33574d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3358f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 33593e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 33603e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 33613e469cdcSAndy Whitcroft if (!defined $stat); 33624d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 33634d001e4dSAndy Whitcroft 33644d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 33654d001e4dSAndy Whitcroft 33669f5af480SJoe Perches # remove inline comments 33679f5af480SJoe Perches $s =~ s/$;/ /g; 33689f5af480SJoe Perches $c =~ s/$;/ /g; 33694d001e4dSAndy Whitcroft 33704d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 33716f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 33726f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 33734d001e4dSAndy Whitcroft 33749f5af480SJoe Perches # Make sure we remove the line prefixes as we have 33759f5af480SJoe Perches # none on the first line, and are going to readd them 33769f5af480SJoe Perches # where necessary. 33779f5af480SJoe Perches $s =~ s/\n./\n/gs; 33789f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 33799f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 33809f5af480SJoe Perches } 33819f5af480SJoe Perches 33824d001e4dSAndy Whitcroft # We want to check the first line inside the block 33834d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 33844d001e4dSAndy Whitcroft # 1) any blank line termination 33854d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 33864d001e4dSAndy Whitcroft # 3) any do (...) { 33874d001e4dSAndy Whitcroft my $continuation = 0; 33884d001e4dSAndy Whitcroft my $check = 0; 33894d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 33904d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 33914d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 33924d001e4dSAndy Whitcroft $continuation = 1; 33934d001e4dSAndy Whitcroft } 33949bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 33954d001e4dSAndy Whitcroft $check = 1; 33964d001e4dSAndy Whitcroft $cond_lines++; 33974d001e4dSAndy Whitcroft } 33984d001e4dSAndy Whitcroft 33994d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 34004d001e4dSAndy Whitcroft # preprocessor statement. 34014d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 34024d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 34034d001e4dSAndy Whitcroft $check = 0; 34044d001e4dSAndy Whitcroft } 34054d001e4dSAndy Whitcroft 34069bd49efeSAndy Whitcroft my $cond_ptr = -1; 3407740504c6SAndy Whitcroft $continuation = 0; 34089bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 34099bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 34104d001e4dSAndy Whitcroft 3411f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3412f16fa28fSAndy Whitcroft # is not linear. 3413f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3414f16fa28fSAndy Whitcroft $check = 0; 3415f16fa28fSAndy Whitcroft } 3416f16fa28fSAndy Whitcroft 34179bd49efeSAndy Whitcroft # Ignore: 34189bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 34199bd49efeSAndy Whitcroft # 2) preprocessor lines, and 34209bd49efeSAndy Whitcroft # 3) labels. 3421740504c6SAndy Whitcroft if ($continuation || 3422740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 34239bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 34249bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3425740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 342630dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 34279bd49efeSAndy Whitcroft $cond_lines++; 34289bd49efeSAndy Whitcroft } 34294d001e4dSAndy Whitcroft } 343030dad6ebSAndy Whitcroft } 34314d001e4dSAndy Whitcroft 34324d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 34334d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 34344d001e4dSAndy Whitcroft 34354d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 34364d001e4dSAndy Whitcroft # this is not this patch's fault. 34374d001e4dSAndy Whitcroft if (!defined($stat_real) || 34384d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 34394d001e4dSAndy Whitcroft $check = 0; 34404d001e4dSAndy Whitcroft } 34414d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 34424d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 34434d001e4dSAndy Whitcroft } 34444d001e4dSAndy Whitcroft 34459bd49efeSAndy 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"; 34464d001e4dSAndy Whitcroft 34479f5af480SJoe Perches if ($check && $s ne '' && 34489f5af480SJoe Perches (($sindent % 8) != 0 || 34499f5af480SJoe Perches ($sindent < $indent) || 3450f6950a73SJoe Perches ($sindent == $indent && 3451f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 34529f5af480SJoe Perches ($sindent > $indent + 8))) { 3453000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3454000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 34554d001e4dSAndy Whitcroft } 34564d001e4dSAndy Whitcroft } 34574d001e4dSAndy Whitcroft 34586c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 34596c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 34601f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 34611f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 34626c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3463c2fdda0dSAndy Whitcroft if ($dbg_values) { 3464c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3465cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3466cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 34671f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3468c2fdda0dSAndy Whitcroft } 34696c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 34706c72ffaaSAndy Whitcroft 347100df344fSAndy Whitcroft#ignore lines not being added 34723705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 347300df344fSAndy Whitcroft 347411ca40a0SJoe Perches# check for dereferences that span multiple lines 347511ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 347611ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 347711ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 347811ca40a0SJoe Perches my $ref = $1; 347911ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 348011ca40a0SJoe Perches $ref .= $1; 348111ca40a0SJoe Perches $ref =~ s/\s//g; 348211ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 348311ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 348411ca40a0SJoe Perches } 348511ca40a0SJoe Perches 3486a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3487c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3488a1ce18e4SJoe Perches my $type = $1; 3489a1ce18e4SJoe Perches my $var = $2; 3490207a8e84SJoe Perches $var = "" if (!defined $var); 3491207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3492a1ce18e4SJoe Perches my $sign = $1; 3493a1ce18e4SJoe Perches my $pointer = $2; 3494a1ce18e4SJoe Perches 3495a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3496a1ce18e4SJoe Perches 3497a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3498a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3499a1ce18e4SJoe Perches $fix) { 3500a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3501207a8e84SJoe Perches my $comp_pointer = $pointer; 3502207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3503207a8e84SJoe Perches $decl .= $comp_pointer; 3504207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3505207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3506a1ce18e4SJoe Perches } 3507a1ce18e4SJoe Perches } 3508a1ce18e4SJoe Perches } 3509a1ce18e4SJoe Perches 3510653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 35117429c690SAndy Whitcroft if ($dbg_type) { 35127429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3513000d1cc1SJoe Perches ERROR("TEST_TYPE", 3514000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 35157429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3516000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3517000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 35187429c690SAndy Whitcroft } 3519653d4876SAndy Whitcroft next; 3520653d4876SAndy Whitcroft } 3521a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3522a1ef277eSAndy Whitcroft if ($dbg_attr) { 35239360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3524000d1cc1SJoe Perches ERROR("TEST_ATTR", 3525000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 35269360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3527000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3528000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3529a1ef277eSAndy Whitcroft } 3530a1ef277eSAndy Whitcroft next; 3531a1ef277eSAndy Whitcroft } 3532653d4876SAndy Whitcroft 3533f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 353499423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 353599423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3536d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3537d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3538f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3539f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3540f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3541d752fcc8SJoe Perches my $fixedline = $prevrawline; 3542d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3543f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3544d752fcc8SJoe Perches $fixedline = $line; 3545d752fcc8SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1/; 3546f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3547d752fcc8SJoe Perches } 3548f0a594c1SAndy Whitcroft } 3549f0a594c1SAndy Whitcroft 355000df344fSAndy Whitcroft# 355100df344fSAndy Whitcroft# Checks which are anchored on the added line. 355200df344fSAndy Whitcroft# 355300df344fSAndy Whitcroft 3554653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3555c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3556653d4876SAndy Whitcroft my $path = $1; 3557653d4876SAndy Whitcroft if ($path =~ m{//}) { 3558000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3559495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3560495e9d84SJoe Perches } 3561495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3562495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3563495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3564653d4876SAndy Whitcroft } 3565653d4876SAndy Whitcroft } 3566653d4876SAndy Whitcroft 356700df344fSAndy Whitcroft# no C99 // comments 356800df344fSAndy Whitcroft if ($line =~ m{//}) { 35693705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 35703705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 35713705ce5bSJoe Perches $fix) { 3572194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 35733705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 35743705ce5bSJoe Perches my $comment = trim($1); 3575194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 35763705ce5bSJoe Perches } 35773705ce5bSJoe Perches } 357800df344fSAndy Whitcroft } 357900df344fSAndy Whitcroft # Remove C99 comments. 35800a920b5bSAndy Whitcroft $line =~ s@//.*@@; 35816c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 35820a920b5bSAndy Whitcroft 35832b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 35842b474a1aSAndy Whitcroft# the whole statement. 35852b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 35862b474a1aSAndy Whitcroft if (defined $realline_next && 35872b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 35882b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 35892b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 35902b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 35913cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 35923cbf62dfSAndy Whitcroft # a prefix: 35933cbf62dfSAndy Whitcroft # XXX(foo); 35943cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3595653d4876SAndy Whitcroft my $name = $1; 359687a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 35973cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 35983cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 35993cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 36003cbf62dfSAndy Whitcroft 36013cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 36022b474a1aSAndy Whitcroft \n.}\s*$| 360348012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 360448012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 360548012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 36062b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 36072b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 360848012058SAndy Whitcroft )/x) { 36092b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 36102b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 36112b474a1aSAndy Whitcroft } else { 36122b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 36130a920b5bSAndy Whitcroft } 36140a920b5bSAndy Whitcroft } 36152b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 36162b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 36172b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36182b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36192b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 36202b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 36212b474a1aSAndy Whitcroft } 36222b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 36232b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3624000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3625000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 36262b474a1aSAndy Whitcroft } 36270a920b5bSAndy Whitcroft 36285150bda4SJoe Eloff# check for global initialisers. 36296d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3630d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 36316d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3632d5e616fcSJoe Perches $fix) { 36336d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3634d5e616fcSJoe Perches } 3635f0a594c1SAndy Whitcroft } 36360a920b5bSAndy Whitcroft# check for static initialisers. 36376d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3638d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 36396d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3640d5e616fcSJoe Perches $herecurr) && 3641d5e616fcSJoe Perches $fix) { 36426d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3643d5e616fcSJoe Perches } 36440a920b5bSAndy Whitcroft } 36450a920b5bSAndy Whitcroft 36461813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 36471813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36481813087dSJoe Perches my $tmp = trim($1); 36491813087dSJoe Perches WARN("MISORDERED_TYPE", 36501813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36511813087dSJoe Perches } 36521813087dSJoe Perches 3653cb710ecaSJoe Perches# check for static const char * arrays. 3654cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3655000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3656000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3657cb710ecaSJoe Perches $herecurr); 3658cb710ecaSJoe Perches } 3659cb710ecaSJoe Perches 3660cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3661cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3662000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3663000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3664cb710ecaSJoe Perches $herecurr); 3665cb710ecaSJoe Perches } 3666cb710ecaSJoe Perches 3667ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3668ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3669ab7e23f3SJoe Perches my $found = $1; 3670ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3671ab7e23f3SJoe Perches WARN("CONST_CONST", 3672ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3673ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3674ab7e23f3SJoe Perches WARN("CONST_CONST", 3675ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3676ab7e23f3SJoe Perches } 3677ab7e23f3SJoe Perches } 3678ab7e23f3SJoe Perches 36799b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 36809b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 36819b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 36829b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 36839b0fa60dSJoe Perches $herecurr); 36849b0fa60dSJoe Perches } 36859b0fa60dSJoe Perches 3686b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3687b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3688b598b670SJoe Perches my $array = $1; 3689b598b670SJoe 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*\))@) { 3690b598b670SJoe Perches my $array_div = $1; 3691b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3692b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3693b598b670SJoe Perches $fix) { 3694b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3695b598b670SJoe Perches } 3696b598b670SJoe Perches } 3697b598b670SJoe Perches } 3698b598b670SJoe Perches 3699b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3700b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3701b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3702b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3703b36190c5SJoe Perches $fix) { 3704194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3705b36190c5SJoe Perches } 3706b36190c5SJoe Perches } 3707b36190c5SJoe Perches 3708653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3709653d4876SAndy Whitcroft# make sense. 3710653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 37118054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3712c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 37138ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 371446d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 3715000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3716000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 37170a920b5bSAndy Whitcroft } 37180a920b5bSAndy Whitcroft 37190a920b5bSAndy Whitcroft# * goes on variable not on type 372065863862SAndy Whitcroft # (char*[ const]) 3721bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3722bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 37233705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3724d8aaf121SAndy Whitcroft 372565863862SAndy Whitcroft # Should start with a space. 372665863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 372765863862SAndy Whitcroft # Should not end with a space. 372865863862SAndy Whitcroft $to =~ s/\s+$//; 372965863862SAndy Whitcroft # '*'s should not have spaces between. 3730f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 373165863862SAndy Whitcroft } 3732d8aaf121SAndy Whitcroft 37333705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 373465863862SAndy Whitcroft if ($from ne $to) { 37353705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37363705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37373705ce5bSJoe Perches $fix) { 37383705ce5bSJoe Perches my $sub_from = $ident; 37393705ce5bSJoe Perches my $sub_to = $ident; 37403705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3741194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37423705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37433705ce5bSJoe Perches } 374465863862SAndy Whitcroft } 3745bfcb2cc7SAndy Whitcroft } 3746bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3747bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 37483705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3749d8aaf121SAndy Whitcroft 375065863862SAndy Whitcroft # Should start with a space. 375165863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 375265863862SAndy Whitcroft # Should not end with a space. 375365863862SAndy Whitcroft $to =~ s/\s+$//; 375465863862SAndy Whitcroft # '*'s should not have spaces between. 3755f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 375665863862SAndy Whitcroft } 375765863862SAndy Whitcroft # Modifiers should have spaces. 375865863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 375965863862SAndy Whitcroft 37603705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3761667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 37623705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37633705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 37643705ce5bSJoe Perches $fix) { 37653705ce5bSJoe Perches 37663705ce5bSJoe Perches my $sub_from = $match; 37673705ce5bSJoe Perches my $sub_to = $match; 37683705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3769194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37703705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37713705ce5bSJoe Perches } 377265863862SAndy Whitcroft } 37730a920b5bSAndy Whitcroft } 37740a920b5bSAndy Whitcroft 37759d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 37769d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 37779d3e3c70SJoe Perches my $msg_type = \&WARN; 37789d3e3c70SJoe Perches $msg_type = \&CHK if ($file); 37799d3e3c70SJoe Perches &{$msg_type}("AVOID_BUG", 37809d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 37819d3e3c70SJoe Perches } 37820a920b5bSAndy Whitcroft 37839d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 37848905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3785000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3786000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 37878905a67cSAndy Whitcroft } 37888905a67cSAndy Whitcroft 378917441227SJoe Perches# check for uses of printk_ratelimit 379017441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3791000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3792000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 379317441227SJoe Perches } 379417441227SJoe Perches 379500df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 379600df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 379700df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 379825985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 379900df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3800f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 380100df344fSAndy Whitcroft my $ok = 0; 380200df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 380300df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 380425985edcSLucas De Marchi # we have a preceding printk if it ends 380500df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 380600df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 380700df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 380800df344fSAndy Whitcroft $ok = 1; 380900df344fSAndy Whitcroft } 381000df344fSAndy Whitcroft last; 381100df344fSAndy Whitcroft } 381200df344fSAndy Whitcroft } 381300df344fSAndy Whitcroft if ($ok == 0) { 3814000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3815000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 38160a920b5bSAndy Whitcroft } 381700df344fSAndy Whitcroft } 38180a920b5bSAndy Whitcroft 3819243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3820243f3803SJoe Perches my $orig = $1; 3821243f3803SJoe Perches my $level = lc($orig); 3822243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 38238f26b837SJoe Perches my $level2 = $level; 38248f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3825243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3826daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3827243f3803SJoe Perches } 3828243f3803SJoe Perches 3829243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3830d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3831d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3832d5e616fcSJoe Perches $fix) { 3833194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3834d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3835d5e616fcSJoe Perches } 3836243f3803SJoe Perches } 3837243f3803SJoe Perches 3838dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3839dc139313SJoe Perches my $orig = $1; 3840dc139313SJoe Perches my $level = lc($orig); 3841dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3842dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3843dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3844dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3845dc139313SJoe Perches } 3846dc139313SJoe Perches 384791c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 384891c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 384991c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 385091c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 385191c9afafSAndy Lutomirski WARN("ENOSYS", 385291c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 385391c9afafSAndy Lutomirski } 385491c9afafSAndy Lutomirski 3855653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3856653d4876SAndy Whitcroft# or if closed on same line 38578d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 38584e5d56bdSEddie Kovsky !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38598d182478SJoe Perches if (ERROR("OPEN_BRACE", 38608d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38618d182478SJoe Perches $fix) { 38628d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38638d182478SJoe Perches my $fixed_line = $rawline; 38648d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 38658d182478SJoe Perches my $line1 = $1; 38668d182478SJoe Perches my $line2 = $2; 38678d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 38688d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 38698d182478SJoe Perches if ($line2 !~ /^\s*$/) { 38708d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 38718d182478SJoe Perches } 38728d182478SJoe Perches } 38730a920b5bSAndy Whitcroft } 3874653d4876SAndy Whitcroft 38758905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 38768905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 38778905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 38788d182478SJoe Perches if (ERROR("OPEN_BRACE", 38798d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 38808d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 38818d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 38828d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38838d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 38848d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38858d182478SJoe Perches $fixedline = $rawline; 38868d182478SJoe Perches $fixedline =~ s/^(.\s*){\s*/$1\t/; 38878d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 38888d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38898d182478SJoe Perches } 38908d182478SJoe Perches } 38918905a67cSAndy Whitcroft } 38928905a67cSAndy Whitcroft 38930c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 38943705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 38953705ce5bSJoe Perches if (WARN("SPACING", 38963705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 38973705ce5bSJoe Perches $fix) { 3898194f66fcSJoe Perches $fixed[$fixlinenr] =~ 38993705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 39003705ce5bSJoe Perches } 39010c73b4ebSAndy Whitcroft } 39020c73b4ebSAndy Whitcroft 390331070b5dSJoe Perches# Function pointer declarations 390431070b5dSJoe Perches# check spacing between type, funcptr, and args 390531070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 390691f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 390731070b5dSJoe Perches my $declare = $1; 390831070b5dSJoe Perches my $pre_pointer_space = $2; 390931070b5dSJoe Perches my $post_pointer_space = $3; 391031070b5dSJoe Perches my $funcname = $4; 391131070b5dSJoe Perches my $post_funcname_space = $5; 391231070b5dSJoe Perches my $pre_args_space = $6; 391331070b5dSJoe Perches 391491f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 391591f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 391691f72e9cSJoe Perches# don't need a space so don't warn for those. 391791f72e9cSJoe Perches my $post_declare_space = ""; 391891f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 391991f72e9cSJoe Perches $post_declare_space = $1; 392091f72e9cSJoe Perches $declare = rtrim($declare); 392191f72e9cSJoe Perches } 392291f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 392331070b5dSJoe Perches WARN("SPACING", 392431070b5dSJoe Perches "missing space after return type\n" . $herecurr); 392591f72e9cSJoe Perches $post_declare_space = " "; 392631070b5dSJoe Perches } 392731070b5dSJoe Perches 392831070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 392991f72e9cSJoe Perches# This test is not currently implemented because these declarations are 393091f72e9cSJoe Perches# equivalent to 393191f72e9cSJoe Perches# int foo(int bar, ...) 393291f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 393391f72e9cSJoe Perches# 393491f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 393591f72e9cSJoe Perches# WARN("SPACING", 393691f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 393791f72e9cSJoe Perches# } 393831070b5dSJoe Perches 393931070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 394031070b5dSJoe Perches if (defined $pre_pointer_space && 394131070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 394231070b5dSJoe Perches WARN("SPACING", 394331070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 394431070b5dSJoe Perches } 394531070b5dSJoe Perches 394631070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 394731070b5dSJoe Perches if (defined $post_pointer_space && 394831070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 394931070b5dSJoe Perches WARN("SPACING", 395031070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 395131070b5dSJoe Perches } 395231070b5dSJoe Perches 395331070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 395431070b5dSJoe Perches if (defined $post_funcname_space && 395531070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 395631070b5dSJoe Perches WARN("SPACING", 395731070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 395831070b5dSJoe Perches } 395931070b5dSJoe Perches 396031070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 396131070b5dSJoe Perches if (defined $pre_args_space && 396231070b5dSJoe Perches $pre_args_space =~ /^\s/) { 396331070b5dSJoe Perches WARN("SPACING", 396431070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 396531070b5dSJoe Perches } 396631070b5dSJoe Perches 396731070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3968194f66fcSJoe Perches $fixed[$fixlinenr] =~ 396991f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 397031070b5dSJoe Perches } 397131070b5dSJoe Perches } 397231070b5dSJoe Perches 39738d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 39748d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3975fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3976fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 39778d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 39788d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 39798d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3980fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3981daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 39823705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 39833705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 39843705ce5bSJoe Perches $fix) { 3985194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39863705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 39873705ce5bSJoe Perches } 39888d31cfceSAndy Whitcroft } 39898d31cfceSAndy Whitcroft } 39908d31cfceSAndy Whitcroft 3991f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 39926c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 3993c2fdda0dSAndy Whitcroft my $name = $1; 3994773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 3995773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 3996c2fdda0dSAndy Whitcroft 3997c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 3998773647a0SAndy Whitcroft if ($name =~ /^(?: 3999773647a0SAndy Whitcroft if|for|while|switch|return|case| 4000773647a0SAndy Whitcroft volatile|__volatile__| 4001773647a0SAndy Whitcroft __attribute__|format|__extension__| 4002773647a0SAndy Whitcroft asm|__asm__)$/x) 4003773647a0SAndy Whitcroft { 4004c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4005c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4006c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4007c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4008773647a0SAndy Whitcroft 4009773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4010c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4011c2fdda0dSAndy Whitcroft 4012c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4013c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4014773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4015c2fdda0dSAndy Whitcroft 4016c2fdda0dSAndy Whitcroft } else { 40173705ce5bSJoe Perches if (WARN("SPACING", 40183705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40193705ce5bSJoe Perches $fix) { 4020194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40213705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 40223705ce5bSJoe Perches } 4023f0a594c1SAndy Whitcroft } 40246c72ffaaSAndy Whitcroft } 40259a4cad4eSEric Nelson 4026653d4876SAndy Whitcroft# Check operator spacing. 40270a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 40283705ce5bSJoe Perches my $fixed_line = ""; 40293705ce5bSJoe Perches my $line_fixed = 0; 40303705ce5bSJoe Perches 40319c0ca6f9SAndy Whitcroft my $ops = qr{ 40329c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 40339c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 40349c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 40351f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 403684731623SJoe Perches \?:|\?|: 40379c0ca6f9SAndy Whitcroft }x; 4038cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 40393705ce5bSJoe Perches 40403705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 40413705ce5bSJoe Perches## foreach my $el (@elements) { 40423705ce5bSJoe Perches## print("el: <$el>\n"); 40433705ce5bSJoe Perches## } 40443705ce5bSJoe Perches 40453705ce5bSJoe Perches my @fix_elements = (); 404600df344fSAndy Whitcroft my $off = 0; 40476c72ffaaSAndy Whitcroft 40483705ce5bSJoe Perches foreach my $el (@elements) { 40493705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 40503705ce5bSJoe Perches $off += length($el); 40513705ce5bSJoe Perches } 40523705ce5bSJoe Perches 40533705ce5bSJoe Perches $off = 0; 40543705ce5bSJoe Perches 40556c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4056b34c648bSJoe Perches my $last_after = -1; 40576c72ffaaSAndy Whitcroft 40580a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 40593705ce5bSJoe Perches 40603705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40613705ce5bSJoe Perches 40623705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 40633705ce5bSJoe Perches 40644a0df2efSAndy Whitcroft $off += length($elements[$n]); 40654a0df2efSAndy Whitcroft 406625985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4067773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4068773647a0SAndy Whitcroft my $cc = ''; 4069773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4070773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4071773647a0SAndy Whitcroft } 4072773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4073773647a0SAndy Whitcroft 40744a0df2efSAndy Whitcroft my $a = ''; 40754a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 40764a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4077cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 40784a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 40794a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4080773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 40814a0df2efSAndy Whitcroft 40820a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 40834a0df2efSAndy Whitcroft 40844a0df2efSAndy Whitcroft my $c = ''; 40850a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 40864a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 40874a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4088cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 40894a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 40904a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 40918b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 40924a0df2efSAndy Whitcroft } else { 40934a0df2efSAndy Whitcroft $c = 'E'; 40940a920b5bSAndy Whitcroft } 40950a920b5bSAndy Whitcroft 40964a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 40974a0df2efSAndy Whitcroft 40984a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 40994a0df2efSAndy Whitcroft 41006c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4101de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 41020a920b5bSAndy Whitcroft 410374048ed8SAndy Whitcroft # Pull out the value of this operator. 41046c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 41050a920b5bSAndy Whitcroft 41061f65f947SAndy Whitcroft # Get the full operator variant. 41071f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 41081f65f947SAndy Whitcroft 410913214adfSAndy Whitcroft # Ignore operators passed as parameters. 411013214adfSAndy Whitcroft if ($op_type ne 'V' && 4111d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 411213214adfSAndy Whitcroft 4113cf655043SAndy Whitcroft# # Ignore comments 4114cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 411513214adfSAndy Whitcroft 4116d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 411713214adfSAndy Whitcroft } elsif ($op eq ';') { 4118cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4119cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 41203705ce5bSJoe Perches if (ERROR("SPACING", 41213705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4122b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41233705ce5bSJoe Perches $line_fixed = 1; 41243705ce5bSJoe Perches } 4125d8aaf121SAndy Whitcroft } 4126d8aaf121SAndy Whitcroft 4127d8aaf121SAndy Whitcroft # // is a comment 4128d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 41290a920b5bSAndy Whitcroft 4130b00e4814SJoe Perches # : when part of a bitfield 4131b00e4814SJoe Perches } elsif ($opv eq ':B') { 4132b00e4814SJoe Perches # skip the bitfield test for now 4133b00e4814SJoe Perches 41341f65f947SAndy Whitcroft # No spaces for: 41351f65f947SAndy Whitcroft # -> 4136b00e4814SJoe Perches } elsif ($op eq '->') { 41374a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 41383705ce5bSJoe Perches if (ERROR("SPACING", 41393705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4140b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41413705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 41423705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 41433705ce5bSJoe Perches } 4144b34c648bSJoe Perches $line_fixed = 1; 41453705ce5bSJoe Perches } 41460a920b5bSAndy Whitcroft } 41470a920b5bSAndy Whitcroft 41482381097bSJoe Perches # , must not have a space before and must have a space on the right. 41490a920b5bSAndy Whitcroft } elsif ($op eq ',') { 41502381097bSJoe Perches my $rtrim_before = 0; 41512381097bSJoe Perches my $space_after = 0; 41522381097bSJoe Perches if ($ctx =~ /Wx./) { 41532381097bSJoe Perches if (ERROR("SPACING", 41542381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 41552381097bSJoe Perches $line_fixed = 1; 41562381097bSJoe Perches $rtrim_before = 1; 41572381097bSJoe Perches } 41582381097bSJoe Perches } 4159cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41603705ce5bSJoe Perches if (ERROR("SPACING", 41613705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 41623705ce5bSJoe Perches $line_fixed = 1; 4163b34c648bSJoe Perches $last_after = $n; 41642381097bSJoe Perches $space_after = 1; 41652381097bSJoe Perches } 41662381097bSJoe Perches } 41672381097bSJoe Perches if ($rtrim_before || $space_after) { 41682381097bSJoe Perches if ($rtrim_before) { 41692381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41702381097bSJoe Perches } else { 41712381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 41722381097bSJoe Perches } 41732381097bSJoe Perches if ($space_after) { 41742381097bSJoe Perches $good .= " "; 41753705ce5bSJoe Perches } 41760a920b5bSAndy Whitcroft } 41770a920b5bSAndy Whitcroft 41789c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 417974048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 41809c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 41819c0ca6f9SAndy Whitcroft 41829c0ca6f9SAndy Whitcroft # unary operators should have a space before and 41839c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 41849c0ca6f9SAndy Whitcroft # unary operator, or a cast 41859c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 418674048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 41870d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4188cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 41893705ce5bSJoe Perches if (ERROR("SPACING", 41903705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4191b34c648bSJoe Perches if ($n != $last_after + 2) { 4192b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 41933705ce5bSJoe Perches $line_fixed = 1; 41943705ce5bSJoe Perches } 41950a920b5bSAndy Whitcroft } 4196b34c648bSJoe Perches } 4197a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4198171ae1a4SAndy Whitcroft # A unary '*' may be const 4199171ae1a4SAndy Whitcroft 4200171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 42013705ce5bSJoe Perches if (ERROR("SPACING", 42023705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4203b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42043705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42053705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 42063705ce5bSJoe Perches } 4207b34c648bSJoe Perches $line_fixed = 1; 42083705ce5bSJoe Perches } 42090a920b5bSAndy Whitcroft } 42100a920b5bSAndy Whitcroft 42110a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 42120a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4213773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42143705ce5bSJoe Perches if (ERROR("SPACING", 42153705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4216b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42173705ce5bSJoe Perches $line_fixed = 1; 42183705ce5bSJoe Perches } 42190a920b5bSAndy Whitcroft } 4220773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4221773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42223705ce5bSJoe Perches if (ERROR("SPACING", 42233705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4224b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42253705ce5bSJoe Perches $line_fixed = 1; 42263705ce5bSJoe Perches } 4227653d4876SAndy Whitcroft } 4228773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 42293705ce5bSJoe Perches if (ERROR("SPACING", 42303705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4231b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42323705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42333705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4234773647a0SAndy Whitcroft } 4235b34c648bSJoe Perches $line_fixed = 1; 42363705ce5bSJoe Perches } 42373705ce5bSJoe Perches } 42380a920b5bSAndy Whitcroft 42390a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 42409c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 42419c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 42429c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4243c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4244c2fdda0dSAndy Whitcroft $op eq '%') 42450a920b5bSAndy Whitcroft { 4246d2e025f3SJoe Perches if ($check) { 4247d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4248d2e025f3SJoe Perches if (CHK("SPACING", 4249d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4250d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4251d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4252d2e025f3SJoe Perches $line_fixed = 1; 4253d2e025f3SJoe Perches } 4254d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4255d2e025f3SJoe Perches if (CHK("SPACING", 4256d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4257d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4258d2e025f3SJoe Perches $line_fixed = 1; 4259d2e025f3SJoe Perches } 4260d2e025f3SJoe Perches } 4261d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42623705ce5bSJoe Perches if (ERROR("SPACING", 42633705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4264b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4265b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4266b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4267b34c648bSJoe Perches } 42683705ce5bSJoe Perches $line_fixed = 1; 42693705ce5bSJoe Perches } 42700a920b5bSAndy Whitcroft } 42710a920b5bSAndy Whitcroft 42721f65f947SAndy Whitcroft # A colon needs no spaces before when it is 42731f65f947SAndy Whitcroft # terminating a case value or a label. 42741f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 42751f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 42763705ce5bSJoe Perches if (ERROR("SPACING", 42773705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4278b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42793705ce5bSJoe Perches $line_fixed = 1; 42803705ce5bSJoe Perches } 42811f65f947SAndy Whitcroft } 42821f65f947SAndy Whitcroft 42830a920b5bSAndy Whitcroft # All the others need spaces both sides. 4284cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 42851f65f947SAndy Whitcroft my $ok = 0; 42861f65f947SAndy Whitcroft 428722f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 42881f65f947SAndy Whitcroft if (($op eq '<' && 42891f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 42901f65f947SAndy Whitcroft ($op eq '>' && 42911f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 42921f65f947SAndy Whitcroft { 42931f65f947SAndy Whitcroft $ok = 1; 42941f65f947SAndy Whitcroft } 42951f65f947SAndy Whitcroft 4296e0df7e1fSJoe Perches # for asm volatile statements 4297e0df7e1fSJoe Perches # ignore a colon with another 4298e0df7e1fSJoe Perches # colon immediately before or after 4299e0df7e1fSJoe Perches if (($op eq ':') && 4300e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4301e0df7e1fSJoe Perches $ok = 1; 4302e0df7e1fSJoe Perches } 4303e0df7e1fSJoe Perches 430484731623SJoe Perches # messages are ERROR, but ?: are CHK 43051f65f947SAndy Whitcroft if ($ok == 0) { 430684731623SJoe Perches my $msg_type = \&ERROR; 430784731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 430884731623SJoe Perches 430984731623SJoe Perches if (&{$msg_type}("SPACING", 43103705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4311b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4312b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4313b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4314b34c648bSJoe Perches } 43153705ce5bSJoe Perches $line_fixed = 1; 43163705ce5bSJoe Perches } 43170a920b5bSAndy Whitcroft } 431822f2a2efSAndy Whitcroft } 43194a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 43203705ce5bSJoe Perches 43213705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 43223705ce5bSJoe Perches 43233705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 43240a920b5bSAndy Whitcroft } 43253705ce5bSJoe Perches 43263705ce5bSJoe Perches if (($#elements % 2) == 0) { 43273705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 43283705ce5bSJoe Perches } 43293705ce5bSJoe Perches 4330194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4331194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 43323705ce5bSJoe Perches } 43333705ce5bSJoe Perches 43343705ce5bSJoe Perches 43350a920b5bSAndy Whitcroft } 43360a920b5bSAndy Whitcroft 4337786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4338d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4339786b6326SJoe Perches if (WARN("SPACING", 4340786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4341786b6326SJoe Perches $fix) { 4342194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4343786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4344786b6326SJoe Perches } 4345786b6326SJoe Perches } 4346786b6326SJoe Perches 4347f0a594c1SAndy Whitcroft# check for multiple assignments 4348f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4349000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4350000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4351f0a594c1SAndy Whitcroft } 4352f0a594c1SAndy Whitcroft 435322f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 435422f2a2efSAndy Whitcroft## # continuation. 435522f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 435622f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 435722f2a2efSAndy Whitcroft## 435822f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 435922f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 436022f2a2efSAndy Whitcroft## my $ln = $line; 436122f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 436222f2a2efSAndy Whitcroft## } 436322f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4364000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4365000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 436622f2a2efSAndy Whitcroft## } 436722f2a2efSAndy Whitcroft## } 4368f0a594c1SAndy Whitcroft 43690a920b5bSAndy Whitcroft#need space before brace following if, while, etc 43706b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 43714e5d56bdSEddie Kovsky $line =~ /do\{/) { 43723705ce5bSJoe Perches if (ERROR("SPACING", 43733705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 43743705ce5bSJoe Perches $fix) { 4375194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; 43763705ce5bSJoe Perches } 4377de7d4f0eSAndy Whitcroft } 4378de7d4f0eSAndy Whitcroft 4379c4a62ef9SJoe Perches## # check for blank lines before declarations 4380c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4381c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4382c4a62ef9SJoe Perches## WARN("SPACING", 4383c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4384c4a62ef9SJoe Perches## } 4385c4a62ef9SJoe Perches## 4386c4a62ef9SJoe Perches 4387de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4388de7d4f0eSAndy Whitcroft# on the line 4389de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 4390d5e616fcSJoe Perches if (ERROR("SPACING", 4391d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4392d5e616fcSJoe Perches $fix) { 4393194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4394d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4395d5e616fcSJoe Perches } 43960a920b5bSAndy Whitcroft } 43970a920b5bSAndy Whitcroft 439822f2a2efSAndy Whitcroft# check spacing on square brackets 439922f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 44003705ce5bSJoe Perches if (ERROR("SPACING", 44013705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 44023705ce5bSJoe Perches $fix) { 4403194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44043705ce5bSJoe Perches s/\[\s+/\[/; 44053705ce5bSJoe Perches } 440622f2a2efSAndy Whitcroft } 440722f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 44083705ce5bSJoe Perches if (ERROR("SPACING", 44093705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 44103705ce5bSJoe Perches $fix) { 4411194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44123705ce5bSJoe Perches s/\s+\]/\]/; 44133705ce5bSJoe Perches } 441422f2a2efSAndy Whitcroft } 441522f2a2efSAndy Whitcroft 4416c45dcabdSAndy Whitcroft# check spacing on parentheses 44179c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 44189c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 44193705ce5bSJoe Perches if (ERROR("SPACING", 44203705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 44213705ce5bSJoe Perches $fix) { 4422194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44233705ce5bSJoe Perches s/\(\s+/\(/; 44243705ce5bSJoe Perches } 442522f2a2efSAndy Whitcroft } 442613214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4427c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4428c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 44293705ce5bSJoe Perches if (ERROR("SPACING", 44303705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44313705ce5bSJoe Perches $fix) { 4432194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44333705ce5bSJoe Perches s/\s+\)/\)/; 44343705ce5bSJoe Perches } 443522f2a2efSAndy Whitcroft } 443622f2a2efSAndy Whitcroft 4437e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4438e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4439e2826fd0SJoe Perches 4440e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4441ea4acbb1SJoe Perches my $var = $1; 4442ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4443ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4444ea4acbb1SJoe Perches $fix) { 4445ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4446ea4acbb1SJoe Perches } 4447ea4acbb1SJoe Perches } 4448ea4acbb1SJoe Perches 4449ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4450ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4451ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4452ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4453ea4acbb1SJoe Perches my $var = $2; 4454ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4455ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4456ea4acbb1SJoe Perches $fix) { 4457ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4458ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4459ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4460ea4acbb1SJoe Perches } 4461e2826fd0SJoe Perches } 4462e2826fd0SJoe Perches 44630a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 44644a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 44650a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 44663705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 44673705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 44683705ce5bSJoe Perches $fix) { 4469194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44703705ce5bSJoe Perches s/^(.)\s+/$1/; 44713705ce5bSJoe Perches } 44720a920b5bSAndy Whitcroft } 44730a920b5bSAndy Whitcroft 44745b9553abSJoe Perches# return is not a function 4475507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4476c45dcabdSAndy Whitcroft my $spacing = $1; 4477507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 44785b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 44795b9553abSJoe Perches my $value = $1; 44805b9553abSJoe Perches $value = deparenthesize($value); 44815b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4482000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4483000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 44845b9553abSJoe Perches } 4485c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4486000d1cc1SJoe Perches ERROR("SPACING", 4487000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4488c45dcabdSAndy Whitcroft } 4489c45dcabdSAndy Whitcroft } 4490507e5141SJoe Perches 4491b43ae21bSJoe Perches# unnecessary return in a void function 4492b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4493b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4494b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4495b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4496b43ae21bSJoe Perches $linenr >= 3 && 4497b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4498b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 44999819cf25SJoe Perches WARN("RETURN_VOID", 4500b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 45019819cf25SJoe Perches } 45029819cf25SJoe Perches 4503189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4504189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4505189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4506189248d8SJoe Perches my $openparens = $1; 4507189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4508189248d8SJoe Perches my $msg = ""; 4509189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4510189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4511189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4512189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4513189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4514189248d8SJoe Perches } 4515189248d8SJoe Perches } 4516189248d8SJoe Perches 4517c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4518c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4519c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4520c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4521c5595fa2SJoe Perches if ($^V && $^V ge 5.10.0 && 4522c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4523c5595fa2SJoe Perches my $lead = $1; 4524c5595fa2SJoe Perches my $const = $2; 4525c5595fa2SJoe Perches my $comp = $3; 4526c5595fa2SJoe Perches my $to = $4; 4527c5595fa2SJoe Perches my $newcomp = $comp; 4528f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4529c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4530c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4531c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4532c5595fa2SJoe Perches $fix) { 4533c5595fa2SJoe Perches if ($comp eq "<") { 4534c5595fa2SJoe Perches $newcomp = ">"; 4535c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4536c5595fa2SJoe Perches $newcomp = ">="; 4537c5595fa2SJoe Perches } elsif ($comp eq ">") { 4538c5595fa2SJoe Perches $newcomp = "<"; 4539c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4540c5595fa2SJoe Perches $newcomp = "<="; 4541c5595fa2SJoe Perches } 4542c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4543c5595fa2SJoe Perches } 4544c5595fa2SJoe Perches } 4545c5595fa2SJoe Perches 4546f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4547f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 454853a3c448SAndy Whitcroft my $name = $1; 454953a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4550000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4551f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 455253a3c448SAndy Whitcroft } 455353a3c448SAndy Whitcroft } 4554c45dcabdSAndy Whitcroft 45550a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 45564a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 45573705ce5bSJoe Perches if (ERROR("SPACING", 45583705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 45593705ce5bSJoe Perches $fix) { 4560194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45613705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 45623705ce5bSJoe Perches } 45630a920b5bSAndy Whitcroft } 45640a920b5bSAndy Whitcroft 4565f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4566f5fe35ddSAndy Whitcroft# statements after the conditional. 4567170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 45683e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 45693e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 45703e469cdcSAndy Whitcroft if (!defined $stat); 4571170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4572170d3a22SAndy Whitcroft $remain_next, $off_next); 4573170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4574170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4575170d3a22SAndy Whitcroft 4576170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4577170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4578170d3a22SAndy Whitcroft # then count those as offsets. 4579170d3a22SAndy Whitcroft my ($whitespace) = 4580170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4581170d3a22SAndy Whitcroft my $offset = 4582170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4583170d3a22SAndy Whitcroft 4584170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4585170d3a22SAndy Whitcroft $offset} = 1; 4586170d3a22SAndy Whitcroft } 4587170d3a22SAndy Whitcroft } 4588170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4589c11230f4SJoe Perches defined($stat) && defined($cond) && 4590170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4591171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 45928905a67cSAndy Whitcroft 4593b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4594000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4595000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 45968905a67cSAndy Whitcroft } 45978905a67cSAndy Whitcroft 45988905a67cSAndy Whitcroft # Find out what is on the end of the line after the 45998905a67cSAndy Whitcroft # conditional. 4600773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 46018905a67cSAndy Whitcroft $s =~ s/\n.*//g; 460213214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 460353210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 460453210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4605773647a0SAndy Whitcroft { 4606bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4607bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4608bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 460942bdf74cSHidetoshi Seto my $stat_real = ''; 4610bb44ad39SAndy Whitcroft 461142bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 461242bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4613bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4614bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4615bb44ad39SAndy Whitcroft } 4616bb44ad39SAndy Whitcroft 4617000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4618000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 46198905a67cSAndy Whitcroft } 46208905a67cSAndy Whitcroft } 46218905a67cSAndy Whitcroft 462213214adfSAndy Whitcroft# Check for bitwise tests written as boolean 462313214adfSAndy Whitcroft if ($line =~ / 462413214adfSAndy Whitcroft (?: 462513214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 462613214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 462713214adfSAndy Whitcroft (?:\&\&|\|\|) 462813214adfSAndy Whitcroft | 462913214adfSAndy Whitcroft (?:\&\&|\|\|) 463013214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 463113214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 463213214adfSAndy Whitcroft )/x) 463313214adfSAndy Whitcroft { 4634000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4635000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 463613214adfSAndy Whitcroft } 463713214adfSAndy Whitcroft 46388905a67cSAndy Whitcroft# if and else should not have general statements after it 463913214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 464013214adfSAndy Whitcroft my $s = $1; 464113214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 464213214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4643000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4644000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 46450a920b5bSAndy Whitcroft } 464613214adfSAndy Whitcroft } 464739667782SAndy Whitcroft# if should not continue a brace 464839667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4649000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4650048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 465139667782SAndy Whitcroft $herecurr); 465239667782SAndy Whitcroft } 4653a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4654a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4655a1080bf8SAndy Whitcroft $line !~ /\G(?: 46563fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4657a1080bf8SAndy Whitcroft \s*return\s+ 4658a1080bf8SAndy Whitcroft )/xg) 4659a1080bf8SAndy Whitcroft { 4660000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4661000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4662a1080bf8SAndy Whitcroft } 46630a920b5bSAndy Whitcroft 46640a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 46650a920b5bSAndy Whitcroft # indent level to be relevant to each other. 46668b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 46670a920b5bSAndy Whitcroft $previndent == $indent) { 46688b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 46698b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 46708b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46718b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46728b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46738b8856f4SJoe Perches my $fixedline = $prevrawline; 46748b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 46758b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46768b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46778b8856f4SJoe Perches } 46788b8856f4SJoe Perches $fixedline = $rawline; 46798b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 46808b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46818b8856f4SJoe Perches } 46820a920b5bSAndy Whitcroft } 46830a920b5bSAndy Whitcroft 46848b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4685c2fdda0dSAndy Whitcroft $previndent == $indent) { 4686c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4687c2fdda0dSAndy Whitcroft 4688c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4689c2fdda0dSAndy Whitcroft # conditional. 4690773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4691c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4692c2fdda0dSAndy Whitcroft 4693c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 46948b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 46958b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 46968b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46978b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46988b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46998b8856f4SJoe Perches my $fixedline = $prevrawline; 47008b8856f4SJoe Perches my $trailing = $rawline; 47018b8856f4SJoe Perches $trailing =~ s/^\+//; 47028b8856f4SJoe Perches $trailing = trim($trailing); 47038b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 47048b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47058b8856f4SJoe Perches } 4706c2fdda0dSAndy Whitcroft } 4707c2fdda0dSAndy Whitcroft } 4708c2fdda0dSAndy Whitcroft 470995e2c602SJoe Perches#Specific variable tests 4710323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4711323c1260SJoe Perches my $var = $1; 471295e2c602SJoe Perches 471395e2c602SJoe Perches#gcc binary extension 471495e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4715d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4716d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4717d5e616fcSJoe Perches $fix) { 4718d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4719194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4720d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4721d5e616fcSJoe Perches } 472295e2c602SJoe Perches } 472395e2c602SJoe Perches 472495e2c602SJoe Perches#CamelCase 4725807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4726be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 472722735ce8SJoe Perches#Ignore Page<foo> variants 4728807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 472922735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4730f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4731f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4732f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47337e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 47347e781f67SJoe Perches my $word = $1; 47357e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4736d8b07710SJoe Perches if ($check) { 4737d8b07710SJoe Perches seed_camelcase_includes(); 4738d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4739d8b07710SJoe Perches seed_camelcase_file($realfile); 4740d8b07710SJoe Perches $camelcase_file_seeded = 1; 4741d8b07710SJoe Perches } 4742d8b07710SJoe Perches } 47437e781f67SJoe Perches if (!defined $camelcase{$word}) { 47447e781f67SJoe Perches $camelcase{$word} = 1; 4745be79794bSJoe Perches CHK("CAMELCASE", 47467e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 47477e781f67SJoe Perches } 4748323c1260SJoe Perches } 4749323c1260SJoe Perches } 47503445686aSJoe Perches } 47510a920b5bSAndy Whitcroft 47520a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4753d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4754d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4755d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4756d5e616fcSJoe Perches $fix) { 4757194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4758d5e616fcSJoe Perches } 47590a920b5bSAndy Whitcroft } 47600a920b5bSAndy Whitcroft 47610e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47620e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4763c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4764e09dec48SAndy Whitcroft my $file = "$1.h"; 4765e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4766e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4767e09dec48SAndy Whitcroft $realfile ne $checkfile && 47687840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4769c45dcabdSAndy Whitcroft { 47700e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 47710e212e0aSFabian Frederick if ($asminclude > 0) { 4772e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4773000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4774000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4775e09dec48SAndy Whitcroft } else { 4776000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4777000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4778e09dec48SAndy Whitcroft } 47790a920b5bSAndy Whitcroft } 47800a920b5bSAndy Whitcroft } 47810e212e0aSFabian Frederick } 47820a920b5bSAndy Whitcroft 4783653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4784653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4785cf655043SAndy Whitcroft# in a known good container 4786b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4787b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4788d8aaf121SAndy Whitcroft my $ln = $linenr; 4789d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4790c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4791c45dcabdSAndy Whitcroft my $ctx = ''; 479208a2843eSJoe Perches my $has_flow_statement = 0; 479308a2843eSJoe Perches my $has_arg_concat = 0; 4794c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4795f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4796f74bd194SAndy Whitcroft $ctx = $dstat; 4797c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4798a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4799c45dcabdSAndy Whitcroft 480008a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 480162e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 480208a2843eSJoe Perches 4803f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 4804f59b64bfSJoe Perches my $define_args = $1; 4805f59b64bfSJoe Perches my $define_stmt = $dstat; 4806f59b64bfSJoe Perches my @def_args = (); 4807f59b64bfSJoe Perches 4808f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 4809f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 4810f59b64bfSJoe Perches $define_args =~ s/\s*//g; 4811f59b64bfSJoe Perches @def_args = split(",", $define_args); 4812f59b64bfSJoe Perches } 4813f59b64bfSJoe Perches 4814292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4815c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4816c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4817c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4818c45dcabdSAndy Whitcroft 4819c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4820bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4821bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 48226b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 4823bf30d6edSAndy Whitcroft { 4824c45dcabdSAndy Whitcroft } 4825c45dcabdSAndy Whitcroft 4826e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 482733acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 482833acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 4829e45bab8eSAndy Whitcroft { 4830e45bab8eSAndy Whitcroft } 4831e45bab8eSAndy Whitcroft 483242e15293SJoe Perches # Make asm volatile uses seem like a generic function 483342e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 483442e15293SJoe Perches 4835c45dcabdSAndy Whitcroft my $exceptions = qr{ 4836c45dcabdSAndy Whitcroft $Declare| 4837c45dcabdSAndy Whitcroft module_param_named| 4838a0a0a7a9SKees Cook MODULE_PARM_DESC| 4839c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4840c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4841383099fdSAndy Whitcroft __typeof__\(| 484222fd2d3eSStefani Seibold union| 484322fd2d3eSStefani Seibold struct| 4844ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 48456b10df42SVladimir Zapolskiy ^\"|\"$| 48466b10df42SVladimir Zapolskiy ^\[ 4847c45dcabdSAndy Whitcroft }x; 48485eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4849f59b64bfSJoe Perches 4850f59b64bfSJoe Perches $ctx =~ s/\n*$//; 4851f59b64bfSJoe Perches my $herectx = $here . "\n"; 4852f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 4853f59b64bfSJoe Perches 4854f59b64bfSJoe Perches for (my $n = 0; $n < $stmt_cnt; $n++) { 4855f59b64bfSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4856f59b64bfSJoe Perches } 4857f59b64bfSJoe Perches 4858f74bd194SAndy Whitcroft if ($dstat ne '' && 4859f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4860f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48613cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4862356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4863f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4864f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4865e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 486672f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4867f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4868f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4869f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 48704e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 4871f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4872c45dcabdSAndy Whitcroft { 4873e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 4874e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4875e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 4876e795556aSJoe Perches } elsif ($dstat =~ /;/) { 4877f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4878f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4879f74bd194SAndy Whitcroft } else { 4880000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4881388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4882d8aaf121SAndy Whitcroft } 4883f59b64bfSJoe Perches 4884f59b64bfSJoe Perches } 48855207649bSJoe Perches 48865207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 48875207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 48885207649bSJoe Perches my $first = 1; 48895207649bSJoe Perches $define_stmt = ""; 48905207649bSJoe Perches foreach my $l (@stmt_array) { 48915207649bSJoe Perches $l =~ s/\\$//; 48925207649bSJoe Perches if ($first) { 48935207649bSJoe Perches $define_stmt = $l; 48945207649bSJoe Perches $first = 0; 48955207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 48965207649bSJoe Perches $define_stmt .= substr($l, 1); 48975207649bSJoe Perches } 48985207649bSJoe Perches } 48995207649bSJoe Perches $define_stmt =~ s/$;//g; 49005207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 49015207649bSJoe Perches $define_stmt = trim($define_stmt); 49025207649bSJoe Perches 4903f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 4904f59b64bfSJoe Perches foreach my $arg (@def_args) { 4905f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 49069192d41aSJoe Perches next if ($arg =~ /^type$/i); 4907f59b64bfSJoe Perches my $tmp = $define_stmt; 4908f59b64bfSJoe Perches $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49095207649bSJoe Perches $tmp =~ s/\#+\s*$arg\b//g; 4910f59b64bfSJoe Perches $tmp =~ s/\b$arg\s*\#\#//g; 4911f59b64bfSJoe Perches my $use_cnt = $tmp =~ s/\b$arg\b//g; 4912f59b64bfSJoe Perches if ($use_cnt > 1) { 4913f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 4914f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 4915f59b64bfSJoe Perches } 49169192d41aSJoe Perches# check if any macro arguments may have other precedence issues 49179192d41aSJoe Perches if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49189192d41aSJoe Perches ((defined($1) && $1 ne ',') || 49199192d41aSJoe Perches (defined($2) && $2 ne ','))) { 49209192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 49219192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49229192d41aSJoe Perches } 49230a920b5bSAndy Whitcroft } 49245023d347SJoe Perches 492508a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 492608a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 492708a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 492808a2843eSJoe Perches my $herectx = $here . "\n"; 492908a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 493008a2843eSJoe Perches 493108a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 493208a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 493308a2843eSJoe Perches } 493408a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 493508a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 493608a2843eSJoe Perches } 493708a2843eSJoe Perches 4938481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 49395023d347SJoe Perches 49405023d347SJoe Perches } else { 49415023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4942481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4943481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 49445023d347SJoe Perches $line =~ /^\+.*\\$/) { 49455023d347SJoe Perches WARN("LINE_CONTINUATIONS", 49465023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 49475023d347SJoe Perches } 4948653d4876SAndy Whitcroft } 49490a920b5bSAndy Whitcroft 4950b13edf7fSJoe Perches# do {} while (0) macro tests: 4951b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4952b13edf7fSJoe Perches# macro should not end with a semicolon 4953b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4954b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4955b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4956b13edf7fSJoe Perches my $ln = $linenr; 4957b13edf7fSJoe Perches my $cnt = $realcnt; 4958b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4959b13edf7fSJoe Perches my $ctx = ''; 4960b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4961b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4962b13edf7fSJoe Perches $ctx = $dstat; 4963b13edf7fSJoe Perches 4964b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 49651b36b201SJoe Perches $dstat =~ s/$;/ /g; 4966b13edf7fSJoe Perches 4967b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4968b13edf7fSJoe Perches my $stmts = $2; 4969b13edf7fSJoe Perches my $semis = $3; 4970b13edf7fSJoe Perches 4971b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4972b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4973b13edf7fSJoe Perches my $herectx = $here . "\n"; 4974b13edf7fSJoe Perches 4975b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4976b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4977b13edf7fSJoe Perches } 4978b13edf7fSJoe Perches 4979ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4980ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4981b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4982b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4983b13edf7fSJoe Perches } 4984b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4985b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4986b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 4987b13edf7fSJoe Perches } 4988f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 4989f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 4990f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 4991f5ef95b1SJoe Perches my $herectx = $here . "\n"; 4992f5ef95b1SJoe Perches 4993f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4994f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4995f5ef95b1SJoe Perches } 4996f5ef95b1SJoe Perches 4997f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 4998f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 4999b13edf7fSJoe Perches } 5000b13edf7fSJoe Perches } 5001b13edf7fSJoe Perches 5002080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5003080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 5004080ba929SMike Frysinger# . 5005080ba929SMike Frysinger# ALIGN(...) 5006080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 5007080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5008000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 5009000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5010080ba929SMike Frysinger } 5011080ba929SMike Frysinger 5012f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 501313214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 501413214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5015cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 501613214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5017cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5018cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5019aad4f614SJoe Perches my @allowed = (); 5020aad4f614SJoe Perches my $allow = 0; 502113214adfSAndy Whitcroft my $seen = 0; 5022773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5023cf655043SAndy Whitcroft my $ln = $linenr - 1; 502413214adfSAndy Whitcroft for my $chunk (@chunks) { 502513214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 502613214adfSAndy Whitcroft 5027773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5028773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5029773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5030773647a0SAndy Whitcroft 5031aad4f614SJoe Perches $allowed[$allow] = 0; 5032773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5033773647a0SAndy Whitcroft 5034773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5035773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5036773647a0SAndy Whitcroft 5037773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5038cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5039cf655043SAndy Whitcroft 5040773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 504113214adfSAndy Whitcroft 504213214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 504313214adfSAndy Whitcroft 5044aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5045cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5046cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5047aad4f614SJoe Perches $allowed[$allow] = 1; 504813214adfSAndy Whitcroft } 504913214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5050cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5051aad4f614SJoe Perches $allowed[$allow] = 1; 505213214adfSAndy Whitcroft } 5053cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5054cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5055aad4f614SJoe Perches $allowed[$allow] = 1; 505613214adfSAndy Whitcroft } 5057aad4f614SJoe Perches $allow++; 505813214adfSAndy Whitcroft } 5059aad4f614SJoe Perches if ($seen) { 5060aad4f614SJoe Perches my $sum_allowed = 0; 5061aad4f614SJoe Perches foreach (@allowed) { 5062aad4f614SJoe Perches $sum_allowed += $_; 5063aad4f614SJoe Perches } 5064aad4f614SJoe Perches if ($sum_allowed == 0) { 5065000d1cc1SJoe Perches WARN("BRACES", 5066000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5067aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5068aad4f614SJoe Perches $seen != $allow) { 5069aad4f614SJoe Perches CHK("BRACES", 5070aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5071aad4f614SJoe Perches } 507213214adfSAndy Whitcroft } 507313214adfSAndy Whitcroft } 507413214adfSAndy Whitcroft } 5075773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 507613214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5077cf655043SAndy Whitcroft my $allowed = 0; 5078f0a594c1SAndy Whitcroft 5079cf655043SAndy Whitcroft # Check the pre-context. 5080cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5081cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5082cf655043SAndy Whitcroft $allowed = 1; 5083f0a594c1SAndy Whitcroft } 5084773647a0SAndy Whitcroft 5085773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5086773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5087773647a0SAndy Whitcroft 5088cf655043SAndy Whitcroft # Check the condition. 5089cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5090773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5091cf655043SAndy Whitcroft if (defined $cond) { 5092773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5093cf655043SAndy Whitcroft } 5094cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5095cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5096cf655043SAndy Whitcroft $allowed = 1; 5097cf655043SAndy Whitcroft } 5098cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5099cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5100cf655043SAndy Whitcroft $allowed = 1; 5101cf655043SAndy Whitcroft } 5102cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5103cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5104cf655043SAndy Whitcroft $allowed = 1; 5105cf655043SAndy Whitcroft } 5106cf655043SAndy Whitcroft # Check the post-context. 5107cf655043SAndy Whitcroft if (defined $chunks[1]) { 5108cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5109cf655043SAndy Whitcroft if (defined $cond) { 5110773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5111cf655043SAndy Whitcroft } 5112cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5113cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5114cf655043SAndy Whitcroft $allowed = 1; 5115cf655043SAndy Whitcroft } 5116cf655043SAndy Whitcroft } 5117cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 511869932487SJustin P. Mattock my $herectx = $here . "\n"; 5119f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5120cf655043SAndy Whitcroft 5121f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 512269932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 5123cf655043SAndy Whitcroft } 5124cf655043SAndy Whitcroft 5125000d1cc1SJoe Perches WARN("BRACES", 5126000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5127f0a594c1SAndy Whitcroft } 5128f0a594c1SAndy Whitcroft } 5129f0a594c1SAndy Whitcroft 5130e4c5babdSJoe Perches# check for single line unbalanced braces 513195330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 513295330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5133e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5134e4c5babdSJoe Perches } 5135e4c5babdSJoe Perches 51360979ae66SJoe Perches# check for unnecessary blank lines around braces 513777b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5138f8e58219SJoe Perches if (CHK("BRACES", 5139f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5140f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5141f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5142f8e58219SJoe Perches } 51430979ae66SJoe Perches } 514477b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5145f8e58219SJoe Perches if (CHK("BRACES", 5146f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5147f8e58219SJoe Perches $fix) { 5148f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5149f8e58219SJoe Perches } 51500979ae66SJoe Perches } 51510979ae66SJoe Perches 51524a0df2efSAndy Whitcroft# no volatiles please 51536c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 51546c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5155000d1cc1SJoe Perches WARN("VOLATILE", 51568c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51574a0df2efSAndy Whitcroft } 51584a0df2efSAndy Whitcroft 51595e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 51605e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 51615e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51625e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 516333acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 51645e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 51655e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 51665e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 51675e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 51685e4f6ba5SJoe Perches $fix && 51695e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 51705e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 51715e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 51725e4f6ba5SJoe Perches my $comma_close = ""; 51735e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 51745e4f6ba5SJoe Perches $comma_close = $1; 51755e4f6ba5SJoe Perches } 51765e4f6ba5SJoe Perches 51775e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51785e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 51795e4f6ba5SJoe Perches my $fixedline = $prevrawline; 51805e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 51815e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 51825e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 51835e4f6ba5SJoe Perches $fixedline = $rawline; 51845e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 51855e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 51865e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 51875e4f6ba5SJoe Perches } 51885e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 51895e4f6ba5SJoe Perches } 51905e4f6ba5SJoe Perches } 51915e4f6ba5SJoe Perches 51925e4f6ba5SJoe Perches# check for missing a space in a string concatenation 51935e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 51945e4f6ba5SJoe Perches WARN('MISSING_SPACE', 51955e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 51965e4f6ba5SJoe Perches } 51975e4f6ba5SJoe Perches 519877cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5199e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5200e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5201e4b7d309SJoe Perches# function declarations 520277cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 520377cb8546SJoe Perches defined($context_function) && 5204e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5205e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 520677cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5207e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 520877cb8546SJoe Perches } 520977cb8546SJoe Perches 52105e4f6ba5SJoe Perches# check for spaces before a quoted newline 52115e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 52125e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52135e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52145e4f6ba5SJoe Perches $fix) { 52155e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52165e4f6ba5SJoe Perches } 52175e4f6ba5SJoe Perches 52185e4f6ba5SJoe Perches } 52195e4f6ba5SJoe Perches 5220f17dba4fSJoe Perches# concatenated string without spaces between elements 522133acb54aSJoe Perches if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5222f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 5223f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 5224f17dba4fSJoe Perches } 5225f17dba4fSJoe Perches 522690ad30e5SJoe Perches# uncoalesced string fragments 522733acb54aSJoe Perches if ($line =~ /$String\s*"/) { 522890ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 522990ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 523090ad30e5SJoe Perches } 523190ad30e5SJoe Perches 5232522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5233522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5234522b837cSAlexey Dobriyan my $show_Z = 1; 52355e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5236522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52375e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5238522b837cSAlexey Dobriyan # check for %L 5239522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52405e4f6ba5SJoe Perches WARN("PRINTF_L", 5241522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5242522b837cSAlexey Dobriyan $show_L = 0; 52435e4f6ba5SJoe Perches } 5244522b837cSAlexey Dobriyan # check for %Z 5245522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5246522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5247522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5248522b837cSAlexey Dobriyan $show_Z = 0; 5249522b837cSAlexey Dobriyan } 5250522b837cSAlexey Dobriyan # check for 0x<decimal> 5251522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5252522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 52536e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 52546e300757SJoe Perches } 52555e4f6ba5SJoe Perches } 52565e4f6ba5SJoe Perches 52575e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 52585e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52595e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 52605e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 52615e4f6ba5SJoe Perches } 52625e4f6ba5SJoe Perches 526300df344fSAndy Whitcroft# warn about #if 0 5264c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5265000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 5266000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 5267de7d4f0eSAndy Whitcroft $herecurr); 52684a0df2efSAndy Whitcroft } 52694a0df2efSAndy Whitcroft 527003df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 527103df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5272100425deSJoe Perches my $tested = quotemeta($1); 5273100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5274100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5275100425deSJoe Perches my $func = $1; 5276100425deSJoe Perches if (WARN('NEEDLESS_IF', 5277100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5278100425deSJoe Perches $fix) { 5279100425deSJoe Perches my $do_fix = 1; 5280100425deSJoe Perches my $leading_tabs = ""; 5281100425deSJoe Perches my $new_leading_tabs = ""; 5282100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5283100425deSJoe Perches $leading_tabs = $1; 5284100425deSJoe Perches } else { 5285100425deSJoe Perches $do_fix = 0; 5286100425deSJoe Perches } 5287100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5288100425deSJoe Perches $new_leading_tabs = $1; 5289100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5290100425deSJoe Perches $do_fix = 0; 5291100425deSJoe Perches } 5292100425deSJoe Perches } else { 5293100425deSJoe Perches $do_fix = 0; 5294100425deSJoe Perches } 5295100425deSJoe Perches if ($do_fix) { 5296100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5297100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5298100425deSJoe Perches } 5299100425deSJoe Perches } 53004c432a8fSGreg Kroah-Hartman } 53014c432a8fSGreg Kroah-Hartman } 5302f0a594c1SAndy Whitcroft 5303ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5304ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5305ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5306ebfdc409SJoe Perches (defined $1 || defined $3) && 5307ebfdc409SJoe Perches $linenr > 3) { 5308ebfdc409SJoe Perches my $testval = $2; 5309ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5310ebfdc409SJoe Perches 5311ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5312ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5313ebfdc409SJoe Perches 5314*fb0d0e08SJoe 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)/) { 5315ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5316ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5317ebfdc409SJoe Perches } 5318ebfdc409SJoe Perches } 5319ebfdc409SJoe Perches 5320f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5321dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5322f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5323f78d98f6SJoe Perches my $level = $1; 5324f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5325f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5326f78d98f6SJoe Perches $fix) { 5327f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5328f78d98f6SJoe Perches } 5329f78d98f6SJoe Perches } 5330f78d98f6SJoe Perches 533145c55e92SJoe Perches# check for logging continuations 533245c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 533345c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 533445c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 533545c55e92SJoe Perches } 533645c55e92SJoe Perches 5337abb08a53SJoe Perches# check for mask then right shift without a parentheses 5338abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 5339abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5340abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5341abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5342abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5343abb08a53SJoe Perches } 5344abb08a53SJoe Perches 5345b75ac618SJoe Perches# check for pointer comparisons to NULL 5346b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 5347b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5348b75ac618SJoe Perches my $val = $1; 5349b75ac618SJoe Perches my $equal = "!"; 5350b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5351b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5352b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5353b75ac618SJoe Perches $fix) { 5354b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5355b75ac618SJoe Perches } 5356b75ac618SJoe Perches } 5357b75ac618SJoe Perches } 5358b75ac618SJoe Perches 53598716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 53608716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 53618716de38SJoe Perches my $attr = $1; 53628716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 53638716de38SJoe Perches my $ptr = $1; 53648716de38SJoe Perches my $var = $2; 53658716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 53668716de38SJoe Perches ERROR("MISPLACED_INIT", 53678716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 53688716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 53698716de38SJoe Perches WARN("MISPLACED_INIT", 53708716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 53718716de38SJoe Perches $fix) { 5372194f66fcSJoe 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; 53738716de38SJoe Perches } 53748716de38SJoe Perches } 53758716de38SJoe Perches } 53768716de38SJoe Perches 5377e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5378e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5379e970b884SJoe Perches my $attr = $1; 5380e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5381e970b884SJoe Perches my $attr_prefix = $1; 5382e970b884SJoe Perches my $attr_type = $2; 5383e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5384e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5385e970b884SJoe Perches $fix) { 5386194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5387e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5388e970b884SJoe Perches } 5389e970b884SJoe Perches } 5390e970b884SJoe Perches 5391e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5392e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5393e970b884SJoe Perches my $attr = $1; 5394e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5395e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5396e970b884SJoe Perches $fix) { 5397194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5398e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5399e970b884SJoe Perches $lead = rtrim($1); 5400e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5401e970b884SJoe Perches $lead = "${lead}const "; 5402194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5403e970b884SJoe Perches } 5404e970b884SJoe Perches } 5405e970b884SJoe Perches 5406c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5407c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5408c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5409c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5410c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5411c17893c7SJoe Perches $fix) { 5412c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5413c17893c7SJoe Perches } 5414c17893c7SJoe Perches } 5415c17893c7SJoe Perches 5416fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5417fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5418fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5419fbdb8138SJoe Perches my $constant_func = $1; 5420fbdb8138SJoe Perches my $func = $constant_func; 5421fbdb8138SJoe Perches $func =~ s/^__constant_//; 5422fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5423fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5424fbdb8138SJoe Perches $fix) { 5425194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5426fbdb8138SJoe Perches } 5427fbdb8138SJoe Perches } 5428fbdb8138SJoe Perches 54291a15a250SPatrick Pannuto# prefer usleep_range over udelay 543037581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 543143c1d77cSJoe Perches my $delay = $1; 54321a15a250SPatrick Pannuto # ignore udelay's < 10, however 543343c1d77cSJoe Perches if (! ($delay < 10) ) { 5434000d1cc1SJoe Perches CHK("USLEEP_RANGE", 543543c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 543643c1d77cSJoe Perches } 543743c1d77cSJoe Perches if ($delay > 2000) { 543843c1d77cSJoe Perches WARN("LONG_UDELAY", 543943c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 54401a15a250SPatrick Pannuto } 54411a15a250SPatrick Pannuto } 54421a15a250SPatrick Pannuto 544309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 544409ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 544509ef8725SPatrick Pannuto if ($1 < 20) { 5446000d1cc1SJoe Perches WARN("MSLEEP", 544743c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 544809ef8725SPatrick Pannuto } 544909ef8725SPatrick Pannuto } 545009ef8725SPatrick Pannuto 545136ec1939SJoe Perches# check for comparisons of jiffies 545236ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 545336ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 545436ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 545536ec1939SJoe Perches } 545636ec1939SJoe Perches 54579d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 54589d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54599d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 54609d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54619d7a34a5SJoe Perches } 54629d7a34a5SJoe Perches 546300df344fSAndy Whitcroft# warn about #ifdefs in C files 5464c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 546500df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 546600df344fSAndy Whitcroft# print "$herecurr"; 546700df344fSAndy Whitcroft# $clean = 0; 546800df344fSAndy Whitcroft# } 546900df344fSAndy Whitcroft 547022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5471c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 54723705ce5bSJoe Perches if (ERROR("SPACING", 54733705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 54743705ce5bSJoe Perches $fix) { 5475194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54763705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 54773705ce5bSJoe Perches } 54783705ce5bSJoe Perches 547922f2a2efSAndy Whitcroft } 548022f2a2efSAndy Whitcroft 54814a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5482171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5483171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 54844a0df2efSAndy Whitcroft my $which = $1; 54854a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5486000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5487000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 54884a0df2efSAndy Whitcroft } 54894a0df2efSAndy Whitcroft } 54904a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5491402c2553SMichael S. Tsirkin 5492402c2553SMichael S. Tsirkin my $barriers = qr{ 5493402c2553SMichael S. Tsirkin mb| 5494402c2553SMichael S. Tsirkin rmb| 5495402c2553SMichael S. Tsirkin wmb| 5496402c2553SMichael S. Tsirkin read_barrier_depends 5497402c2553SMichael S. Tsirkin }x; 5498402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5499402c2553SMichael S. Tsirkin mb__before_atomic| 5500402c2553SMichael S. Tsirkin mb__after_atomic| 5501402c2553SMichael S. Tsirkin store_release| 5502402c2553SMichael S. Tsirkin load_acquire| 5503402c2553SMichael S. Tsirkin store_mb| 5504402c2553SMichael S. Tsirkin (?:$barriers) 5505402c2553SMichael S. Tsirkin }x; 5506402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5507402c2553SMichael S. Tsirkin (?:$barriers)| 550843e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 550943e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5510402c2553SMichael S. Tsirkin }x; 5511402c2553SMichael S. Tsirkin 5512402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 55134a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5514c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5515000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 55164a0df2efSAndy Whitcroft } 55174a0df2efSAndy Whitcroft } 55183ad81779SPaul E. McKenney 5519f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5520f4073b0fSMichael S. Tsirkin 5521f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5522f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5523f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5524f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5525f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5526f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5527f4073b0fSMichael S. Tsirkin } 5528f4073b0fSMichael S. Tsirkin 5529cb426e99SJoe Perches# check for waitqueue_active without a comment. 5530cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5531cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5532cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5533cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5534cb426e99SJoe Perches } 5535cb426e99SJoe Perches } 55363ad81779SPaul E. McKenney 55374a0df2efSAndy Whitcroft# check of hardware specific defines 5538c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5539000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5540000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 55410a920b5bSAndy Whitcroft } 5542653d4876SAndy Whitcroft 5543d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 5544d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 5545000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5546000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 5547d4977c78STobias Klauser } 5548d4977c78STobias Klauser 5549de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5550de7d4f0eSAndy Whitcroft# storage class and type. 55519c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 55529c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5553000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5554000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5555de7d4f0eSAndy Whitcroft } 5556de7d4f0eSAndy Whitcroft 55578905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 55582b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55592b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5560d5e616fcSJoe Perches if (WARN("INLINE", 5561d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5562d5e616fcSJoe Perches $fix) { 5563194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5564d5e616fcSJoe Perches 5565d5e616fcSJoe Perches } 55668905a67cSAndy Whitcroft } 55678905a67cSAndy Whitcroft 55683d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 55692b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55702b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5571000d1cc1SJoe Perches WARN("PREFER_PACKED", 5572000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 55733d130fd0SJoe Perches } 55743d130fd0SJoe Perches 557539b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 55762b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55772b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5578000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5579000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 558039b7e287SJoe Perches } 558139b7e287SJoe Perches 55825f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 55832b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55842b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5585d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5586d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5587d5e616fcSJoe Perches $fix) { 5588194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5589d5e616fcSJoe Perches 5590d5e616fcSJoe Perches } 55915f14d3bdSJoe Perches } 55925f14d3bdSJoe Perches 55936061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 55942b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55952b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5596d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5597d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5598d5e616fcSJoe Perches $fix) { 5599194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5600d5e616fcSJoe Perches } 56016061d949SJoe Perches } 56026061d949SJoe Perches 5603619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 5604619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 5605619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5606619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5607619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5608619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5609619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5610619a908aSJoe Perches } 5611619a908aSJoe Perches 5612fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5613e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5614fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5615e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5616e6176fa4SJoe Perches my $type = $1; 5617e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5618e6176fa4SJoe Perches $type = $1; 5619e6176fa4SJoe Perches my $kernel_type = 'u'; 5620e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5621e6176fa4SJoe Perches $type =~ /(\d+)/; 5622e6176fa4SJoe Perches $kernel_type .= $1; 5623e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5624e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5625e6176fa4SJoe Perches $fix) { 5626e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5627e6176fa4SJoe Perches } 5628e6176fa4SJoe Perches } 5629e6176fa4SJoe Perches } 5630e6176fa4SJoe Perches 5631938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5632938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5633938224b5SJoe Perches my $cast = $1; 5634938224b5SJoe Perches my $const = $2; 5635938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5636938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5637938224b5SJoe Perches $fix) { 5638938224b5SJoe Perches my $suffix = ""; 5639938224b5SJoe Perches my $newconst = $const; 5640938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5641938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5642938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5643938224b5SJoe Perches $suffix .= 'LL'; 5644938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5645938224b5SJoe Perches $suffix .= 'L'; 5646938224b5SJoe Perches } 5647938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5648938224b5SJoe Perches } 5649938224b5SJoe Perches } 5650938224b5SJoe Perches 56518f53a9b8SJoe Perches# check for sizeof(&) 56528f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5653000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5654000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 56558f53a9b8SJoe Perches } 56568f53a9b8SJoe Perches 565766c80b60SJoe Perches# check for sizeof without parenthesis 565866c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5659d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5660d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5661d5e616fcSJoe Perches $fix) { 5662194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5663d5e616fcSJoe Perches } 566466c80b60SJoe Perches } 566566c80b60SJoe Perches 566688982feaSJoe Perches# check for struct spinlock declarations 566788982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 566888982feaSJoe Perches WARN("USE_SPINLOCK_T", 566988982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 567088982feaSJoe Perches } 567188982feaSJoe Perches 5672a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 567306668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5674a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5675caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5676caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5677d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5678d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5679d5e616fcSJoe Perches $fix) { 5680194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5681d5e616fcSJoe Perches } 5682a6962d72SJoe Perches } 5683a6962d72SJoe Perches } 5684a6962d72SJoe Perches 56850b523769SJoe Perches # check for vsprintf extension %p<foo> misuses 56860b523769SJoe Perches if ($^V && $^V ge 5.10.0 && 56870b523769SJoe Perches defined $stat && 56880b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 56890b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 56900b523769SJoe Perches my $bad_extension = ""; 56910b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 56920b523769SJoe Perches $lc = $lc + $linenr; 56930b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 56940b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 56950b523769SJoe Perches $fmt =~ s/%%//g; 5696ce4fecf1SPantelis Antoniou if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 56970b523769SJoe Perches $bad_extension = $1; 56980b523769SJoe Perches last; 56990b523769SJoe Perches } 57000b523769SJoe Perches } 57010b523769SJoe Perches if ($bad_extension ne "") { 57020b523769SJoe Perches my $stat_real = raw_line($linenr, 0); 57030b523769SJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 57040b523769SJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 57050b523769SJoe Perches } 57060b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 57070b523769SJoe Perches "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57080b523769SJoe Perches } 57090b523769SJoe Perches } 57100b523769SJoe Perches 5711554e165cSAndy Whitcroft# Check for misused memsets 5712d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5713d1fe9c09SJoe Perches defined $stat && 57149e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5715554e165cSAndy Whitcroft 5716d7c76ba7SJoe Perches my $ms_addr = $2; 5717d1fe9c09SJoe Perches my $ms_val = $7; 5718d1fe9c09SJoe Perches my $ms_size = $12; 5719d7c76ba7SJoe Perches 5720554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5721554e165cSAndy Whitcroft ERROR("MEMSET", 5722d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5723554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5724554e165cSAndy Whitcroft WARN("MEMSET", 5725d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5726d7c76ba7SJoe Perches } 5727d7c76ba7SJoe Perches } 5728d7c76ba7SJoe Perches 572998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5730f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5731f333195dSJoe Perches# defined $stat && 5732f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5733f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 5734f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 5735f333195dSJoe Perches# $fix) { 5736f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 5737f333195dSJoe Perches# } 5738f333195dSJoe Perches# } 573998a9bba5SJoe Perches 5740b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5741f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5742f333195dSJoe Perches# defined $stat && 5743f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5744f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 5745f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 5746f333195dSJoe Perches# } 5747b6117d17SMateusz Kulikowski 57488617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 57498617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5750f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5751f333195dSJoe Perches# defined $stat && 5752f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5753f333195dSJoe Perches# 5754f333195dSJoe Perches# my $ms_val = $7; 5755f333195dSJoe Perches# 5756f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 5757f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 5758f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 5759f333195dSJoe Perches# $fix) { 5760f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 5761f333195dSJoe Perches# } 5762f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 5763f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 5764f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 5765f333195dSJoe Perches# $fix) { 5766f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 5767f333195dSJoe Perches# } 5768f333195dSJoe Perches# } 5769f333195dSJoe Perches# } 57708617cd09SMateusz Kulikowski 5771d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5772d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5773d1fe9c09SJoe Perches defined $stat && 5774d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5775d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5776d7c76ba7SJoe Perches my $call = $1; 5777d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5778d7c76ba7SJoe Perches my $arg1 = $3; 5779d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5780d1fe9c09SJoe Perches my $arg2 = $8; 5781d7c76ba7SJoe Perches my $cast; 5782d7c76ba7SJoe Perches 5783d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5784d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5785d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5786d7c76ba7SJoe Perches $cast = $cast1; 5787d7c76ba7SJoe Perches } else { 5788d7c76ba7SJoe Perches $cast = $cast2; 5789d7c76ba7SJoe Perches } 5790d7c76ba7SJoe Perches WARN("MINMAX", 5791d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5792554e165cSAndy Whitcroft } 5793554e165cSAndy Whitcroft } 5794554e165cSAndy Whitcroft 57954a273195SJoe Perches# check usleep_range arguments 57964a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 57974a273195SJoe Perches defined $stat && 57984a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 57994a273195SJoe Perches my $min = $1; 58004a273195SJoe Perches my $max = $7; 58014a273195SJoe Perches if ($min eq $max) { 58024a273195SJoe Perches WARN("USLEEP_RANGE", 58034a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58044a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 58054a273195SJoe Perches $min > $max) { 58064a273195SJoe Perches WARN("USLEEP_RANGE", 58074a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58084a273195SJoe Perches } 58094a273195SJoe Perches } 58104a273195SJoe Perches 5811823b794cSJoe Perches# check for naked sscanf 5812823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5813823b794cSJoe Perches defined $stat && 58146c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5815823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5816823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5817823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5818823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5819823b794cSJoe Perches $lc = $lc + $linenr; 5820823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5821823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5822823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5823823b794cSJoe Perches } 5824823b794cSJoe Perches WARN("NAKED_SSCANF", 5825823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5826823b794cSJoe Perches } 5827823b794cSJoe Perches 5828afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5829afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5830afc819abSJoe Perches defined $stat && 5831afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5832afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5833afc819abSJoe Perches $lc = $lc + $linenr; 5834afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5835afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5836afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5837afc819abSJoe Perches } 5838afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5839afc819abSJoe Perches my $format = $6; 5840afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5841afc819abSJoe Perches if ($count == 1 && 5842afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5843afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5844afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5845afc819abSJoe Perches } 5846afc819abSJoe Perches } 5847afc819abSJoe Perches } 5848afc819abSJoe Perches 584970dc8a48SJoe Perches# check for new externs in .h files. 585070dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 585170dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5852d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 585370dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 585470dc8a48SJoe Perches $fix) { 5855194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 585670dc8a48SJoe Perches } 585770dc8a48SJoe Perches } 585870dc8a48SJoe Perches 5859de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5860171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5861c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5862171ae1a4SAndy Whitcroft { 5863c45dcabdSAndy Whitcroft my $function_name = $1; 5864c45dcabdSAndy Whitcroft my $paren_space = $2; 5865171ae1a4SAndy Whitcroft 5866171ae1a4SAndy Whitcroft my $s = $stat; 5867171ae1a4SAndy Whitcroft if (defined $cond) { 5868171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5869171ae1a4SAndy Whitcroft } 5870c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5871c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5872c45dcabdSAndy Whitcroft { 5873000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5874000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5875de7d4f0eSAndy Whitcroft } 5876de7d4f0eSAndy Whitcroft 5877171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5878000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5879000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5880171ae1a4SAndy Whitcroft } 58819c9ba34eSAndy Whitcroft 58829c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 58839c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 58849c9ba34eSAndy Whitcroft { 5885000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5886000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5887171ae1a4SAndy Whitcroft } 5888171ae1a4SAndy Whitcroft 5889ca0d8929SJoe Perches if ($realfile =~ /\.[ch]$/ && defined $stat && 5890ca0d8929SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 5891ca0d8929SJoe Perches $1 ne "void") { 5892ca0d8929SJoe Perches my $args = trim($1); 5893ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 5894ca0d8929SJoe Perches my $arg = trim($1); 5895ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 5896ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 5897ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 5898ca0d8929SJoe Perches } 5899ca0d8929SJoe Perches } 5900ca0d8929SJoe Perches } 5901ca0d8929SJoe Perches 5902de7d4f0eSAndy Whitcroft# checks for new __setup's 5903de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5904de7d4f0eSAndy Whitcroft my $name = $1; 5905de7d4f0eSAndy Whitcroft 5906de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5907000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 59088c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5909de7d4f0eSAndy Whitcroft } 5910653d4876SAndy Whitcroft } 59119c0ca6f9SAndy Whitcroft 59129c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5913caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5914000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5915000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 59169c0ca6f9SAndy Whitcroft } 591713214adfSAndy Whitcroft 5918a640d25cSJoe Perches# alloc style 5919a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5920a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5921a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5922a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5923a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5924a640d25cSJoe Perches } 5925a640d25cSJoe Perches 592660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 592760a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 59281b4a2ed4SJoe Perches defined $stat && 59291b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 593060a55369SJoe Perches my $oldfunc = $3; 593160a55369SJoe Perches my $a1 = $4; 593260a55369SJoe Perches my $a2 = $10; 593360a55369SJoe Perches my $newfunc = "kmalloc_array"; 593460a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 593560a55369SJoe Perches my $r1 = $a1; 593660a55369SJoe Perches my $r2 = $a2; 593760a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 593860a55369SJoe Perches $r1 = $a2; 593960a55369SJoe Perches $r2 = $a1; 594060a55369SJoe Perches } 5941e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5942e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 59431b4a2ed4SJoe Perches my $ctx = ''; 59441b4a2ed4SJoe Perches my $herectx = $here . "\n"; 59451b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 59461b4a2ed4SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 59471b4a2ed4SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 59481b4a2ed4SJoe Perches } 5949e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 59501b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 59511b4a2ed4SJoe Perches $cnt == 1 && 5952e367455aSJoe Perches $fix) { 5953194f66fcSJoe 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; 595460a55369SJoe Perches } 595560a55369SJoe Perches } 595660a55369SJoe Perches } 595760a55369SJoe Perches 5958972fdea2SJoe Perches# check for krealloc arg reuse 5959972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5960972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5961972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5962972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 5963972fdea2SJoe Perches } 5964972fdea2SJoe Perches 59655ce59ae0SJoe Perches# check for alloc argument mismatch 59665ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 59675ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 59685ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 59695ce59ae0SJoe Perches } 59705ce59ae0SJoe Perches 5971caf2a54fSJoe Perches# check for multiple semicolons 5972caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 5973d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 5974d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 5975d5e616fcSJoe Perches $fix) { 5976194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 5977d5e616fcSJoe Perches } 5978d1e2ad07SJoe Perches } 5979d1e2ad07SJoe Perches 5980cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 5981cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 5982cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 59830ab90191SJoe Perches my $ull = ""; 59840ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 59850ab90191SJoe Perches if (CHK("BIT_MACRO", 59860ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 59870ab90191SJoe Perches $fix) { 59880ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 59890ab90191SJoe Perches } 59900ab90191SJoe Perches } 59910ab90191SJoe Perches 59922d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 59932d632745SJoe 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*$/) { 59942d632745SJoe Perches my $config = $1; 59952d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 59962d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 59972d632745SJoe Perches $fix) { 59982d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 59992d632745SJoe Perches } 60002d632745SJoe Perches } 60012d632745SJoe Perches 6002e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6003c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6004c34c09a8SJoe Perches my $has_break = 0; 6005c34c09a8SJoe Perches my $has_statement = 0; 6006c34c09a8SJoe Perches my $count = 0; 6007c34c09a8SJoe Perches my $prevline = $linenr; 6008e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6009c34c09a8SJoe Perches $prevline--; 6010c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6011c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6012c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6013c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6014c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6015c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6016c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6017c34c09a8SJoe Perches $has_statement = 1; 6018c34c09a8SJoe Perches $count++; 6019c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 6020c34c09a8SJoe Perches } 6021c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6022c34c09a8SJoe Perches WARN("MISSING_BREAK", 6023224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6024c34c09a8SJoe Perches } 6025c34c09a8SJoe Perches } 6026c34c09a8SJoe Perches 6027d1e2ad07SJoe Perches# check for switch/default statements without a break; 6028d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 6029d1e2ad07SJoe Perches defined $stat && 6030d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6031d1e2ad07SJoe Perches my $ctx = ''; 6032d1e2ad07SJoe Perches my $herectx = $here . "\n"; 6033d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6034d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6035d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 6036d1e2ad07SJoe Perches } 6037d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6038d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6039caf2a54fSJoe Perches } 6040caf2a54fSJoe Perches 604113214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6042d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6043d5e616fcSJoe Perches if (WARN("USE_FUNC", 6044d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6045d5e616fcSJoe Perches $fix) { 6046194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6047d5e616fcSJoe Perches } 604813214adfSAndy Whitcroft } 6049773647a0SAndy Whitcroft 605062ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 605162ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 605262ec818fSJoe Perches ERROR("DATE_TIME", 605362ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 605462ec818fSJoe Perches } 605562ec818fSJoe Perches 60562c92488aSJoe Perches# check for use of yield() 60572c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 60582c92488aSJoe Perches WARN("YIELD", 60592c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 60602c92488aSJoe Perches } 60612c92488aSJoe Perches 6062179f8f40SJoe Perches# check for comparisons against true and false 6063179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6064179f8f40SJoe Perches my $lead = $1; 6065179f8f40SJoe Perches my $arg = $2; 6066179f8f40SJoe Perches my $test = $3; 6067179f8f40SJoe Perches my $otype = $4; 6068179f8f40SJoe Perches my $trail = $5; 6069179f8f40SJoe Perches my $op = "!"; 6070179f8f40SJoe Perches 6071179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6072179f8f40SJoe Perches 6073179f8f40SJoe Perches my $type = lc($otype); 6074179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6075179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6076179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6077179f8f40SJoe Perches $op = ""; 6078179f8f40SJoe Perches } 6079179f8f40SJoe Perches 6080179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6081179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6082179f8f40SJoe Perches 6083179f8f40SJoe Perches## maybe suggesting a correct construct would better 6084179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6085179f8f40SJoe Perches 6086179f8f40SJoe Perches } 6087179f8f40SJoe Perches } 6088179f8f40SJoe Perches 60894882720bSThomas Gleixner# check for semaphores initialized locked 60904882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6091000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6092000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6093773647a0SAndy Whitcroft } 60946712d858SJoe Perches 609567d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 609667d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6097000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 609867d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6099773647a0SAndy Whitcroft } 61006712d858SJoe Perches 6101ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6102f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6103000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6104ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6105f3db6639SMichael Ellerman } 61066712d858SJoe Perches 61070f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6108d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 61096903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6110d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6111000d1cc1SJoe Perches WARN("CONST_STRUCT", 6112d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 61132b6db5cbSAndy Whitcroft } 6114773647a0SAndy Whitcroft 6115773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6116773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6117773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6118c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6119c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6120171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6121171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6122171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6123773647a0SAndy Whitcroft { 6124000d1cc1SJoe Perches WARN("NR_CPUS", 6125000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6126773647a0SAndy Whitcroft } 61279c9ba34eSAndy Whitcroft 612852ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 612952ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 613052ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 613152ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 613252ea8506SJoe Perches } 613352ea8506SJoe Perches 6134acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6135acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 6136acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6137acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6138acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6139acd9362cSJoe Perches } 6140acd9362cSJoe Perches 6141691d77b6SAndy Whitcroft# whine mightly about in_atomic 6142691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6143691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6144000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6145000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6146f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6147000d1cc1SJoe Perches WARN("IN_ATOMIC", 6148000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6149691d77b6SAndy Whitcroft } 6150691d77b6SAndy Whitcroft } 61511704f47bSPeter Zijlstra 6152481aea5cSJoe Perches# whine about ACCESS_ONCE 6153481aea5cSJoe Perches if ($^V && $^V ge 5.10.0 && 6154481aea5cSJoe Perches $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 6155481aea5cSJoe Perches my $par = $1; 6156481aea5cSJoe Perches my $eq = $2; 6157481aea5cSJoe Perches my $fun = $3; 6158481aea5cSJoe Perches $par =~ s/^\(\s*(.*)\s*\)$/$1/; 6159481aea5cSJoe Perches if (defined($eq)) { 6160481aea5cSJoe Perches if (WARN("PREFER_WRITE_ONCE", 6161481aea5cSJoe Perches "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 6162481aea5cSJoe Perches $fix) { 6163481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 6164481aea5cSJoe Perches } 6165481aea5cSJoe Perches } else { 6166481aea5cSJoe Perches if (WARN("PREFER_READ_ONCE", 6167481aea5cSJoe Perches "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 6168481aea5cSJoe Perches $fix) { 6169481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 6170481aea5cSJoe Perches } 6171481aea5cSJoe Perches } 6172481aea5cSJoe Perches } 6173481aea5cSJoe Perches 61740f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 61750f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 61760f5225b0SPeter Zijlstra ERROR("LOCKING", 61770f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 61780f5225b0SPeter Zijlstra } 61790f5225b0SPeter Zijlstra 61801704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 61811704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 61821704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 61831704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 61841704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 61851704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6186000d1cc1SJoe Perches ERROR("LOCKDEP", 6187000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 61881704f47bSPeter Zijlstra } 61891704f47bSPeter Zijlstra } 619088f8831cSDave Jones 6191b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6192b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6193000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6194000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 619588f8831cSDave Jones } 61962435880fSJoe Perches 6197515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6198515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 6199515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 6200459cf0aeSJoe Perches defined $stat && 6201515a235eSJoe Perches $line =~ /$mode_perms_search/) { 62022435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 62032435880fSJoe Perches my $func = $entry->[0]; 62042435880fSJoe Perches my $arg_pos = $entry->[1]; 62052435880fSJoe Perches 6206459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6207459cf0aeSJoe Perches $lc = $lc + $linenr; 6208459cf0aeSJoe Perches my $stat_real = raw_line($linenr, 0); 6209459cf0aeSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 6210459cf0aeSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 6211459cf0aeSJoe Perches } 6212459cf0aeSJoe Perches 62132435880fSJoe Perches my $skip_args = ""; 62142435880fSJoe Perches if ($arg_pos > 1) { 62152435880fSJoe Perches $arg_pos--; 62162435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62172435880fSJoe Perches } 6218f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6219459cf0aeSJoe Perches if ($stat =~ /$test/) { 62202435880fSJoe Perches my $val = $1; 62212435880fSJoe Perches $val = $6 if ($skip_args ne ""); 6222f90774e1SJoe Perches if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 6223f90774e1SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4)) { 62242435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6225459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6226f90774e1SJoe Perches } 6227f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6228c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6229459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 62302435880fSJoe Perches } 6231459cf0aeSJoe Perches } 6232459cf0aeSJoe Perches } 6233459cf0aeSJoe Perches } 6234459cf0aeSJoe Perches 6235459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6236459cf0aeSJoe Perches if ($line =~ /\b$mode_perms_string_search\b/) { 6237459cf0aeSJoe Perches my $val = ""; 6238459cf0aeSJoe Perches my $oval = ""; 6239f90774e1SJoe Perches my $to = 0; 6240459cf0aeSJoe Perches my $curpos = 0; 6241459cf0aeSJoe Perches my $lastpos = 0; 6242459cf0aeSJoe Perches while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 6243459cf0aeSJoe Perches $curpos = pos($line); 6244459cf0aeSJoe Perches my $match = $2; 6245459cf0aeSJoe Perches my $omatch = $1; 6246459cf0aeSJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 6247459cf0aeSJoe Perches $lastpos = $curpos; 6248459cf0aeSJoe Perches $to |= $mode_permission_string_types{$match}; 6249459cf0aeSJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 6250459cf0aeSJoe Perches $val .= $match; 6251459cf0aeSJoe Perches $oval .= $omatch; 6252f90774e1SJoe Perches } 6253459cf0aeSJoe Perches $oval =~ s/^\s*\|\s*//; 6254459cf0aeSJoe Perches $oval =~ s/\s*\|\s*$//; 6255459cf0aeSJoe Perches my $octal = sprintf("%04o", $to); 6256f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6257459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6258f90774e1SJoe Perches $fix) { 6259459cf0aeSJoe Perches $fixed[$fixlinenr] =~ s/$val/$octal/; 62602435880fSJoe Perches } 626113214adfSAndy Whitcroft } 62625a6d20ceSBjorn Andersson 62635a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 62645a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 62655a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 62665a6d20ceSBjorn Andersson my $valid_licenses = qr{ 62675a6d20ceSBjorn Andersson GPL| 62685a6d20ceSBjorn Andersson GPL\ v2| 62695a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 62705a6d20ceSBjorn Andersson Dual\ BSD/GPL| 62715a6d20ceSBjorn Andersson Dual\ MIT/GPL| 62725a6d20ceSBjorn Andersson Dual\ MPL/GPL| 62735a6d20ceSBjorn Andersson Proprietary 62745a6d20ceSBjorn Andersson }x; 62755a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 62765a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 62775a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 62785a6d20ceSBjorn Andersson } 62795a6d20ceSBjorn Andersson } 6280515a235eSJoe Perches } 628113214adfSAndy Whitcroft 628213214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 628313214adfSAndy Whitcroft # so just keep quiet. 628413214adfSAndy Whitcroft if ($#rawlines == -1) { 628513214adfSAndy Whitcroft exit(0); 62860a920b5bSAndy Whitcroft } 62870a920b5bSAndy Whitcroft 62888905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 62898905a67cSAndy Whitcroft # things that appear to be patches. 62908905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 62918905a67cSAndy Whitcroft exit(0); 62928905a67cSAndy Whitcroft } 62938905a67cSAndy Whitcroft 62948905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 62958905a67cSAndy Whitcroft # just keep quiet. 62968905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 62978905a67cSAndy Whitcroft exit(0); 62988905a67cSAndy Whitcroft } 62998905a67cSAndy Whitcroft 630006330fc4SJoe Perches if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6301000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6302000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 63030a920b5bSAndy Whitcroft } 6304ed43c4e5SAllen Hubbe if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6305000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6306000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 63070a920b5bSAndy Whitcroft } 63080a920b5bSAndy Whitcroft 6309f0a594c1SAndy Whitcroft print report_dump(); 631013214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 631113214adfSAndy Whitcroft print "$filename " if ($summary_file); 63126c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 63136c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 63146c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 63156c72ffaaSAndy Whitcroft } 63168905a67cSAndy Whitcroft 6317d2c0a235SAndy Whitcroft if ($quiet == 0) { 6318ef212196SJoe Perches # If there were any defects found and not already fixing them 6319ef212196SJoe Perches if (!$clean and !$fix) { 6320ef212196SJoe Perches print << "EOM" 6321ef212196SJoe Perches 6322ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6323ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6324ef212196SJoe PerchesEOM 6325ef212196SJoe Perches } 6326d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6327d2c0a235SAndy Whitcroft # then suggest that. 6328d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6329b0781216SMike Frysinger $rpt_cleaners = 0; 6330d8469f16SJoe Perches print << "EOM" 6331d8469f16SJoe Perches 6332d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6333d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6334d8469f16SJoe PerchesEOM 6335d2c0a235SAndy Whitcroft } 6336d2c0a235SAndy Whitcroft } 6337d2c0a235SAndy Whitcroft 6338d752fcc8SJoe Perches if ($clean == 0 && $fix && 6339d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6340d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 63419624b8d6SJoe Perches my $newfile = $filename; 63429624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 63433705ce5bSJoe Perches my $linecount = 0; 63443705ce5bSJoe Perches my $f; 63453705ce5bSJoe Perches 6346d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6347d752fcc8SJoe Perches 63483705ce5bSJoe Perches open($f, '>', $newfile) 63493705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 63503705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 63513705ce5bSJoe Perches $linecount++; 63523705ce5bSJoe Perches if ($file) { 63533705ce5bSJoe Perches if ($linecount > 3) { 63543705ce5bSJoe Perches $fixed_line =~ s/^\+//; 63553705ce5bSJoe Perches print $f $fixed_line . "\n"; 63563705ce5bSJoe Perches } 63573705ce5bSJoe Perches } else { 63583705ce5bSJoe Perches print $f $fixed_line . "\n"; 63593705ce5bSJoe Perches } 63603705ce5bSJoe Perches } 63613705ce5bSJoe Perches close($f); 63623705ce5bSJoe Perches 63633705ce5bSJoe Perches if (!$quiet) { 63643705ce5bSJoe Perches print << "EOM"; 6365d8469f16SJoe Perches 63663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 63673705ce5bSJoe Perches 63683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 63693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 63703705ce5bSJoe Perches 63713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 63723705ce5bSJoe PerchesNo warranties, expressed or implied... 63733705ce5bSJoe PerchesEOM 63743705ce5bSJoe Perches } 63753705ce5bSJoe Perches } 63763705ce5bSJoe Perches 6377d8469f16SJoe Perches if ($quiet == 0) { 6378d8469f16SJoe Perches print "\n"; 6379d8469f16SJoe Perches if ($clean == 1) { 6380d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6381d8469f16SJoe Perches } else { 6382d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 63830a920b5bSAndy Whitcroft } 63840a920b5bSAndy Whitcroft } 63850a920b5bSAndy Whitcroft return $clean; 63860a920b5bSAndy Whitcroft} 6387