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*\(| 736fe658f94SSteffen Maier (?:$Storage\s+)?[HLP]?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\./) { 870948b133aSHeinrich Schuchardt $id = undef; 871d311cd44SJoe Perches } else { 872d311cd44SJoe Perches $id = substr($lines[0], 0, 12); 873d311cd44SJoe Perches $desc = substr($lines[0], 41); 874d311cd44SJoe Perches } 875d311cd44SJoe Perches 876d311cd44SJoe Perches return ($id, $desc); 877d311cd44SJoe Perches} 878d311cd44SJoe Perches 8796c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 8800a920b5bSAndy Whitcroft 88100df344fSAndy Whitcroftmy @rawlines = (); 882c2fdda0dSAndy Whitcroftmy @lines = (); 8833705ce5bSJoe Perchesmy @fixed = (); 884d752fcc8SJoe Perchesmy @fixed_inserted = (); 885d752fcc8SJoe Perchesmy @fixed_deleted = (); 886194f66fcSJoe Perchesmy $fixlinenr = -1; 887194f66fcSJoe Perches 8884a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions. 8894a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. 8904a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git"); 8914a593c34SDu, Changbin 8924a593c34SDu, Changbinif ($git) { 8934a593c34SDu, Changbin my @commits = (); 8940dea9f1eSJoe Perches foreach my $commit_expr (@ARGV) { 8954a593c34SDu, Changbin my $git_range; 89628898fd1SJoe Perches if ($commit_expr =~ m/^(.*)-(\d+)$/) { 89728898fd1SJoe Perches $git_range = "-$2 $1"; 8984a593c34SDu, Changbin } elsif ($commit_expr =~ m/\.\./) { 8994a593c34SDu, Changbin $git_range = "$commit_expr"; 9004a593c34SDu, Changbin } else { 9010dea9f1eSJoe Perches $git_range = "-1 $commit_expr"; 9020dea9f1eSJoe Perches } 9030dea9f1eSJoe Perches my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; 9040dea9f1eSJoe Perches foreach my $line (split(/\n/, $lines)) { 90528898fd1SJoe Perches $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; 90628898fd1SJoe Perches next if (!defined($1) || !defined($2)); 9070dea9f1eSJoe Perches my $sha1 = $1; 9080dea9f1eSJoe Perches my $subject = $2; 9090dea9f1eSJoe Perches unshift(@commits, $sha1); 9100dea9f1eSJoe Perches $git_commits{$sha1} = $subject; 9114a593c34SDu, Changbin } 9124a593c34SDu, Changbin } 9134a593c34SDu, Changbin die "$P: no git commits after extraction!\n" if (@commits == 0); 9144a593c34SDu, Changbin @ARGV = @commits; 9154a593c34SDu, Changbin} 9164a593c34SDu, Changbin 917c2fdda0dSAndy Whitcroftmy $vname; 9186c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 91921caa13cSAndy Whitcroft my $FILE; 9204a593c34SDu, Changbin if ($git) { 9214a593c34SDu, Changbin open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || 9224a593c34SDu, Changbin die "$P: $filename: git format-patch failed - $!\n"; 9234a593c34SDu, Changbin } elsif ($file) { 92421caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 9256c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 92621caa13cSAndy Whitcroft } elsif ($filename eq '-') { 92721caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 9286c72ffaaSAndy Whitcroft } else { 92921caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 9306c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 9316c72ffaaSAndy Whitcroft } 932c2fdda0dSAndy Whitcroft if ($filename eq '-') { 933c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 9344a593c34SDu, Changbin } elsif ($git) { 9350dea9f1eSJoe Perches $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; 936c2fdda0dSAndy Whitcroft } else { 937c2fdda0dSAndy Whitcroft $vname = $filename; 938c2fdda0dSAndy Whitcroft } 93921caa13cSAndy Whitcroft while (<$FILE>) { 9400a920b5bSAndy Whitcroft chomp; 94100df344fSAndy Whitcroft push(@rawlines, $_); 9426c72ffaaSAndy Whitcroft } 94321caa13cSAndy Whitcroft close($FILE); 944d8469f16SJoe Perches 945d8469f16SJoe Perches if ($#ARGV > 0 && $quiet == 0) { 946d8469f16SJoe Perches print '-' x length($vname) . "\n"; 947d8469f16SJoe Perches print "$vname\n"; 948d8469f16SJoe Perches print '-' x length($vname) . "\n"; 949d8469f16SJoe Perches } 950d8469f16SJoe Perches 951c2fdda0dSAndy Whitcroft if (!process($filename)) { 9520a920b5bSAndy Whitcroft $exit = 1; 9530a920b5bSAndy Whitcroft } 95400df344fSAndy Whitcroft @rawlines = (); 95513214adfSAndy Whitcroft @lines = (); 9563705ce5bSJoe Perches @fixed = (); 957d752fcc8SJoe Perches @fixed_inserted = (); 958d752fcc8SJoe Perches @fixed_deleted = (); 959194f66fcSJoe Perches $fixlinenr = -1; 960485ff23eSAlex Dowad @modifierListFile = (); 961485ff23eSAlex Dowad @typeListFile = (); 962485ff23eSAlex Dowad build_types(); 9630a920b5bSAndy Whitcroft} 9640a920b5bSAndy Whitcroft 965d8469f16SJoe Perchesif (!$quiet) { 9663c816e49SJoe Perches hash_show_words(\%use_type, "Used"); 9673c816e49SJoe Perches hash_show_words(\%ignore_type, "Ignored"); 9683c816e49SJoe Perches 969d8469f16SJoe Perches if ($^V lt 5.10.0) { 970d8469f16SJoe Perches print << "EOM" 971d8469f16SJoe Perches 972d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues. 973d8469f16SJoe Perches An upgrade to at least perl v5.10.0 is suggested. 974d8469f16SJoe PerchesEOM 975d8469f16SJoe Perches } 976d8469f16SJoe Perches if ($exit) { 977d8469f16SJoe Perches print << "EOM" 978d8469f16SJoe Perches 979d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report 980d8469f16SJoe Perches them to the maintainer, see CHECKPATCH in MAINTAINERS. 981d8469f16SJoe PerchesEOM 982d8469f16SJoe Perches } 983d8469f16SJoe Perches} 984d8469f16SJoe Perches 9850a920b5bSAndy Whitcroftexit($exit); 9860a920b5bSAndy Whitcroft 9870a920b5bSAndy Whitcroftsub top_of_kernel_tree { 9886c72ffaaSAndy Whitcroft my ($root) = @_; 9896c72ffaaSAndy Whitcroft 9906c72ffaaSAndy Whitcroft my @tree_check = ( 9916c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 9926c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 9936c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 9946c72ffaaSAndy Whitcroft ); 9956c72ffaaSAndy Whitcroft 9966c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 9976c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 9980a920b5bSAndy Whitcroft return 0; 9990a920b5bSAndy Whitcroft } 10006c72ffaaSAndy Whitcroft } 10016c72ffaaSAndy Whitcroft return 1; 10026c72ffaaSAndy Whitcroft} 10030a920b5bSAndy Whitcroft 100420112475SJoe Perchessub parse_email { 100520112475SJoe Perches my ($formatted_email) = @_; 100620112475SJoe Perches 100720112475SJoe Perches my $name = ""; 100820112475SJoe Perches my $address = ""; 100920112475SJoe Perches my $comment = ""; 101020112475SJoe Perches 101120112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 101220112475SJoe Perches $name = $1; 101320112475SJoe Perches $address = $2; 101420112475SJoe Perches $comment = $3 if defined $3; 101520112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 101620112475SJoe Perches $address = $1; 101720112475SJoe Perches $comment = $2 if defined $2; 101820112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 101920112475SJoe Perches $address = $1; 102020112475SJoe Perches $comment = $2 if defined $2; 102120112475SJoe Perches $formatted_email =~ s/$address.*$//; 102220112475SJoe Perches $name = $formatted_email; 10233705ce5bSJoe Perches $name = trim($name); 102420112475SJoe Perches $name =~ s/^\"|\"$//g; 102520112475SJoe Perches # If there's a name left after stripping spaces and 102620112475SJoe Perches # leading quotes, and the address doesn't have both 102720112475SJoe Perches # leading and trailing angle brackets, the address 102820112475SJoe Perches # is invalid. ie: 102920112475SJoe Perches # "joe smith [email protected]" bad 103020112475SJoe Perches # "joe smith <[email protected]" bad 103120112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 103220112475SJoe Perches $name = ""; 103320112475SJoe Perches $address = ""; 103420112475SJoe Perches $comment = ""; 103520112475SJoe Perches } 103620112475SJoe Perches } 103720112475SJoe Perches 10383705ce5bSJoe Perches $name = trim($name); 103920112475SJoe Perches $name =~ s/^\"|\"$//g; 10403705ce5bSJoe Perches $address = trim($address); 104120112475SJoe Perches $address =~ s/^\<|\>$//g; 104220112475SJoe Perches 104320112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 104420112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 104520112475SJoe Perches $name = "\"$name\""; 104620112475SJoe Perches } 104720112475SJoe Perches 104820112475SJoe Perches return ($name, $address, $comment); 104920112475SJoe Perches} 105020112475SJoe Perches 105120112475SJoe Perchessub format_email { 105220112475SJoe Perches my ($name, $address) = @_; 105320112475SJoe Perches 105420112475SJoe Perches my $formatted_email; 105520112475SJoe Perches 10563705ce5bSJoe Perches $name = trim($name); 105720112475SJoe Perches $name =~ s/^\"|\"$//g; 10583705ce5bSJoe Perches $address = trim($address); 105920112475SJoe Perches 106020112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 106120112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 106220112475SJoe Perches $name = "\"$name\""; 106320112475SJoe Perches } 106420112475SJoe Perches 106520112475SJoe Perches if ("$name" eq "") { 106620112475SJoe Perches $formatted_email = "$address"; 106720112475SJoe Perches } else { 106820112475SJoe Perches $formatted_email = "$name <$address>"; 106920112475SJoe Perches } 107020112475SJoe Perches 107120112475SJoe Perches return $formatted_email; 107220112475SJoe Perches} 107320112475SJoe Perches 1074d311cd44SJoe Perchessub which { 1075d311cd44SJoe Perches my ($bin) = @_; 1076d311cd44SJoe Perches 1077d311cd44SJoe Perches foreach my $path (split(/:/, $ENV{PATH})) { 1078d311cd44SJoe Perches if (-e "$path/$bin") { 1079d311cd44SJoe Perches return "$path/$bin"; 1080d311cd44SJoe Perches } 1081d311cd44SJoe Perches } 1082d311cd44SJoe Perches 1083d311cd44SJoe Perches return ""; 1084d311cd44SJoe Perches} 1085d311cd44SJoe Perches 1086000d1cc1SJoe Perchessub which_conf { 1087000d1cc1SJoe Perches my ($conf) = @_; 1088000d1cc1SJoe Perches 1089000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 1090000d1cc1SJoe Perches if (-e "$path/$conf") { 1091000d1cc1SJoe Perches return "$path/$conf"; 1092000d1cc1SJoe Perches } 1093000d1cc1SJoe Perches } 1094000d1cc1SJoe Perches 1095000d1cc1SJoe Perches return ""; 1096000d1cc1SJoe Perches} 1097000d1cc1SJoe Perches 10980a920b5bSAndy Whitcroftsub expand_tabs { 10990a920b5bSAndy Whitcroft my ($str) = @_; 11000a920b5bSAndy Whitcroft 11010a920b5bSAndy Whitcroft my $res = ''; 11020a920b5bSAndy Whitcroft my $n = 0; 11030a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 11040a920b5bSAndy Whitcroft if ($c eq "\t") { 11050a920b5bSAndy Whitcroft $res .= ' '; 11060a920b5bSAndy Whitcroft $n++; 11070a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 11080a920b5bSAndy Whitcroft $res .= ' '; 11090a920b5bSAndy Whitcroft } 11100a920b5bSAndy Whitcroft next; 11110a920b5bSAndy Whitcroft } 11120a920b5bSAndy Whitcroft $res .= $c; 11130a920b5bSAndy Whitcroft $n++; 11140a920b5bSAndy Whitcroft } 11150a920b5bSAndy Whitcroft 11160a920b5bSAndy Whitcroft return $res; 11170a920b5bSAndy Whitcroft} 11186c72ffaaSAndy Whitcroftsub copy_spacing { 1119773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 11206c72ffaaSAndy Whitcroft return $res; 11216c72ffaaSAndy Whitcroft} 11220a920b5bSAndy Whitcroft 11234a0df2efSAndy Whitcroftsub line_stats { 11244a0df2efSAndy Whitcroft my ($line) = @_; 11254a0df2efSAndy Whitcroft 11264a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 11274a0df2efSAndy Whitcroft $line =~ s/^.//; 11284a0df2efSAndy Whitcroft $line = expand_tabs($line); 11294a0df2efSAndy Whitcroft 11304a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 11314a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 11324a0df2efSAndy Whitcroft 11334a0df2efSAndy Whitcroft return (length($line), length($white)); 11344a0df2efSAndy Whitcroft} 11354a0df2efSAndy Whitcroft 1136773647a0SAndy Whitcroftmy $sanitise_quote = ''; 1137773647a0SAndy Whitcroft 1138773647a0SAndy Whitcroftsub sanitise_line_reset { 1139773647a0SAndy Whitcroft my ($in_comment) = @_; 1140773647a0SAndy Whitcroft 1141773647a0SAndy Whitcroft if ($in_comment) { 1142773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1143773647a0SAndy Whitcroft } else { 1144773647a0SAndy Whitcroft $sanitise_quote = ''; 1145773647a0SAndy Whitcroft } 1146773647a0SAndy Whitcroft} 114700df344fSAndy Whitcroftsub sanitise_line { 114800df344fSAndy Whitcroft my ($line) = @_; 114900df344fSAndy Whitcroft 115000df344fSAndy Whitcroft my $res = ''; 115100df344fSAndy Whitcroft my $l = ''; 115200df344fSAndy Whitcroft 1153c2fdda0dSAndy Whitcroft my $qlen = 0; 1154773647a0SAndy Whitcroft my $off = 0; 1155773647a0SAndy Whitcroft my $c; 115600df344fSAndy Whitcroft 1157773647a0SAndy Whitcroft # Always copy over the diff marker. 1158773647a0SAndy Whitcroft $res = substr($line, 0, 1); 1159773647a0SAndy Whitcroft 1160773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 1161773647a0SAndy Whitcroft $c = substr($line, $off, 1); 1162773647a0SAndy Whitcroft 1163773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 1164773647a0SAndy Whitcroft # and end, all to $;. 1165773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 1166773647a0SAndy Whitcroft $sanitise_quote = '*/'; 1167773647a0SAndy Whitcroft 1168773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1169773647a0SAndy Whitcroft $off++; 117000df344fSAndy Whitcroft next; 1171773647a0SAndy Whitcroft } 117281bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 1173773647a0SAndy Whitcroft $sanitise_quote = ''; 1174773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 1175773647a0SAndy Whitcroft $off++; 1176773647a0SAndy Whitcroft next; 1177773647a0SAndy Whitcroft } 1178113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 1179113f04a8SDaniel Walker $sanitise_quote = '//'; 1180113f04a8SDaniel Walker 1181113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 1182113f04a8SDaniel Walker $off++; 1183113f04a8SDaniel Walker next; 1184113f04a8SDaniel Walker } 1185773647a0SAndy Whitcroft 1186773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 1187773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 1188773647a0SAndy Whitcroft $c eq "\\") { 1189773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 1190773647a0SAndy Whitcroft $off++; 1191773647a0SAndy Whitcroft next; 1192773647a0SAndy Whitcroft } 1193773647a0SAndy Whitcroft # Regular quotes. 1194773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 1195773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 1196773647a0SAndy Whitcroft $sanitise_quote = $c; 1197773647a0SAndy Whitcroft 1198773647a0SAndy Whitcroft substr($res, $off, 1, $c); 1199773647a0SAndy Whitcroft next; 1200773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 1201773647a0SAndy Whitcroft $sanitise_quote = ''; 120200df344fSAndy Whitcroft } 120300df344fSAndy Whitcroft } 1204773647a0SAndy Whitcroft 1205fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 1206773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 1207773647a0SAndy Whitcroft substr($res, $off, 1, $;); 1208113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 1209113f04a8SDaniel Walker substr($res, $off, 1, $;); 1210773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 1211773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 121200df344fSAndy Whitcroft } else { 1213773647a0SAndy Whitcroft substr($res, $off, 1, $c); 121400df344fSAndy Whitcroft } 1215c2fdda0dSAndy Whitcroft } 1216c2fdda0dSAndy Whitcroft 1217113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 1218113f04a8SDaniel Walker $sanitise_quote = ''; 1219113f04a8SDaniel Walker } 1220113f04a8SDaniel Walker 1221c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 1222c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 1223c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1224c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 1225c2fdda0dSAndy Whitcroft 1226c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 1227c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 1228c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 1229c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 1230c2fdda0dSAndy Whitcroft } 1231c2fdda0dSAndy Whitcroft 1232dadf680dSJoe Perches if ($allow_c99_comments && $res =~ m@(//.*$)@) { 1233dadf680dSJoe Perches my $match = $1; 1234dadf680dSJoe Perches $res =~ s/\Q$match\E/"$;" x length($match)/e; 1235dadf680dSJoe Perches } 1236dadf680dSJoe Perches 123700df344fSAndy Whitcroft return $res; 123800df344fSAndy Whitcroft} 123900df344fSAndy Whitcroft 1240a6962d72SJoe Perchessub get_quoted_string { 1241a6962d72SJoe Perches my ($line, $rawline) = @_; 1242a6962d72SJoe Perches 124333acb54aSJoe Perches return "" if ($line !~ m/($String)/g); 1244a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 1245a6962d72SJoe Perches} 1246a6962d72SJoe Perches 12478905a67cSAndy Whitcroftsub ctx_statement_block { 12488905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 12498905a67cSAndy Whitcroft my $line = $linenr - 1; 12508905a67cSAndy Whitcroft my $blk = ''; 12518905a67cSAndy Whitcroft my $soff = $off; 12528905a67cSAndy Whitcroft my $coff = $off - 1; 1253773647a0SAndy Whitcroft my $coff_set = 0; 12548905a67cSAndy Whitcroft 125513214adfSAndy Whitcroft my $loff = 0; 125613214adfSAndy Whitcroft 12578905a67cSAndy Whitcroft my $type = ''; 12588905a67cSAndy Whitcroft my $level = 0; 1259a2750645SAndy Whitcroft my @stack = (); 1260cf655043SAndy Whitcroft my $p; 12618905a67cSAndy Whitcroft my $c; 12628905a67cSAndy Whitcroft my $len = 0; 126313214adfSAndy Whitcroft 126413214adfSAndy Whitcroft my $remainder; 12658905a67cSAndy Whitcroft while (1) { 1266a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 1267a2750645SAndy Whitcroft 1268773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 12698905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 12708905a67cSAndy Whitcroft # context. 12718905a67cSAndy Whitcroft if ($off >= $len) { 12728905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 1273dea33496SAndy Whitcroft last if (!defined $lines[$line]); 1274c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 12758905a67cSAndy Whitcroft $remain--; 127613214adfSAndy Whitcroft $loff = $len; 1277c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 12788905a67cSAndy Whitcroft $len = length($blk); 12798905a67cSAndy Whitcroft $line++; 12808905a67cSAndy Whitcroft last; 12818905a67cSAndy Whitcroft } 12828905a67cSAndy Whitcroft # Bail if there is no further context. 12838905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 128413214adfSAndy Whitcroft if ($off >= $len) { 12858905a67cSAndy Whitcroft last; 12868905a67cSAndy Whitcroft } 1287f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 1288f74bd194SAndy Whitcroft $level++; 1289f74bd194SAndy Whitcroft $type = '#'; 1290f74bd194SAndy Whitcroft } 12918905a67cSAndy Whitcroft } 1292cf655043SAndy Whitcroft $p = $c; 12938905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 129413214adfSAndy Whitcroft $remainder = substr($blk, $off); 12958905a67cSAndy Whitcroft 1296773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 12974635f4fbSAndy Whitcroft 12984635f4fbSAndy Whitcroft # Handle nested #if/#else. 12994635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 13004635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 13014635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 13024635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 13034635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 13044635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 13054635f4fbSAndy Whitcroft } 13064635f4fbSAndy Whitcroft 13078905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 13088905a67cSAndy Whitcroft # outermost level. 13098905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 13108905a67cSAndy Whitcroft last; 13118905a67cSAndy Whitcroft } 13128905a67cSAndy Whitcroft 131313214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 1314773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 1315773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 1316773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 1317773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 1318773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 1319773647a0SAndy Whitcroft $coff_set = 1; 1320773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 1321773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 132213214adfSAndy Whitcroft } 132313214adfSAndy Whitcroft 13248905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 13258905a67cSAndy Whitcroft $level++; 13268905a67cSAndy Whitcroft $type = '('; 13278905a67cSAndy Whitcroft } 13288905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 13298905a67cSAndy Whitcroft $level--; 13308905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 13318905a67cSAndy Whitcroft 13328905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 13338905a67cSAndy Whitcroft $coff = $off; 1334773647a0SAndy Whitcroft $coff_set = 1; 1335773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 13368905a67cSAndy Whitcroft } 13378905a67cSAndy Whitcroft } 13388905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 13398905a67cSAndy Whitcroft $level++; 13408905a67cSAndy Whitcroft $type = '{'; 13418905a67cSAndy Whitcroft } 13428905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 13438905a67cSAndy Whitcroft $level--; 13448905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 13458905a67cSAndy Whitcroft 13468905a67cSAndy Whitcroft if ($level == 0) { 1347b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 1348b998e001SPatrick Pannuto $off++; 1349b998e001SPatrick Pannuto } 13508905a67cSAndy Whitcroft last; 13518905a67cSAndy Whitcroft } 13528905a67cSAndy Whitcroft } 1353f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 1354f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 1355f74bd194SAndy Whitcroft $level--; 1356f74bd194SAndy Whitcroft $type = ''; 1357f74bd194SAndy Whitcroft $off++; 1358f74bd194SAndy Whitcroft last; 1359f74bd194SAndy Whitcroft } 13608905a67cSAndy Whitcroft $off++; 13618905a67cSAndy Whitcroft } 1362a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 136313214adfSAndy Whitcroft if ($off == $len) { 1364a3bb97a7SAndy Whitcroft $loff = $len + 1; 136513214adfSAndy Whitcroft $line++; 136613214adfSAndy Whitcroft $remain--; 136713214adfSAndy Whitcroft } 13688905a67cSAndy Whitcroft 13698905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 13708905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 13718905a67cSAndy Whitcroft 13728905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 13738905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 13748905a67cSAndy Whitcroft 1375773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 137613214adfSAndy Whitcroft 137713214adfSAndy Whitcroft return ($statement, $condition, 137813214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 137913214adfSAndy Whitcroft} 138013214adfSAndy Whitcroft 1381cf655043SAndy Whitcroftsub statement_lines { 1382cf655043SAndy Whitcroft my ($stmt) = @_; 1383cf655043SAndy Whitcroft 1384cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 1385cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1386cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1387cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1388cf655043SAndy Whitcroft 1389cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1390cf655043SAndy Whitcroft 1391cf655043SAndy Whitcroft return $#stmt_lines + 2; 1392cf655043SAndy Whitcroft} 1393cf655043SAndy Whitcroft 1394cf655043SAndy Whitcroftsub statement_rawlines { 1395cf655043SAndy Whitcroft my ($stmt) = @_; 1396cf655043SAndy Whitcroft 1397cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1398cf655043SAndy Whitcroft 1399cf655043SAndy Whitcroft return $#stmt_lines + 2; 1400cf655043SAndy Whitcroft} 1401cf655043SAndy Whitcroft 1402cf655043SAndy Whitcroftsub statement_block_size { 1403cf655043SAndy Whitcroft my ($stmt) = @_; 1404cf655043SAndy Whitcroft 1405cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 1406cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 1407cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 1408cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 1409cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 1410cf655043SAndy Whitcroft 1411cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 1412cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 1413cf655043SAndy Whitcroft 1414cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 1415cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 1416cf655043SAndy Whitcroft 1417cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 1418cf655043SAndy Whitcroft return $stmt_lines; 1419cf655043SAndy Whitcroft } else { 1420cf655043SAndy Whitcroft return $stmt_statements; 1421cf655043SAndy Whitcroft } 1422cf655043SAndy Whitcroft} 1423cf655043SAndy Whitcroft 142413214adfSAndy Whitcroftsub ctx_statement_full { 142513214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 142613214adfSAndy Whitcroft my ($statement, $condition, $level); 142713214adfSAndy Whitcroft 142813214adfSAndy Whitcroft my (@chunks); 142913214adfSAndy Whitcroft 1430cf655043SAndy Whitcroft # Grab the first conditional/block pair. 143113214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 143213214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1433773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 143413214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 1435cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 1436cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 1437cf655043SAndy Whitcroft } 1438cf655043SAndy Whitcroft 1439cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 1440cf655043SAndy Whitcroft # could continue the statement. 1441cf655043SAndy Whitcroft for (;;) { 144213214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 144313214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 1444cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 1445773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 1446cf655043SAndy Whitcroft #print "C: push\n"; 1447cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 144813214adfSAndy Whitcroft } 144913214adfSAndy Whitcroft 145013214adfSAndy Whitcroft return ($level, $linenr, @chunks); 14518905a67cSAndy Whitcroft} 14528905a67cSAndy Whitcroft 14534a0df2efSAndy Whitcroftsub ctx_block_get { 1454f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 14554a0df2efSAndy Whitcroft my $line; 14564a0df2efSAndy Whitcroft my $start = $linenr - 1; 14574a0df2efSAndy Whitcroft my $blk = ''; 14584a0df2efSAndy Whitcroft my @o; 14594a0df2efSAndy Whitcroft my @c; 14604a0df2efSAndy Whitcroft my @res = (); 14614a0df2efSAndy Whitcroft 1462f0a594c1SAndy Whitcroft my $level = 0; 14634635f4fbSAndy Whitcroft my @stack = ($level); 146400df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 146500df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 146600df344fSAndy Whitcroft $remain--; 146700df344fSAndy Whitcroft 146800df344fSAndy Whitcroft $blk .= $rawlines[$line]; 14694635f4fbSAndy Whitcroft 14704635f4fbSAndy Whitcroft # Handle nested #if/#else. 147101464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 14724635f4fbSAndy Whitcroft push(@stack, $level); 147301464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 14744635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 147501464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 14764635f4fbSAndy Whitcroft $level = pop(@stack); 14774635f4fbSAndy Whitcroft } 14784635f4fbSAndy Whitcroft 147901464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 1480f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 1481f0a594c1SAndy Whitcroft if ($off > 0) { 1482f0a594c1SAndy Whitcroft $off--; 1483f0a594c1SAndy Whitcroft next; 1484f0a594c1SAndy Whitcroft } 14854a0df2efSAndy Whitcroft 1486f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 1487f0a594c1SAndy Whitcroft $level--; 1488f0a594c1SAndy Whitcroft last if ($level == 0); 1489f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 1490f0a594c1SAndy Whitcroft $level++; 1491f0a594c1SAndy Whitcroft } 1492f0a594c1SAndy Whitcroft } 14934a0df2efSAndy Whitcroft 1494f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 149500df344fSAndy Whitcroft push(@res, $rawlines[$line]); 14964a0df2efSAndy Whitcroft } 14974a0df2efSAndy Whitcroft 1498f0a594c1SAndy Whitcroft last if ($level == 0); 14994a0df2efSAndy Whitcroft } 15004a0df2efSAndy Whitcroft 1501f0a594c1SAndy Whitcroft return ($level, @res); 15024a0df2efSAndy Whitcroft} 15034a0df2efSAndy Whitcroftsub ctx_block_outer { 15044a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15054a0df2efSAndy Whitcroft 1506f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 1507f0a594c1SAndy Whitcroft return @r; 15084a0df2efSAndy Whitcroft} 15094a0df2efSAndy Whitcroftsub ctx_block { 15104a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 15114a0df2efSAndy Whitcroft 1512f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 1513f0a594c1SAndy Whitcroft return @r; 1514653d4876SAndy Whitcroft} 1515653d4876SAndy Whitcroftsub ctx_statement { 1516f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 1517f0a594c1SAndy Whitcroft 1518f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 1519f0a594c1SAndy Whitcroft return @r; 1520f0a594c1SAndy Whitcroft} 1521f0a594c1SAndy Whitcroftsub ctx_block_level { 1522653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 1523653d4876SAndy Whitcroft 1524f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 15254a0df2efSAndy Whitcroft} 15269c0ca6f9SAndy Whitcroftsub ctx_statement_level { 15279c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 15289c0ca6f9SAndy Whitcroft 15299c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 15309c0ca6f9SAndy Whitcroft} 15314a0df2efSAndy Whitcroft 15324a0df2efSAndy Whitcroftsub ctx_locate_comment { 15334a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15344a0df2efSAndy Whitcroft 15354a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 1536beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 15374a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 15384a0df2efSAndy Whitcroft 15394a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 15404a0df2efSAndy Whitcroft # comment. 15414a0df2efSAndy Whitcroft my $in_comment = 0; 15424a0df2efSAndy Whitcroft $current_comment = ''; 15434a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 154400df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 154500df344fSAndy Whitcroft #warn " $line\n"; 15464a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 15474a0df2efSAndy Whitcroft $in_comment = 1; 15484a0df2efSAndy Whitcroft } 15494a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 15504a0df2efSAndy Whitcroft $in_comment = 1; 15514a0df2efSAndy Whitcroft } 15524a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 15534a0df2efSAndy Whitcroft $current_comment = ''; 15544a0df2efSAndy Whitcroft } 15554a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 15564a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 15574a0df2efSAndy Whitcroft $in_comment = 0; 15584a0df2efSAndy Whitcroft } 15594a0df2efSAndy Whitcroft } 15604a0df2efSAndy Whitcroft 15614a0df2efSAndy Whitcroft chomp($current_comment); 15624a0df2efSAndy Whitcroft return($current_comment); 15634a0df2efSAndy Whitcroft} 15644a0df2efSAndy Whitcroftsub ctx_has_comment { 15654a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 15664a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 15674a0df2efSAndy Whitcroft 156800df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 15694a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 15704a0df2efSAndy Whitcroft 15714a0df2efSAndy Whitcroft return ($cmt ne ''); 15724a0df2efSAndy Whitcroft} 15734a0df2efSAndy Whitcroft 15744d001e4dSAndy Whitcroftsub raw_line { 15754d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 15764d001e4dSAndy Whitcroft 15774d001e4dSAndy Whitcroft my $offset = $linenr - 1; 15784d001e4dSAndy Whitcroft $cnt++; 15794d001e4dSAndy Whitcroft 15804d001e4dSAndy Whitcroft my $line; 15814d001e4dSAndy Whitcroft while ($cnt) { 15824d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 15834d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 15844d001e4dSAndy Whitcroft $cnt--; 15854d001e4dSAndy Whitcroft } 15864d001e4dSAndy Whitcroft 15874d001e4dSAndy Whitcroft return $line; 15884d001e4dSAndy Whitcroft} 15894d001e4dSAndy Whitcroft 15900a920b5bSAndy Whitcroftsub cat_vet { 15910a920b5bSAndy Whitcroft my ($vet) = @_; 15929c0ca6f9SAndy Whitcroft my ($res, $coded); 15930a920b5bSAndy Whitcroft 15949c0ca6f9SAndy Whitcroft $res = ''; 15956c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 15966c72ffaaSAndy Whitcroft $res .= $1; 15976c72ffaaSAndy Whitcroft if ($2 ne '') { 15989c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 15996c72ffaaSAndy Whitcroft $res .= $coded; 16006c72ffaaSAndy Whitcroft } 16019c0ca6f9SAndy Whitcroft } 16029c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 16030a920b5bSAndy Whitcroft 16049c0ca6f9SAndy Whitcroft return $res; 16050a920b5bSAndy Whitcroft} 16060a920b5bSAndy Whitcroft 1607c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1608cf655043SAndy Whitcroftmy $av_pending; 1609c2fdda0dSAndy Whitcroftmy @av_paren_type; 16101f65f947SAndy Whitcroftmy $av_pend_colon; 1611c2fdda0dSAndy Whitcroft 1612c2fdda0dSAndy Whitcroftsub annotate_reset { 1613c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1614cf655043SAndy Whitcroft $av_pending = '_'; 1615cf655043SAndy Whitcroft @av_paren_type = ('E'); 16161f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1617c2fdda0dSAndy Whitcroft} 1618c2fdda0dSAndy Whitcroft 16196c72ffaaSAndy Whitcroftsub annotate_values { 16206c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 16216c72ffaaSAndy Whitcroft 16226c72ffaaSAndy Whitcroft my $res; 16231f65f947SAndy Whitcroft my $var = '_' x length($stream); 16246c72ffaaSAndy Whitcroft my $cur = $stream; 16256c72ffaaSAndy Whitcroft 1626c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 16276c72ffaaSAndy Whitcroft 16286c72ffaaSAndy Whitcroft while (length($cur)) { 1629773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1630cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1631171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 16326c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1633c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1634c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1635cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1636c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 16376c72ffaaSAndy Whitcroft } 16386c72ffaaSAndy Whitcroft 1639c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 16409446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 16419446ef56SAndy Whitcroft push(@av_paren_type, $type); 1642addcdceaSAndy Whitcroft $type = 'c'; 16439446ef56SAndy Whitcroft 1644e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1645c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 16466c72ffaaSAndy Whitcroft $type = 'T'; 16476c72ffaaSAndy Whitcroft 1648389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1649389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1650389a2fe5SAndy Whitcroft $type = 'T'; 1651389a2fe5SAndy Whitcroft 1652c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1653171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1654c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1655171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1656171ae1a4SAndy Whitcroft if ($2 ne '') { 1657cf655043SAndy Whitcroft $av_pending = 'N'; 1658171ae1a4SAndy Whitcroft } 1659171ae1a4SAndy Whitcroft $type = 'E'; 1660171ae1a4SAndy Whitcroft 1661c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1662171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1663171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1664171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 16656c72ffaaSAndy Whitcroft 1666c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1667cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1668c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1669cf655043SAndy Whitcroft 1670cf655043SAndy Whitcroft push(@av_paren_type, $type); 1671cf655043SAndy Whitcroft push(@av_paren_type, $type); 1672171ae1a4SAndy Whitcroft $type = 'E'; 1673cf655043SAndy Whitcroft 1674c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1675cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1676cf655043SAndy Whitcroft $av_preprocessor = 1; 1677cf655043SAndy Whitcroft 1678cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1679cf655043SAndy Whitcroft 1680171ae1a4SAndy Whitcroft $type = 'E'; 1681cf655043SAndy Whitcroft 1682c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1683cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1684cf655043SAndy Whitcroft 1685cf655043SAndy Whitcroft $av_preprocessor = 1; 1686cf655043SAndy Whitcroft 1687cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1688cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1689cf655043SAndy Whitcroft pop(@av_paren_type); 1690cf655043SAndy Whitcroft push(@av_paren_type, $type); 1691171ae1a4SAndy Whitcroft $type = 'E'; 16926c72ffaaSAndy Whitcroft 16936c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1694c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 16956c72ffaaSAndy Whitcroft 1696171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1697171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1698171ae1a4SAndy Whitcroft $av_pending = $type; 1699171ae1a4SAndy Whitcroft $type = 'N'; 1700171ae1a4SAndy Whitcroft 17016c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1702c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 17036c72ffaaSAndy Whitcroft if (defined $2) { 1704cf655043SAndy Whitcroft $av_pending = 'V'; 17056c72ffaaSAndy Whitcroft } 17066c72ffaaSAndy Whitcroft $type = 'N'; 17076c72ffaaSAndy Whitcroft 170814b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1709c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 171014b111c1SAndy Whitcroft $av_pending = 'E'; 17116c72ffaaSAndy Whitcroft $type = 'N'; 17126c72ffaaSAndy Whitcroft 17131f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 17141f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 17151f65f947SAndy Whitcroft $av_pend_colon = 'C'; 17161f65f947SAndy Whitcroft $type = 'N'; 17171f65f947SAndy Whitcroft 171814b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1719c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 17206c72ffaaSAndy Whitcroft $type = 'N'; 17216c72ffaaSAndy Whitcroft 17226c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1723c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1724cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1725cf655043SAndy Whitcroft $av_pending = '_'; 17266c72ffaaSAndy Whitcroft $type = 'N'; 17276c72ffaaSAndy Whitcroft 17286c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1729cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1730cf655043SAndy Whitcroft if ($new_type ne '_') { 1731cf655043SAndy Whitcroft $type = $new_type; 1732c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1733c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 17346c72ffaaSAndy Whitcroft } else { 1735c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 17366c72ffaaSAndy Whitcroft } 17376c72ffaaSAndy Whitcroft 1738c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1739c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1740c8cb2ca3SAndy Whitcroft $type = 'V'; 1741cf655043SAndy Whitcroft $av_pending = 'V'; 17426c72ffaaSAndy Whitcroft 17438e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 17448e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 17451f65f947SAndy Whitcroft $av_pend_colon = 'B'; 17468e761b04SAndy Whitcroft } elsif ($type eq 'E') { 17478e761b04SAndy Whitcroft $av_pend_colon = 'L'; 17481f65f947SAndy Whitcroft } 17491f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 17501f65f947SAndy Whitcroft $type = 'V'; 17511f65f947SAndy Whitcroft 17526c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1753c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 17546c72ffaaSAndy Whitcroft $type = 'V'; 17556c72ffaaSAndy Whitcroft 17566c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1757c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 17586c72ffaaSAndy Whitcroft $type = 'N'; 17596c72ffaaSAndy Whitcroft 1760cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1761c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 176213214adfSAndy Whitcroft $type = 'E'; 17631f65f947SAndy Whitcroft $av_pend_colon = 'O'; 176413214adfSAndy Whitcroft 17658e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 17668e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 17678e761b04SAndy Whitcroft $type = 'C'; 17688e761b04SAndy Whitcroft 17691f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 17701f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 17711f65f947SAndy Whitcroft $type = 'N'; 17721f65f947SAndy Whitcroft 17731f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 17741f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 17751f65f947SAndy Whitcroft 17761f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 17771f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 17781f65f947SAndy Whitcroft $type = 'E'; 17791f65f947SAndy Whitcroft } else { 17801f65f947SAndy Whitcroft $type = 'N'; 17811f65f947SAndy Whitcroft } 17821f65f947SAndy Whitcroft $av_pend_colon = 'O'; 17831f65f947SAndy Whitcroft 17848e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 178513214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 17866c72ffaaSAndy Whitcroft $type = 'N'; 17876c72ffaaSAndy Whitcroft 17880d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 178974048ed8SAndy Whitcroft my $variant; 179074048ed8SAndy Whitcroft 179174048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 179274048ed8SAndy Whitcroft if ($type eq 'V') { 179374048ed8SAndy Whitcroft $variant = 'B'; 179474048ed8SAndy Whitcroft } else { 179574048ed8SAndy Whitcroft $variant = 'U'; 179674048ed8SAndy Whitcroft } 179774048ed8SAndy Whitcroft 179874048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 179974048ed8SAndy Whitcroft $type = 'N'; 180074048ed8SAndy Whitcroft 18016c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1802c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 18036c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 18046c72ffaaSAndy Whitcroft $type = 'N'; 18056c72ffaaSAndy Whitcroft } 18066c72ffaaSAndy Whitcroft 18076c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1808c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 18096c72ffaaSAndy Whitcroft } 18106c72ffaaSAndy Whitcroft if (defined $1) { 18116c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 18126c72ffaaSAndy Whitcroft $res .= $type x length($1); 18136c72ffaaSAndy Whitcroft } 18146c72ffaaSAndy Whitcroft } 18156c72ffaaSAndy Whitcroft 18161f65f947SAndy Whitcroft return ($res, $var); 18176c72ffaaSAndy Whitcroft} 18186c72ffaaSAndy Whitcroft 18198905a67cSAndy Whitcroftsub possible { 182013214adfSAndy Whitcroft my ($possible, $line) = @_; 18219a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 18220776e594SAndy Whitcroft ^(?: 18230776e594SAndy Whitcroft $Modifier| 18240776e594SAndy Whitcroft $Storage| 18250776e594SAndy Whitcroft $Type| 18269a974fdbSAndy Whitcroft DEFINE_\S+ 18279a974fdbSAndy Whitcroft )$| 18289a974fdbSAndy Whitcroft ^(?: 18290776e594SAndy Whitcroft goto| 18300776e594SAndy Whitcroft return| 18310776e594SAndy Whitcroft case| 18320776e594SAndy Whitcroft else| 18330776e594SAndy Whitcroft asm|__asm__| 183489a88353SAndy Whitcroft do| 183589a88353SAndy Whitcroft \#| 183689a88353SAndy Whitcroft \#\#| 18379a974fdbSAndy Whitcroft )(?:\s|$)| 18380776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 18399a974fdbSAndy Whitcroft )}x; 18409a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 18419a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1842c45dcabdSAndy Whitcroft # Check for modifiers. 1843c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1844c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1845c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1846c45dcabdSAndy Whitcroft 1847c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1848c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1849d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 18509a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1851d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1852485ff23eSAlex Dowad push(@modifierListFile, $modifier); 1853d2506586SAndy Whitcroft } 18549a974fdbSAndy Whitcroft } 1855c45dcabdSAndy Whitcroft 1856c45dcabdSAndy Whitcroft } else { 185713214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1858485ff23eSAlex Dowad push(@typeListFile, $possible); 1859c45dcabdSAndy Whitcroft } 18608905a67cSAndy Whitcroft build_types(); 18610776e594SAndy Whitcroft } else { 18620776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 18638905a67cSAndy Whitcroft } 18648905a67cSAndy Whitcroft} 18658905a67cSAndy Whitcroft 18666c72ffaaSAndy Whitcroftmy $prefix = ''; 18676c72ffaaSAndy Whitcroft 1868000d1cc1SJoe Perchessub show_type { 1869cbec18afSJoe Perches my ($type) = @_; 187091bfe484SJoe Perches 1871522b837cSAlexey Dobriyan $type =~ tr/[a-z]/[A-Z]/; 1872522b837cSAlexey Dobriyan 1873cbec18afSJoe Perches return defined $use_type{$type} if (scalar keys %use_type > 0); 1874cbec18afSJoe Perches 1875cbec18afSJoe Perches return !defined $ignore_type{$type}; 1876000d1cc1SJoe Perches} 1877000d1cc1SJoe Perches 1878f0a594c1SAndy Whitcroftsub report { 1879cbec18afSJoe Perches my ($level, $type, $msg) = @_; 1880cbec18afSJoe Perches 1881cbec18afSJoe Perches if (!show_type($type) || 1882cbec18afSJoe Perches (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { 1883773647a0SAndy Whitcroft return 0; 1884773647a0SAndy Whitcroft } 188557230297SJoe Perches my $output = ''; 188657230297SJoe Perches if (-t STDOUT && $color) { 188757230297SJoe Perches if ($level eq 'ERROR') { 188857230297SJoe Perches $output .= RED; 188957230297SJoe Perches } elsif ($level eq 'WARNING') { 189057230297SJoe Perches $output .= YELLOW; 1891000d1cc1SJoe Perches } else { 189257230297SJoe Perches $output .= GREEN; 1893000d1cc1SJoe Perches } 189457230297SJoe Perches } 189557230297SJoe Perches $output .= $prefix . $level . ':'; 189657230297SJoe Perches if ($show_types) { 189757230297SJoe Perches $output .= BLUE if (-t STDOUT && $color); 189857230297SJoe Perches $output .= "$type:"; 189957230297SJoe Perches } 190057230297SJoe Perches $output .= RESET if (-t STDOUT && $color); 190157230297SJoe Perches $output .= ' ' . $msg . "\n"; 190234d8815fSJoe Perches 190334d8815fSJoe Perches if ($showfile) { 190434d8815fSJoe Perches my @lines = split("\n", $output, -1); 190534d8815fSJoe Perches splice(@lines, 1, 1); 190634d8815fSJoe Perches $output = join("\n", @lines); 190734d8815fSJoe Perches } 190857230297SJoe Perches $output = (split('\n', $output))[0] . "\n" if ($terse); 19098905a67cSAndy Whitcroft 191057230297SJoe Perches push(our @report, $output); 1911773647a0SAndy Whitcroft 1912773647a0SAndy Whitcroft return 1; 1913f0a594c1SAndy Whitcroft} 1914cbec18afSJoe Perches 1915f0a594c1SAndy Whitcroftsub report_dump { 191613214adfSAndy Whitcroft our @report; 1917f0a594c1SAndy Whitcroft} 1918000d1cc1SJoe Perches 1919d752fcc8SJoe Perchessub fixup_current_range { 1920d752fcc8SJoe Perches my ($lineRef, $offset, $length) = @_; 1921d752fcc8SJoe Perches 1922d752fcc8SJoe Perches if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { 1923d752fcc8SJoe Perches my $o = $1; 1924d752fcc8SJoe Perches my $l = $2; 1925d752fcc8SJoe Perches my $no = $o + $offset; 1926d752fcc8SJoe Perches my $nl = $l + $length; 1927d752fcc8SJoe Perches $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; 1928d752fcc8SJoe Perches } 1929d752fcc8SJoe Perches} 1930d752fcc8SJoe Perches 1931d752fcc8SJoe Perchessub fix_inserted_deleted_lines { 1932d752fcc8SJoe Perches my ($linesRef, $insertedRef, $deletedRef) = @_; 1933d752fcc8SJoe Perches 1934d752fcc8SJoe Perches my $range_last_linenr = 0; 1935d752fcc8SJoe Perches my $delta_offset = 0; 1936d752fcc8SJoe Perches 1937d752fcc8SJoe Perches my $old_linenr = 0; 1938d752fcc8SJoe Perches my $new_linenr = 0; 1939d752fcc8SJoe Perches 1940d752fcc8SJoe Perches my $next_insert = 0; 1941d752fcc8SJoe Perches my $next_delete = 0; 1942d752fcc8SJoe Perches 1943d752fcc8SJoe Perches my @lines = (); 1944d752fcc8SJoe Perches 1945d752fcc8SJoe Perches my $inserted = @{$insertedRef}[$next_insert++]; 1946d752fcc8SJoe Perches my $deleted = @{$deletedRef}[$next_delete++]; 1947d752fcc8SJoe Perches 1948d752fcc8SJoe Perches foreach my $old_line (@{$linesRef}) { 1949d752fcc8SJoe Perches my $save_line = 1; 1950d752fcc8SJoe Perches my $line = $old_line; #don't modify the array 1951323b267fSJoe Perches if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename 1952d752fcc8SJoe Perches $delta_offset = 0; 1953d752fcc8SJoe Perches } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk 1954d752fcc8SJoe Perches $range_last_linenr = $new_linenr; 1955d752fcc8SJoe Perches fixup_current_range(\$line, $delta_offset, 0); 1956d752fcc8SJoe Perches } 1957d752fcc8SJoe Perches 1958d752fcc8SJoe Perches while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { 1959d752fcc8SJoe Perches $deleted = @{$deletedRef}[$next_delete++]; 1960d752fcc8SJoe Perches $save_line = 0; 1961d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); 1962d752fcc8SJoe Perches } 1963d752fcc8SJoe Perches 1964d752fcc8SJoe Perches while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { 1965d752fcc8SJoe Perches push(@lines, ${$inserted}{'LINE'}); 1966d752fcc8SJoe Perches $inserted = @{$insertedRef}[$next_insert++]; 1967d752fcc8SJoe Perches $new_linenr++; 1968d752fcc8SJoe Perches fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); 1969d752fcc8SJoe Perches } 1970d752fcc8SJoe Perches 1971d752fcc8SJoe Perches if ($save_line) { 1972d752fcc8SJoe Perches push(@lines, $line); 1973d752fcc8SJoe Perches $new_linenr++; 1974d752fcc8SJoe Perches } 1975d752fcc8SJoe Perches 1976d752fcc8SJoe Perches $old_linenr++; 1977d752fcc8SJoe Perches } 1978d752fcc8SJoe Perches 1979d752fcc8SJoe Perches return @lines; 1980d752fcc8SJoe Perches} 1981d752fcc8SJoe Perches 1982f2d7e4d4SJoe Perchessub fix_insert_line { 1983f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1984f2d7e4d4SJoe Perches 1985f2d7e4d4SJoe Perches my $inserted = { 1986f2d7e4d4SJoe Perches LINENR => $linenr, 1987f2d7e4d4SJoe Perches LINE => $line, 1988f2d7e4d4SJoe Perches }; 1989f2d7e4d4SJoe Perches push(@fixed_inserted, $inserted); 1990f2d7e4d4SJoe Perches} 1991f2d7e4d4SJoe Perches 1992f2d7e4d4SJoe Perchessub fix_delete_line { 1993f2d7e4d4SJoe Perches my ($linenr, $line) = @_; 1994f2d7e4d4SJoe Perches 1995f2d7e4d4SJoe Perches my $deleted = { 1996f2d7e4d4SJoe Perches LINENR => $linenr, 1997f2d7e4d4SJoe Perches LINE => $line, 1998f2d7e4d4SJoe Perches }; 1999f2d7e4d4SJoe Perches 2000f2d7e4d4SJoe Perches push(@fixed_deleted, $deleted); 2001f2d7e4d4SJoe Perches} 2002f2d7e4d4SJoe Perches 2003de7d4f0eSAndy Whitcroftsub ERROR { 2004cbec18afSJoe Perches my ($type, $msg) = @_; 2005cbec18afSJoe Perches 2006cbec18afSJoe Perches if (report("ERROR", $type, $msg)) { 2007de7d4f0eSAndy Whitcroft our $clean = 0; 20086c72ffaaSAndy Whitcroft our $cnt_error++; 20093705ce5bSJoe Perches return 1; 2010de7d4f0eSAndy Whitcroft } 20113705ce5bSJoe Perches return 0; 2012773647a0SAndy Whitcroft} 2013de7d4f0eSAndy Whitcroftsub WARN { 2014cbec18afSJoe Perches my ($type, $msg) = @_; 2015cbec18afSJoe Perches 2016cbec18afSJoe Perches if (report("WARNING", $type, $msg)) { 2017de7d4f0eSAndy Whitcroft our $clean = 0; 20186c72ffaaSAndy Whitcroft our $cnt_warn++; 20193705ce5bSJoe Perches return 1; 2020de7d4f0eSAndy Whitcroft } 20213705ce5bSJoe Perches return 0; 2022773647a0SAndy Whitcroft} 2023de7d4f0eSAndy Whitcroftsub CHK { 2024cbec18afSJoe Perches my ($type, $msg) = @_; 2025cbec18afSJoe Perches 2026cbec18afSJoe Perches if ($check && report("CHECK", $type, $msg)) { 2027de7d4f0eSAndy Whitcroft our $clean = 0; 20286c72ffaaSAndy Whitcroft our $cnt_chk++; 20293705ce5bSJoe Perches return 1; 20306c72ffaaSAndy Whitcroft } 20313705ce5bSJoe Perches return 0; 2032de7d4f0eSAndy Whitcroft} 2033de7d4f0eSAndy Whitcroft 20346ecd9674SAndy Whitcroftsub check_absolute_file { 20356ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 20366ecd9674SAndy Whitcroft my $file = $absolute; 20376ecd9674SAndy Whitcroft 20386ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 20396ecd9674SAndy Whitcroft 20406ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 20416ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 20426ecd9674SAndy Whitcroft if (-f "$root/$file") { 20436ecd9674SAndy Whitcroft ##print "file<$file>\n"; 20446ecd9674SAndy Whitcroft last; 20456ecd9674SAndy Whitcroft } 20466ecd9674SAndy Whitcroft } 20476ecd9674SAndy Whitcroft if (! -f _) { 20486ecd9674SAndy Whitcroft return 0; 20496ecd9674SAndy Whitcroft } 20506ecd9674SAndy Whitcroft 20516ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 20526ecd9674SAndy Whitcroft my $prefix = $absolute; 20536ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 20546ecd9674SAndy Whitcroft 20556ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 20566ecd9674SAndy Whitcroft if ($prefix ne ".../") { 2057000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 2058000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 20596ecd9674SAndy Whitcroft } 20606ecd9674SAndy Whitcroft} 20616ecd9674SAndy Whitcroft 20623705ce5bSJoe Perchessub trim { 20633705ce5bSJoe Perches my ($string) = @_; 20643705ce5bSJoe Perches 2065b34c648bSJoe Perches $string =~ s/^\s+|\s+$//g; 2066b34c648bSJoe Perches 2067b34c648bSJoe Perches return $string; 2068b34c648bSJoe Perches} 2069b34c648bSJoe Perches 2070b34c648bSJoe Perchessub ltrim { 2071b34c648bSJoe Perches my ($string) = @_; 2072b34c648bSJoe Perches 2073b34c648bSJoe Perches $string =~ s/^\s+//; 2074b34c648bSJoe Perches 2075b34c648bSJoe Perches return $string; 2076b34c648bSJoe Perches} 2077b34c648bSJoe Perches 2078b34c648bSJoe Perchessub rtrim { 2079b34c648bSJoe Perches my ($string) = @_; 2080b34c648bSJoe Perches 2081b34c648bSJoe Perches $string =~ s/\s+$//; 20823705ce5bSJoe Perches 20833705ce5bSJoe Perches return $string; 20843705ce5bSJoe Perches} 20853705ce5bSJoe Perches 208652ea8506SJoe Perchessub string_find_replace { 208752ea8506SJoe Perches my ($string, $find, $replace) = @_; 208852ea8506SJoe Perches 208952ea8506SJoe Perches $string =~ s/$find/$replace/g; 209052ea8506SJoe Perches 209152ea8506SJoe Perches return $string; 209252ea8506SJoe Perches} 209352ea8506SJoe Perches 20943705ce5bSJoe Perchessub tabify { 20953705ce5bSJoe Perches my ($leading) = @_; 20963705ce5bSJoe Perches 20973705ce5bSJoe Perches my $source_indent = 8; 20983705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 20993705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 21003705ce5bSJoe Perches 21013705ce5bSJoe Perches #convert leading spaces to tabs 21023705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 21033705ce5bSJoe Perches #Remove spaces before a tab 21043705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 21053705ce5bSJoe Perches 21063705ce5bSJoe Perches return "$leading"; 21073705ce5bSJoe Perches} 21083705ce5bSJoe Perches 2109d1fe9c09SJoe Perchessub pos_last_openparen { 2110d1fe9c09SJoe Perches my ($line) = @_; 2111d1fe9c09SJoe Perches 2112d1fe9c09SJoe Perches my $pos = 0; 2113d1fe9c09SJoe Perches 2114d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 2115d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 2116d1fe9c09SJoe Perches 2117d1fe9c09SJoe Perches my $last_openparen = 0; 2118d1fe9c09SJoe Perches 2119d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 2120d1fe9c09SJoe Perches return -1; 2121d1fe9c09SJoe Perches } 2122d1fe9c09SJoe Perches 2123d1fe9c09SJoe Perches my $len = length($line); 2124d1fe9c09SJoe Perches 2125d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 2126d1fe9c09SJoe Perches my $string = substr($line, $pos); 2127d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 2128d1fe9c09SJoe Perches $pos += length($1) - 1; 2129d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 2130d1fe9c09SJoe Perches $last_openparen = $pos; 2131d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 2132d1fe9c09SJoe Perches last; 2133d1fe9c09SJoe Perches } 2134d1fe9c09SJoe Perches } 2135d1fe9c09SJoe Perches 213691cb5195SJoe Perches return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; 2137d1fe9c09SJoe Perches} 2138d1fe9c09SJoe Perches 21390a920b5bSAndy Whitcroftsub process { 21400a920b5bSAndy Whitcroft my $filename = shift; 21410a920b5bSAndy Whitcroft 21420a920b5bSAndy Whitcroft my $linenr=0; 21430a920b5bSAndy Whitcroft my $prevline=""; 2144c2fdda0dSAndy Whitcroft my $prevrawline=""; 21450a920b5bSAndy Whitcroft my $stashline=""; 2146c2fdda0dSAndy Whitcroft my $stashrawline=""; 21470a920b5bSAndy Whitcroft 21484a0df2efSAndy Whitcroft my $length; 21490a920b5bSAndy Whitcroft my $indent; 21500a920b5bSAndy Whitcroft my $previndent=0; 21510a920b5bSAndy Whitcroft my $stashindent=0; 21520a920b5bSAndy Whitcroft 2153de7d4f0eSAndy Whitcroft our $clean = 1; 21540a920b5bSAndy Whitcroft my $signoff = 0; 21550a920b5bSAndy Whitcroft my $is_patch = 0; 215629ee1b0cSJoe Perches my $in_header_lines = $file ? 0 : 1; 215715662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 2158ed43c4e5SAllen Hubbe my $has_commit_log = 0; #Encountered lines before patch 2159bf4daf12SJoe Perches my $commit_log_possible_stack_dump = 0; 21602a076f40SJoe Perches my $commit_log_long_line = 0; 2161e518e9a5SJoe Perches my $commit_log_has_diff = 0; 216213f1937eSJoe Perches my $reported_maintainer_file = 0; 2163fa64205dSPasi Savanainen my $non_utf8_charset = 0; 2164fa64205dSPasi Savanainen 2165365dd4eaSJoe Perches my $last_blank_line = 0; 21665e4f6ba5SJoe Perches my $last_coalesced_string_linenr = -1; 2167365dd4eaSJoe Perches 216813214adfSAndy Whitcroft our @report = (); 21696c72ffaaSAndy Whitcroft our $cnt_lines = 0; 21706c72ffaaSAndy Whitcroft our $cnt_error = 0; 21716c72ffaaSAndy Whitcroft our $cnt_warn = 0; 21726c72ffaaSAndy Whitcroft our $cnt_chk = 0; 21736c72ffaaSAndy Whitcroft 21740a920b5bSAndy Whitcroft # Trace the real file/line as we go. 21750a920b5bSAndy Whitcroft my $realfile = ''; 21760a920b5bSAndy Whitcroft my $realline = 0; 21770a920b5bSAndy Whitcroft my $realcnt = 0; 21780a920b5bSAndy Whitcroft my $here = ''; 217977cb8546SJoe Perches my $context_function; #undef'd unless there's a known function 21800a920b5bSAndy Whitcroft my $in_comment = 0; 2181c2fdda0dSAndy Whitcroft my $comment_edge = 0; 21820a920b5bSAndy Whitcroft my $first_line = 0; 21831e855726SWolfram Sang my $p1_prefix = ''; 21840a920b5bSAndy Whitcroft 218513214adfSAndy Whitcroft my $prev_values = 'E'; 218613214adfSAndy Whitcroft 218713214adfSAndy Whitcroft # suppression flags 2188773647a0SAndy Whitcroft my %suppress_ifbraces; 2189170d3a22SAndy Whitcroft my %suppress_whiletrailers; 21902b474a1aSAndy Whitcroft my %suppress_export; 21913e469cdcSAndy Whitcroft my $suppress_statement = 0; 2192653d4876SAndy Whitcroft 21937e51f197SJoe Perches my %signatures = (); 2194323c1260SJoe Perches 2195c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 2196de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 2197c2fdda0dSAndy Whitcroft # 2198de7d4f0eSAndy Whitcroft my @setup_docs = (); 2199de7d4f0eSAndy Whitcroft my $setup_docs = 0; 2200773647a0SAndy Whitcroft 2201d8b07710SJoe Perches my $camelcase_file_seeded = 0; 2202d8b07710SJoe Perches 2203773647a0SAndy Whitcroft sanitise_line_reset(); 2204c2fdda0dSAndy Whitcroft my $line; 2205c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 2206773647a0SAndy Whitcroft $linenr++; 2207773647a0SAndy Whitcroft $line = $rawline; 2208c2fdda0dSAndy Whitcroft 22093705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 22103705ce5bSJoe Perches 2211773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 2212de7d4f0eSAndy Whitcroft $setup_docs = 0; 22138c27ceffSMauro Carvalho Chehab if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { 2214de7d4f0eSAndy Whitcroft $setup_docs = 1; 2215de7d4f0eSAndy Whitcroft } 2216773647a0SAndy Whitcroft #next; 2217de7d4f0eSAndy Whitcroft } 221874fd4f34SJoe Perches if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 2219773647a0SAndy Whitcroft $realline=$1-1; 2220773647a0SAndy Whitcroft if (defined $2) { 2221773647a0SAndy Whitcroft $realcnt=$3+1; 2222773647a0SAndy Whitcroft } else { 2223773647a0SAndy Whitcroft $realcnt=1+1; 2224773647a0SAndy Whitcroft } 2225c45dcabdSAndy Whitcroft $in_comment = 0; 2226773647a0SAndy Whitcroft 2227773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 2228773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 2229773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 2230773647a0SAndy Whitcroft # at context start. 2231773647a0SAndy Whitcroft my $edge; 223201fa9147SAndy Whitcroft my $cnt = $realcnt; 223301fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 223401fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 223501fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 223601fa9147SAndy Whitcroft $cnt--; 223701fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 2238721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 2239fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 2240fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 2241fae17daeSAndy Whitcroft ($edge) = $1; 2242fae17daeSAndy Whitcroft last; 2243fae17daeSAndy Whitcroft } 2244773647a0SAndy Whitcroft } 2245773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 2246773647a0SAndy Whitcroft $in_comment = 1; 2247773647a0SAndy Whitcroft } 2248773647a0SAndy Whitcroft 2249773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 2250773647a0SAndy Whitcroft # is the start of a diff block and this line starts 2251773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 2252773647a0SAndy Whitcroft if (!defined $edge && 225383242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 2254773647a0SAndy Whitcroft { 2255773647a0SAndy Whitcroft $in_comment = 1; 2256773647a0SAndy Whitcroft } 2257773647a0SAndy Whitcroft 2258773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 2259773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 2260773647a0SAndy Whitcroft 2261171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 2262773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 2263171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 2264773647a0SAndy Whitcroft $line = sanitise_line($rawline); 2265773647a0SAndy Whitcroft } 2266773647a0SAndy Whitcroft push(@lines, $line); 2267773647a0SAndy Whitcroft 2268773647a0SAndy Whitcroft if ($realcnt > 1) { 2269773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 2270773647a0SAndy Whitcroft } else { 2271773647a0SAndy Whitcroft $realcnt = 0; 2272773647a0SAndy Whitcroft } 2273773647a0SAndy Whitcroft 2274773647a0SAndy Whitcroft #print "==>$rawline\n"; 2275773647a0SAndy Whitcroft #print "-->$line\n"; 2276de7d4f0eSAndy Whitcroft 2277de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 2278de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 2279de7d4f0eSAndy Whitcroft } 2280de7d4f0eSAndy Whitcroft } 2281de7d4f0eSAndy Whitcroft 22826c72ffaaSAndy Whitcroft $prefix = ''; 22836c72ffaaSAndy Whitcroft 2284773647a0SAndy Whitcroft $realcnt = 0; 2285773647a0SAndy Whitcroft $linenr = 0; 2286194f66fcSJoe Perches $fixlinenr = -1; 22870a920b5bSAndy Whitcroft foreach my $line (@lines) { 22880a920b5bSAndy Whitcroft $linenr++; 2289194f66fcSJoe Perches $fixlinenr++; 22901b5539b1SJoe Perches my $sline = $line; #copy of $line 22911b5539b1SJoe Perches $sline =~ s/$;/ /g; #with comments as spaces 22920a920b5bSAndy Whitcroft 2293c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 22946c72ffaaSAndy Whitcroft 22950a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 2296e518e9a5SJoe Perches if (!$in_commit_log && 229774fd4f34SJoe Perches $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { 229874fd4f34SJoe Perches my $context = $4; 22990a920b5bSAndy Whitcroft $is_patch = 1; 23004a0df2efSAndy Whitcroft $first_line = $linenr + 1; 23010a920b5bSAndy Whitcroft $realline=$1-1; 23020a920b5bSAndy Whitcroft if (defined $2) { 23030a920b5bSAndy Whitcroft $realcnt=$3+1; 23040a920b5bSAndy Whitcroft } else { 23050a920b5bSAndy Whitcroft $realcnt=1+1; 23060a920b5bSAndy Whitcroft } 2307c2fdda0dSAndy Whitcroft annotate_reset(); 230813214adfSAndy Whitcroft $prev_values = 'E'; 230913214adfSAndy Whitcroft 2310773647a0SAndy Whitcroft %suppress_ifbraces = (); 2311170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 23122b474a1aSAndy Whitcroft %suppress_export = (); 23133e469cdcSAndy Whitcroft $suppress_statement = 0; 231474fd4f34SJoe Perches if ($context =~ /\b(\w+)\s*\(/) { 231574fd4f34SJoe Perches $context_function = $1; 231674fd4f34SJoe Perches } else { 231774fd4f34SJoe Perches undef $context_function; 231874fd4f34SJoe Perches } 23190a920b5bSAndy Whitcroft next; 23200a920b5bSAndy Whitcroft 23214a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 23224a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 23234a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 2324773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 23250a920b5bSAndy Whitcroft $realline++; 2326d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 23270a920b5bSAndy Whitcroft 23284a0df2efSAndy Whitcroft # Measure the line length and indent. 2329c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 23300a920b5bSAndy Whitcroft 23310a920b5bSAndy Whitcroft # Track the previous line. 23320a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 23330a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 2334c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 2335c2fdda0dSAndy Whitcroft 2336773647a0SAndy Whitcroft #warn "line<$line>\n"; 23376c72ffaaSAndy Whitcroft 2338d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 2339d8aaf121SAndy Whitcroft $realcnt--; 23400a920b5bSAndy Whitcroft } 23410a920b5bSAndy Whitcroft 2342cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 2343cc77cdcaSAndy Whitcroft 23446c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 23456c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 2346773647a0SAndy Whitcroft 23472ac73b4fSJoe Perches my $found_file = 0; 2348773647a0SAndy Whitcroft # extract the filename as it passes 23493bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 23503bf9a009SRabin Vincent $realfile = $1; 23512b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2352270c49a0SJoe Perches $in_commit_log = 0; 23532ac73b4fSJoe Perches $found_file = 1; 23543bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 2355773647a0SAndy Whitcroft $realfile = $1; 23562b7ab453SJoe Perches $realfile =~ s@^([^/]*)/@@ if (!$file); 2357270c49a0SJoe Perches $in_commit_log = 0; 23581e855726SWolfram Sang 23591e855726SWolfram Sang $p1_prefix = $1; 2360e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 2361e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 2362000d1cc1SJoe Perches WARN("PATCH_PREFIX", 2363000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 23641e855726SWolfram Sang } 2365773647a0SAndy Whitcroft 2366c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 2367000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 2368000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 2369773647a0SAndy Whitcroft } 23702ac73b4fSJoe Perches $found_file = 1; 23712ac73b4fSJoe Perches } 23722ac73b4fSJoe Perches 237334d8815fSJoe Perches#make up the handle for any error we report on this line 237434d8815fSJoe Perches if ($showfile) { 237534d8815fSJoe Perches $prefix = "$realfile:$realline: " 237634d8815fSJoe Perches } elsif ($emacs) { 23777d3a9f67SJoe Perches if ($file) { 23787d3a9f67SJoe Perches $prefix = "$filename:$realline: "; 23797d3a9f67SJoe Perches } else { 238034d8815fSJoe Perches $prefix = "$filename:$linenr: "; 238134d8815fSJoe Perches } 23827d3a9f67SJoe Perches } 238334d8815fSJoe Perches 23842ac73b4fSJoe Perches if ($found_file) { 238585b0ee18SJoe Perches if (is_maintained_obsolete($realfile)) { 238685b0ee18SJoe Perches WARN("OBSOLETE", 238785b0ee18SJoe Perches "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); 238885b0ee18SJoe Perches } 23897bd7e483SJoe Perches if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { 23902ac73b4fSJoe Perches $check = 1; 23912ac73b4fSJoe Perches } else { 23922ac73b4fSJoe Perches $check = $check_orig; 23932ac73b4fSJoe Perches } 2394773647a0SAndy Whitcroft next; 2395773647a0SAndy Whitcroft } 2396773647a0SAndy Whitcroft 2397389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 23980a920b5bSAndy Whitcroft 2399c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 2400c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 2401c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 24020a920b5bSAndy Whitcroft 24036c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 24046c72ffaaSAndy Whitcroft 2405e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch 2406e518e9a5SJoe Perches if ($in_commit_log && !$commit_log_has_diff && 2407e518e9a5SJoe Perches (($line =~ m@^\s+diff\b.*a/[\w/]+@ && 2408e518e9a5SJoe Perches $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || 2409e518e9a5SJoe Perches $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || 2410e518e9a5SJoe Perches $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { 2411e518e9a5SJoe Perches ERROR("DIFF_IN_COMMIT_MSG", 2412e518e9a5SJoe Perches "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); 2413e518e9a5SJoe Perches $commit_log_has_diff = 1; 2414e518e9a5SJoe Perches } 2415e518e9a5SJoe Perches 24163bf9a009SRabin Vincent# Check for incorrect file permissions 24173bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 24183bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 241904db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 242004db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 2421000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 2422000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 24233bf9a009SRabin Vincent } 24243bf9a009SRabin Vincent } 24253bf9a009SRabin Vincent 242620112475SJoe Perches# Check the patch for a signoff: 2427d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 24284a0df2efSAndy Whitcroft $signoff++; 242915662b3eSJoe Perches $in_commit_log = 0; 24300a920b5bSAndy Whitcroft } 243120112475SJoe Perches 2432e0d975b1SJoe Perches# Check if MAINTAINERS is being updated. If so, there's probably no need to 2433e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete 2434e0d975b1SJoe Perches if ($line =~ /^\s*MAINTAINERS\s*\|/) { 2435e0d975b1SJoe Perches $reported_maintainer_file = 1; 2436e0d975b1SJoe Perches } 2437e0d975b1SJoe Perches 243820112475SJoe Perches# Check signature styles 2439270c49a0SJoe Perches if (!$in_header_lines && 2440ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 244120112475SJoe Perches my $space_before = $1; 244220112475SJoe Perches my $sign_off = $2; 244320112475SJoe Perches my $space_after = $3; 244420112475SJoe Perches my $email = $4; 244520112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 244620112475SJoe Perches 2447ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 2448ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 2449ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 2450ce0338dfSJoe Perches } 245120112475SJoe Perches if (defined $space_before && $space_before ne "") { 24523705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24533705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 24543705ce5bSJoe Perches $fix) { 2455194f66fcSJoe Perches $fixed[$fixlinenr] = 24563705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24573705ce5bSJoe Perches } 245820112475SJoe Perches } 245920112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 24603705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24613705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 24623705ce5bSJoe Perches $fix) { 2463194f66fcSJoe Perches $fixed[$fixlinenr] = 24643705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24653705ce5bSJoe Perches } 24663705ce5bSJoe Perches 246720112475SJoe Perches } 246820112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 24693705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 24703705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 24713705ce5bSJoe Perches $fix) { 2472194f66fcSJoe Perches $fixed[$fixlinenr] = 24733705ce5bSJoe Perches "$ucfirst_sign_off $email"; 24743705ce5bSJoe Perches } 247520112475SJoe Perches } 247620112475SJoe Perches 247720112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 247820112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 247920112475SJoe Perches if ($suggested_email eq "") { 2480000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 2481000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 248220112475SJoe Perches } else { 248320112475SJoe Perches my $dequoted = $suggested_email; 248420112475SJoe Perches $dequoted =~ s/^"//; 248520112475SJoe Perches $dequoted =~ s/" </ </; 248620112475SJoe Perches # Don't force email to have quotes 248720112475SJoe Perches # Allow just an angle bracketed address 248820112475SJoe Perches if ("$dequoted$comment" ne $email && 248920112475SJoe Perches "<$email_address>$comment" ne $email && 249020112475SJoe Perches "$suggested_email$comment" ne $email) { 2491000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 2492000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 249320112475SJoe Perches } 24940a920b5bSAndy Whitcroft } 24957e51f197SJoe Perches 24967e51f197SJoe Perches# Check for duplicate signatures 24977e51f197SJoe Perches my $sig_nospace = $line; 24987e51f197SJoe Perches $sig_nospace =~ s/\s//g; 24997e51f197SJoe Perches $sig_nospace = lc($sig_nospace); 25007e51f197SJoe Perches if (defined $signatures{$sig_nospace}) { 25017e51f197SJoe Perches WARN("BAD_SIGN_OFF", 25027e51f197SJoe Perches "Duplicate signature\n" . $herecurr); 25037e51f197SJoe Perches } else { 25047e51f197SJoe Perches $signatures{$sig_nospace} = 1; 25057e51f197SJoe Perches } 25060a920b5bSAndy Whitcroft } 25070a920b5bSAndy Whitcroft 2508a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned 2509a2fe16b9SJoe Perches if ($in_header_lines && 2510a2fe16b9SJoe Perches $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { 2511a2fe16b9SJoe Perches WARN("EMAIL_SUBJECT", 2512a2fe16b9SJoe Perches "A patch subject line should describe the change not the tool that found it\n" . $herecurr); 2513a2fe16b9SJoe Perches } 2514a2fe16b9SJoe Perches 25159b3189ebSJoe Perches# Check for old stable address 25169b3189ebSJoe Perches if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { 25179b3189ebSJoe Perches ERROR("STABLE_ADDRESS", 25189b3189ebSJoe Perches "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); 25199b3189ebSJoe Perches } 25209b3189ebSJoe Perches 25217ebd05efSChristopher Covington# Check for unwanted Gerrit info 25227ebd05efSChristopher Covington if ($in_commit_log && $line =~ /^\s*change-id:/i) { 25237ebd05efSChristopher Covington ERROR("GERRIT_CHANGE_ID", 25247ebd05efSChristopher Covington "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); 25257ebd05efSChristopher Covington } 25267ebd05efSChristopher Covington 2527369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump 2528369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2529369c8dd3SJoe Perches ($line =~ /^\s*(?:WARNING:|BUG:)/ || 2530369c8dd3SJoe Perches $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || 2531369c8dd3SJoe Perches # timestamp 2532369c8dd3SJoe Perches $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { 2533369c8dd3SJoe Perches # stack dump address 2534369c8dd3SJoe Perches $commit_log_possible_stack_dump = 1; 2535369c8dd3SJoe Perches } 2536369c8dd3SJoe Perches 25372a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once 25382a076f40SJoe Perches if ($in_commit_log && !$commit_log_long_line && 2539bf4daf12SJoe Perches length($line) > 75 && 2540bf4daf12SJoe Perches !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || 2541bf4daf12SJoe Perches # file delta changes 2542bf4daf12SJoe Perches $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || 2543bf4daf12SJoe Perches # filename then : 2544bf4daf12SJoe Perches $line =~ /^\s*(?:Fixes:|Link:)/i || 2545bf4daf12SJoe Perches # A Fixes: or Link: line 2546bf4daf12SJoe Perches $commit_log_possible_stack_dump)) { 25472a076f40SJoe Perches WARN("COMMIT_LOG_LONG_LINE", 25482a076f40SJoe Perches "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); 25492a076f40SJoe Perches $commit_log_long_line = 1; 25502a076f40SJoe Perches } 25512a076f40SJoe Perches 2552bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found 2553bf4daf12SJoe Perches if ($in_commit_log && $commit_log_possible_stack_dump && 2554bf4daf12SJoe Perches $line =~ /^\s*$/) { 2555bf4daf12SJoe Perches $commit_log_possible_stack_dump = 0; 2556bf4daf12SJoe Perches } 2557bf4daf12SJoe Perches 25580d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions 2559369c8dd3SJoe Perches if ($in_commit_log && !$commit_log_possible_stack_dump && 2560aab38f51SJoe Perches $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i && 2561e882dbfcSWei Wang $line !~ /^This reverts commit [0-9a-f]{7,40}/ && 2562fe043ea1SJoe Perches ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || 2563aab38f51SJoe Perches ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && 2564369c8dd3SJoe Perches $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && 2565bf4daf12SJoe Perches $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { 2566fe043ea1SJoe Perches my $init_char = "c"; 2567fe043ea1SJoe Perches my $orig_commit = ""; 25680d7835fcSJoe Perches my $short = 1; 25690d7835fcSJoe Perches my $long = 0; 25700d7835fcSJoe Perches my $case = 1; 25710d7835fcSJoe Perches my $space = 1; 25720d7835fcSJoe Perches my $hasdesc = 0; 257319c146a6SJoe Perches my $hasparens = 0; 25740d7835fcSJoe Perches my $id = '0123456789ab'; 25750d7835fcSJoe Perches my $orig_desc = "commit description"; 25760d7835fcSJoe Perches my $description = ""; 25770d7835fcSJoe Perches 2578fe043ea1SJoe Perches if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { 2579fe043ea1SJoe Perches $init_char = $1; 2580fe043ea1SJoe Perches $orig_commit = lc($2); 2581fe043ea1SJoe Perches } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { 2582fe043ea1SJoe Perches $orig_commit = lc($1); 2583fe043ea1SJoe Perches } 2584fe043ea1SJoe Perches 25850d7835fcSJoe Perches $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); 25860d7835fcSJoe Perches $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); 25870d7835fcSJoe Perches $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); 25880d7835fcSJoe Perches $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); 25890d7835fcSJoe Perches if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { 25900d7835fcSJoe Perches $orig_desc = $1; 259119c146a6SJoe Perches $hasparens = 1; 25920d7835fcSJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && 25930d7835fcSJoe Perches defined $rawlines[$linenr] && 25940d7835fcSJoe Perches $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { 25950d7835fcSJoe Perches $orig_desc = $1; 259619c146a6SJoe Perches $hasparens = 1; 2597b671fde0SJoe Perches } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && 2598b671fde0SJoe Perches defined $rawlines[$linenr] && 2599b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { 2600b671fde0SJoe Perches $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; 2601b671fde0SJoe Perches $orig_desc = $1; 2602b671fde0SJoe Perches $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; 2603b671fde0SJoe Perches $orig_desc .= " " . $1; 260419c146a6SJoe Perches $hasparens = 1; 26050d7835fcSJoe Perches } 26060d7835fcSJoe Perches 26070d7835fcSJoe Perches ($id, $description) = git_commit_info($orig_commit, 26080d7835fcSJoe Perches $id, $orig_desc); 26090d7835fcSJoe Perches 2610948b133aSHeinrich Schuchardt if (defined($id) && 2611948b133aSHeinrich Schuchardt ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { 2612d311cd44SJoe Perches ERROR("GIT_COMMIT_ID", 26130d7835fcSJoe Perches "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); 26140d7835fcSJoe Perches } 2615d311cd44SJoe Perches } 2616d311cd44SJoe Perches 261713f1937eSJoe Perches# Check for added, moved or deleted files 261813f1937eSJoe Perches if (!$reported_maintainer_file && !$in_commit_log && 261913f1937eSJoe Perches ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || 262013f1937eSJoe Perches $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || 262113f1937eSJoe Perches ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && 262213f1937eSJoe Perches (defined($1) || defined($2))))) { 2623a82603a8SAndrew Jeffery $is_patch = 1; 262413f1937eSJoe Perches $reported_maintainer_file = 1; 262513f1937eSJoe Perches WARN("FILE_PATH_CHANGES", 262613f1937eSJoe Perches "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr); 262713f1937eSJoe Perches } 262813f1937eSJoe Perches 262900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 26308905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 2631000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 2632000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 26336c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 2634de7d4f0eSAndy Whitcroft } 2635de7d4f0eSAndy Whitcroft 2636de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 2637de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 2638171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 2639171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 2640171ae1a4SAndy Whitcroft 2641171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 2642171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 2643171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 2644171ae1a4SAndy Whitcroft 264534d99219SJoe Perches CHK("INVALID_UTF8", 2646000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 264700df344fSAndy Whitcroft } 26480a920b5bSAndy Whitcroft 264915662b3eSJoe Perches# Check if it's the start of a commit log 265015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 265115662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 2652eb3a58deSJoe Perches !($rawline =~ /^\s+(?:\S|$)/ || 2653eb3a58deSJoe Perches $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { 265415662b3eSJoe Perches $in_header_lines = 0; 265515662b3eSJoe Perches $in_commit_log = 1; 2656ed43c4e5SAllen Hubbe $has_commit_log = 1; 265715662b3eSJoe Perches } 265815662b3eSJoe Perches 2659fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 2660fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 2661fa64205dSPasi Savanainen if ($in_header_lines && 2662fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 2663fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 2664fa64205dSPasi Savanainen $non_utf8_charset = 1; 2665fa64205dSPasi Savanainen } 2666fa64205dSPasi Savanainen 2667fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 266815662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 2669fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 267015662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 267115662b3eSJoe Perches } 267215662b3eSJoe Perches 2673d6430f71SJoe Perches# Check for absolute kernel paths in commit message 2674d6430f71SJoe Perches if ($tree && $in_commit_log) { 2675d6430f71SJoe Perches while ($line =~ m{(?:^|\s)(/\S*)}g) { 2676d6430f71SJoe Perches my $file = $1; 2677d6430f71SJoe Perches 2678d6430f71SJoe Perches if ($file =~ m{^(.*?)(?::\d+)+:?$} && 2679d6430f71SJoe Perches check_absolute_file($1, $herecurr)) { 2680d6430f71SJoe Perches # 2681d6430f71SJoe Perches } else { 2682d6430f71SJoe Perches check_absolute_file($file, $herecurr); 2683d6430f71SJoe Perches } 2684d6430f71SJoe Perches } 2685d6430f71SJoe Perches } 2686d6430f71SJoe Perches 268766b47b4aSKees Cook# Check for various typo / spelling mistakes 268866d7a382SJoe Perches if (defined($misspellings) && 268966d7a382SJoe Perches ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { 2690ebfd7d62SJoe Perches while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { 269166b47b4aSKees Cook my $typo = $1; 269266b47b4aSKees Cook my $typo_fix = $spelling_fix{lc($typo)}; 269366b47b4aSKees Cook $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); 269466b47b4aSKees Cook $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); 269566b47b4aSKees Cook my $msg_type = \&WARN; 269666b47b4aSKees Cook $msg_type = \&CHK if ($file); 269766b47b4aSKees Cook if (&{$msg_type}("TYPO_SPELLING", 269866b47b4aSKees Cook "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && 269966b47b4aSKees Cook $fix) { 270066b47b4aSKees Cook $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; 270166b47b4aSKees Cook } 270266b47b4aSKees Cook } 270366b47b4aSKees Cook } 270466b47b4aSKees Cook 270530670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 270630670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 270700df344fSAndy Whitcroft 27080a920b5bSAndy Whitcroft#trailing whitespace 27099c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 2710c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2711d5e616fcSJoe Perches if (ERROR("DOS_LINE_ENDINGS", 2712d5e616fcSJoe Perches "DOS line endings\n" . $herevet) && 2713d5e616fcSJoe Perches $fix) { 2714194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/[\s\015]+$//; 2715d5e616fcSJoe Perches } 2716c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 2717c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27183705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 27193705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 27203705ce5bSJoe Perches $fix) { 2721194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 27223705ce5bSJoe Perches } 27233705ce5bSJoe Perches 2724d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 27250a920b5bSAndy Whitcroft } 27265368df20SAndy Whitcroft 27274783f894SJosh Triplett# Check for FSF mailing addresses. 2728109d8cb2SAlexander Duyck if ($rawline =~ /\bwrite to the Free/i || 27291bde561eSMatthew Wilcox $rawline =~ /\b675\s+Mass\s+Ave/i || 27303e2232f2SJoe Perches $rawline =~ /\b59\s+Temple\s+Pl/i || 27313e2232f2SJoe Perches $rawline =~ /\b51\s+Franklin\s+St/i) { 27324783f894SJosh Triplett my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 27334783f894SJosh Triplett my $msg_type = \&ERROR; 27344783f894SJosh Triplett $msg_type = \&CHK if ($file); 27354783f894SJosh Triplett &{$msg_type}("FSF_MAILING_ADDRESS", 27364783f894SJosh 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) 27374783f894SJosh Triplett } 27384783f894SJosh Triplett 27393354957aSAndi Kleen# check for Kconfig help text having a real description 27409fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 27419fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 27423354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 27438d73e0e7SJoe Perches $line =~ /^\+\s*config\s+/) { 27443354957aSAndi Kleen my $length = 0; 27459fe287d7SAndy Whitcroft my $cnt = $realcnt; 27469fe287d7SAndy Whitcroft my $ln = $linenr + 1; 27479fe287d7SAndy Whitcroft my $f; 2748a1385803SAndy Whitcroft my $is_start = 0; 27499fe287d7SAndy Whitcroft my $is_end = 0; 2750a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 27519fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 27529fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 27539fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 27549fe287d7SAndy Whitcroft 27559fe287d7SAndy Whitcroft next if ($f =~ /^-/); 27568d73e0e7SJoe Perches last if (!$file && $f =~ /^\@\@/); 2757a1385803SAndy Whitcroft 27588d73e0e7SJoe Perches if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { 2759a1385803SAndy Whitcroft $is_start = 1; 27608d73e0e7SJoe Perches } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { 2761a1385803SAndy Whitcroft $length = -1; 2762a1385803SAndy Whitcroft } 2763a1385803SAndy Whitcroft 27649fe287d7SAndy Whitcroft $f =~ s/^.//; 27653354957aSAndi Kleen $f =~ s/#.*//; 27663354957aSAndi Kleen $f =~ s/^\s+//; 27673354957aSAndi Kleen next if ($f =~ /^$/); 27689fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 27699fe287d7SAndy Whitcroft $is_end = 1; 27709fe287d7SAndy Whitcroft last; 27719fe287d7SAndy Whitcroft } 27723354957aSAndi Kleen $length++; 27733354957aSAndi Kleen } 277456193274SVadim Bendebury if ($is_start && $is_end && $length < $min_conf_desc_length) { 2775000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 277656193274SVadim Bendebury "please write a paragraph that describes the config symbol fully\n" . $herecurr); 277756193274SVadim Bendebury } 2778a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 27793354957aSAndi Kleen } 27803354957aSAndi Kleen 2781628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form 2782628f91a2SJoe Perches if ($realfile =~ /^MAINTAINERS$/ && 2783628f91a2SJoe Perches $rawline =~ /^\+[A-Z]:/ && 2784628f91a2SJoe Perches $rawline !~ /^\+[A-Z]:\t\S/) { 2785628f91a2SJoe Perches if (WARN("MAINTAINERS_STYLE", 2786628f91a2SJoe Perches "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && 2787628f91a2SJoe Perches $fix) { 2788628f91a2SJoe Perches $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; 2789628f91a2SJoe Perches } 2790628f91a2SJoe Perches } 2791628f91a2SJoe Perches 2792327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options 2793327953e9SChristoph Jaeger if ($realfile =~ /Kconfig/ && 2794327953e9SChristoph Jaeger $line =~ /^\+\s*\bboolean\b/) { 2795327953e9SChristoph Jaeger WARN("CONFIG_TYPE_BOOLEAN", 2796327953e9SChristoph Jaeger "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); 2797327953e9SChristoph Jaeger } 2798327953e9SChristoph Jaeger 2799c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 2800c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 2801c68e5878SArnaud Lacombe my $flag = $1; 2802c68e5878SArnaud Lacombe my $replacement = { 2803c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 2804c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 2805c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 2806c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 2807c68e5878SArnaud Lacombe }; 2808c68e5878SArnaud Lacombe 2809c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 2810c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 2811c68e5878SArnaud Lacombe } 2812c68e5878SArnaud Lacombe 2813bff5da43SRob Herring# check for DT compatible documentation 28147dd05b38SFlorian Vaussard if (defined $root && 28157dd05b38SFlorian Vaussard (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || 28167dd05b38SFlorian Vaussard ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { 28177dd05b38SFlorian Vaussard 2818bff5da43SRob Herring my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; 2819bff5da43SRob Herring 2820cc93319bSFlorian Vaussard my $dt_path = $root . "/Documentation/devicetree/bindings/"; 2821cc93319bSFlorian Vaussard my $vp_file = $dt_path . "vendor-prefixes.txt"; 2822cc93319bSFlorian Vaussard 2823bff5da43SRob Herring foreach my $compat (@compats) { 2824bff5da43SRob Herring my $compat2 = $compat; 2825185d566bSRob Herring $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; 2826185d566bSRob Herring my $compat3 = $compat; 2827185d566bSRob Herring $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; 2828185d566bSRob Herring `grep -Erq "$compat|$compat2|$compat3" $dt_path`; 2829bff5da43SRob Herring if ( $? >> 8 ) { 2830bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2831bff5da43SRob Herring "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); 2832bff5da43SRob Herring } 2833bff5da43SRob Herring 28344fbf32a6SFlorian Vaussard next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; 28354fbf32a6SFlorian Vaussard my $vendor = $1; 2836cc93319bSFlorian Vaussard `grep -Eq "^$vendor\\b" $vp_file`; 2837bff5da43SRob Herring if ( $? >> 8 ) { 2838bff5da43SRob Herring WARN("UNDOCUMENTED_DT_STRING", 2839cc93319bSFlorian Vaussard "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); 2840bff5da43SRob Herring } 2841bff5da43SRob Herring } 2842bff5da43SRob Herring } 2843bff5da43SRob Herring 28445368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 2845d6430f71SJoe Perches next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); 28465368df20SAndy Whitcroft 284747e0c88bSJoe Perches# line length limit (with some exclusions) 284847e0c88bSJoe Perches# 284947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length: 285047e0c88bSJoe Perches# logging functions like pr_info that end in a string 285147e0c88bSJoe Perches# lines with a single string 285247e0c88bSJoe Perches# #defines that are a single string 285347e0c88bSJoe Perches# 285447e0c88bSJoe Perches# There are 3 different line length message types: 285547e0c88bSJoe Perches# LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength 285647e0c88bSJoe Perches# LONG_LINE_STRING a string starts before but extends beyond $max_line_length 285747e0c88bSJoe Perches# LONG_LINE all other lines longer than $max_line_length 285847e0c88bSJoe Perches# 285947e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored 286047e0c88bSJoe Perches# 286147e0c88bSJoe Perches 2862b4749e96SJoe Perches if ($line =~ /^\+/ && $length > $max_line_length) { 286347e0c88bSJoe Perches my $msg_type = "LONG_LINE"; 286447e0c88bSJoe Perches 286547e0c88bSJoe Perches # Check the allowed long line types first 286647e0c88bSJoe Perches 286747e0c88bSJoe Perches # logging functions that end in a string that starts 286847e0c88bSJoe Perches # before $max_line_length 286947e0c88bSJoe Perches if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && 287047e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 287147e0c88bSJoe Perches $msg_type = ""; 287247e0c88bSJoe Perches 287347e0c88bSJoe Perches # lines with only strings (w/ possible termination) 287447e0c88bSJoe Perches # #defines with only strings 287547e0c88bSJoe Perches } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || 287647e0c88bSJoe Perches $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { 287747e0c88bSJoe Perches $msg_type = ""; 287847e0c88bSJoe Perches 2879d560a5f8SJoe Perches # EFI_GUID is another special case 2880d560a5f8SJoe Perches } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { 2881d560a5f8SJoe Perches $msg_type = ""; 2882d560a5f8SJoe Perches 288347e0c88bSJoe Perches # Otherwise set the alternate message types 288447e0c88bSJoe Perches 288547e0c88bSJoe Perches # a comment starts before $max_line_length 288647e0c88bSJoe Perches } elsif ($line =~ /($;[\s$;]*)$/ && 288747e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 288847e0c88bSJoe Perches $msg_type = "LONG_LINE_COMMENT" 288947e0c88bSJoe Perches 289047e0c88bSJoe Perches # a quoted string starts before $max_line_length 289147e0c88bSJoe Perches } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && 289247e0c88bSJoe Perches length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { 289347e0c88bSJoe Perches $msg_type = "LONG_LINE_STRING" 289447e0c88bSJoe Perches } 289547e0c88bSJoe Perches 289647e0c88bSJoe Perches if ($msg_type ne "" && 289747e0c88bSJoe Perches (show_type("LONG_LINE") || show_type($msg_type))) { 289847e0c88bSJoe Perches WARN($msg_type, 28996cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 29000a920b5bSAndy Whitcroft } 290147e0c88bSJoe Perches } 29020a920b5bSAndy Whitcroft 29038905a67cSAndy Whitcroft# check for adding lines without a newline. 29048905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 2905000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 2906000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 29078905a67cSAndy Whitcroft } 29088905a67cSAndy Whitcroft 290942e41c54SMike Frysinger# Blackfin: use hi/lo macros 291042e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 291142e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 291242e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2913000d1cc1SJoe Perches ERROR("LO_MACRO", 2914000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 291542e41c54SMike Frysinger } 291642e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 291742e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2918000d1cc1SJoe Perches ERROR("HI_MACRO", 2919000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 292042e41c54SMike Frysinger } 292142e41c54SMike Frysinger } 292242e41c54SMike Frysinger 2923b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 2924de4c924cSGeert Uytterhoeven next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); 29250a920b5bSAndy Whitcroft 29260a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 29270a920b5bSAndy Whitcroft# more than 8 must use tabs. 2928c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 2929c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 2930c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2931d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 29323705ce5bSJoe Perches if (ERROR("CODE_INDENT", 29333705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 29343705ce5bSJoe Perches $fix) { 2935194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 29363705ce5bSJoe Perches } 29370a920b5bSAndy Whitcroft } 29380a920b5bSAndy Whitcroft 293908e44365SAlberto Panizzo# check for space before tabs. 294008e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 294108e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 29423705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 29433705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 29443705ce5bSJoe Perches $fix) { 2945194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2946d2207ccbSJoe Perches s/(^\+.*) {8,8}\t/$1\t\t/) {} 2947194f66fcSJoe Perches while ($fixed[$fixlinenr] =~ 2948c76f4cb3SJoe Perches s/(^\+.*) +\t/$1\t/) {} 29493705ce5bSJoe Perches } 295008e44365SAlberto Panizzo } 295108e44365SAlberto Panizzo 2952d1fe9c09SJoe Perches# check for && or || at the start of a line 2953d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 2954d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 2955d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 2956d1fe9c09SJoe Perches } 2957d1fe9c09SJoe Perches 2958a91e8994SJoe Perches# check indentation starts on a tab stop 2959a91e8994SJoe Perches if ($^V && $^V ge 5.10.0 && 2960a91e8994SJoe Perches $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { 2961a91e8994SJoe Perches my $indent = length($1); 2962a91e8994SJoe Perches if ($indent % 8) { 2963a91e8994SJoe Perches if (WARN("TABSTOP", 2964a91e8994SJoe Perches "Statements should start on a tabstop\n" . $herecurr) && 2965a91e8994SJoe Perches $fix) { 2966a91e8994SJoe Perches $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; 2967a91e8994SJoe Perches } 2968a91e8994SJoe Perches } 2969a91e8994SJoe Perches } 2970a91e8994SJoe Perches 2971d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 2972d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 297391cb5195SJoe Perches $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { 2974d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 2975d1fe9c09SJoe Perches my $oldindent = $1; 2976d1fe9c09SJoe Perches my $rest = $2; 2977d1fe9c09SJoe Perches 2978d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 2979d1fe9c09SJoe Perches if ($pos >= 0) { 2980b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 2981b34a26f3SJoe Perches my $newindent = $2; 2982d1fe9c09SJoe Perches 2983d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 2984d1fe9c09SJoe Perches "\t" x ($pos / 8) . 2985d1fe9c09SJoe Perches " " x ($pos % 8); 2986d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 2987d1fe9c09SJoe Perches 2988d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 2989d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 29903705ce5bSJoe Perches 29913705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 29923705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 29933705ce5bSJoe Perches $fix && $line =~ /^\+/) { 2994194f66fcSJoe Perches $fixed[$fixlinenr] =~ 29953705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 29963705ce5bSJoe Perches } 2997d1fe9c09SJoe Perches } 2998d1fe9c09SJoe Perches } 2999d1fe9c09SJoe Perches } 3000d1fe9c09SJoe Perches 30016ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar" 30026ab3a970SJoe Perches# avoid checking a few false positives: 30036ab3a970SJoe Perches# "sizeof(<type>)" or "__alignof__(<type>)" 30046ab3a970SJoe Perches# function pointer declarations like "(*foo)(int) = bar;" 30056ab3a970SJoe Perches# structure definitions like "(struct foo) { 0 };" 30066ab3a970SJoe Perches# multiline macros that define functions 30076ab3a970SJoe Perches# known attributes or the __attribute__ keyword 30086ab3a970SJoe Perches if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && 30096ab3a970SJoe Perches (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { 30103705ce5bSJoe Perches if (CHK("SPACING", 3011f27c95dbSJoe Perches "No space is necessary after a cast\n" . $herecurr) && 30123705ce5bSJoe Perches $fix) { 3013194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3014f27c95dbSJoe Perches s/(\(\s*$Type\s*\))[ \t]+/$1/; 30153705ce5bSJoe Perches } 3016aad4f614SJoe Perches } 3017aad4f614SJoe Perches 301886406b1cSJoe Perches# Block comment styles 301986406b1cSJoe Perches# Networking with an initial /* 302005880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 3021fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 302285ad978cSJoe Perches $rawline =~ /^\+[ \t]*\*/ && 302385ad978cSJoe Perches $realline > 2) { 302405880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 302505880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 302605880600SJoe Perches } 302705880600SJoe Perches 302886406b1cSJoe Perches# Block comments use * on subsequent lines 302986406b1cSJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 303086406b1cSJoe Perches $prevrawline =~ /^\+.*?\/\*/ && #starting /* 3031a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 303261135e96SJoe Perches $rawline =~ /^\+/ && #line is new 3033a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 303486406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 303586406b1cSJoe Perches "Block comments use * on subsequent lines\n" . $hereprev); 3036a605e32eSJoe Perches } 3037a605e32eSJoe Perches 303886406b1cSJoe Perches# Block comments use */ on trailing lines 303986406b1cSJoe Perches if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 3040c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 3041c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 3042c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 304386406b1cSJoe Perches WARN("BLOCK_COMMENT_STYLE", 304486406b1cSJoe Perches "Block comments use a trailing */ on a separate line\n" . $herecurr); 304505880600SJoe Perches } 304605880600SJoe Perches 304708eb9b80SJoe Perches# Block comment * alignment 304808eb9b80SJoe Perches if ($prevline =~ /$;[ \t]*$/ && #ends in comment 3049af207524SJoe Perches $line =~ /^\+[ \t]*$;/ && #leading comment 3050af207524SJoe Perches $rawline =~ /^\+[ \t]*\*/ && #leading * 3051af207524SJoe Perches (($prevrawline =~ /^\+.*?\/\*/ && #leading /* 305208eb9b80SJoe Perches $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ 3053af207524SJoe Perches $prevrawline =~ /^\+[ \t]*\*/)) { #leading * 3054af207524SJoe Perches my $oldindent; 305508eb9b80SJoe Perches $prevrawline =~ m@^\+([ \t]*/?)\*@; 3056af207524SJoe Perches if (defined($1)) { 3057af207524SJoe Perches $oldindent = expand_tabs($1); 3058af207524SJoe Perches } else { 3059af207524SJoe Perches $prevrawline =~ m@^\+(.*/?)\*@; 3060af207524SJoe Perches $oldindent = expand_tabs($1); 3061af207524SJoe Perches } 306208eb9b80SJoe Perches $rawline =~ m@^\+([ \t]*)\*@; 306308eb9b80SJoe Perches my $newindent = $1; 306408eb9b80SJoe Perches $newindent = expand_tabs($newindent); 3065af207524SJoe Perches if (length($oldindent) ne length($newindent)) { 306608eb9b80SJoe Perches WARN("BLOCK_COMMENT_STYLE", 306708eb9b80SJoe Perches "Block comments should align the * on each line\n" . $hereprev); 306808eb9b80SJoe Perches } 306908eb9b80SJoe Perches } 307008eb9b80SJoe Perches 30717f619191SJoe Perches# check for missing blank lines after struct/union declarations 30727f619191SJoe Perches# with exceptions for various attributes and macros 30737f619191SJoe Perches if ($prevline =~ /^[\+ ]};?\s*$/ && 30747f619191SJoe Perches $line =~ /^\+/ && 30757f619191SJoe Perches !($line =~ /^\+\s*$/ || 30767f619191SJoe Perches $line =~ /^\+\s*EXPORT_SYMBOL/ || 30777f619191SJoe Perches $line =~ /^\+\s*MODULE_/i || 30787f619191SJoe Perches $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || 30797f619191SJoe Perches $line =~ /^\+[a-z_]*init/ || 30807f619191SJoe Perches $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || 30817f619191SJoe Perches $line =~ /^\+\s*DECLARE/ || 30827f619191SJoe Perches $line =~ /^\+\s*__setup/)) { 3083d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3084d752fcc8SJoe Perches "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && 3085d752fcc8SJoe Perches $fix) { 3086f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3087d752fcc8SJoe Perches } 30887f619191SJoe Perches } 30897f619191SJoe Perches 3090365dd4eaSJoe Perches# check for multiple consecutive blank lines 3091365dd4eaSJoe Perches if ($prevline =~ /^[\+ ]\s*$/ && 3092365dd4eaSJoe Perches $line =~ /^\+\s*$/ && 3093365dd4eaSJoe Perches $last_blank_line != ($linenr - 1)) { 3094d752fcc8SJoe Perches if (CHK("LINE_SPACING", 3095d752fcc8SJoe Perches "Please don't use multiple blank lines\n" . $hereprev) && 3096d752fcc8SJoe Perches $fix) { 3097f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3098d752fcc8SJoe Perches } 3099d752fcc8SJoe Perches 3100365dd4eaSJoe Perches $last_blank_line = $linenr; 3101365dd4eaSJoe Perches } 3102365dd4eaSJoe Perches 31033b617e3bSJoe Perches# check for missing blank lines after declarations 31043f7bac03SJoe Perches if ($sline =~ /^\+\s+\S/ && #Not at char 1 31053f7bac03SJoe Perches # actual declarations 31063f7bac03SJoe Perches ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31075a4e1fd3SJoe Perches # function pointer declarations 31085a4e1fd3SJoe Perches $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31093f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31103f7bac03SJoe Perches $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31113f7bac03SJoe Perches # known declaration macros 31123f7bac03SJoe Perches $prevline =~ /^\+\s+$declaration_macros/) && 31133f7bac03SJoe Perches # for "else if" which can look like "$Ident $Ident" 31143f7bac03SJoe Perches !($prevline =~ /^\+\s+$c90_Keywords\b/ || 31153f7bac03SJoe Perches # other possible extensions of declaration lines 31163f7bac03SJoe Perches $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || 31173f7bac03SJoe Perches # not starting a section or a macro "\" extended line 31183f7bac03SJoe Perches $prevline =~ /(?:\{\s*|\\)$/) && 31193f7bac03SJoe Perches # looks like a declaration 31203f7bac03SJoe Perches !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || 31215a4e1fd3SJoe Perches # function pointer declarations 31225a4e1fd3SJoe Perches $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || 31233f7bac03SJoe Perches # foo bar; where foo is some local typedef or #define 31243f7bac03SJoe Perches $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || 31253f7bac03SJoe Perches # known declaration macros 31263f7bac03SJoe Perches $sline =~ /^\+\s+$declaration_macros/ || 31273f7bac03SJoe Perches # start of struct or union or enum 31283b617e3bSJoe Perches $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || 31293f7bac03SJoe Perches # start or end of block or continuation of declaration 31303f7bac03SJoe Perches $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || 31313f7bac03SJoe Perches # bitfield continuation 31323f7bac03SJoe Perches $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || 31333f7bac03SJoe Perches # other possible extensions of declaration lines 31343f7bac03SJoe Perches $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && 31353f7bac03SJoe Perches # indentation of previous and current line are the same 31363f7bac03SJoe Perches (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { 3137d752fcc8SJoe Perches if (WARN("LINE_SPACING", 3138d752fcc8SJoe Perches "Missing a blank line after declarations\n" . $hereprev) && 3139d752fcc8SJoe Perches $fix) { 3140f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, "\+"); 3141d752fcc8SJoe Perches } 31423b617e3bSJoe Perches } 31433b617e3bSJoe Perches 31445f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 31456b4c5bebSAndy Whitcroft# Exceptions: 31466b4c5bebSAndy Whitcroft# 1) within comments 31476b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 31486b4c5bebSAndy Whitcroft# 3) hanging labels 31493705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 31505f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 31513705ce5bSJoe Perches if (WARN("LEADING_SPACE", 31523705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 31533705ce5bSJoe Perches $fix) { 3154194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 31553705ce5bSJoe Perches } 31565f7ddae6SRaffaele Recalcati } 31575f7ddae6SRaffaele Recalcati 3158b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 3159b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 3160b9ea10d6SAndy Whitcroft 31614dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name 31624dbed76fSJoe Perches if ($sline =~ /^\+\{\s*$/ && 31634dbed76fSJoe Perches $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { 31644dbed76fSJoe Perches $context_function = $1; 31654dbed76fSJoe Perches } 31664dbed76fSJoe Perches 31674dbed76fSJoe Perches# check if this appears to be the end of function declaration 31684dbed76fSJoe Perches if ($sline =~ /^\+\}\s*$/) { 31694dbed76fSJoe Perches undef $context_function; 31704dbed76fSJoe Perches } 31714dbed76fSJoe Perches 3172032a4c0fSJoe Perches# check indentation of any line with a bare else 3173840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;") 3174032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more... 3175032a4c0fSJoe Perches if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { 3176032a4c0fSJoe Perches my $tabs = length($1) + 1; 3177840080a0SJoe Perches if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || 3178840080a0SJoe Perches ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && 3179840080a0SJoe Perches defined $lines[$linenr] && 3180840080a0SJoe Perches $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { 3181032a4c0fSJoe Perches WARN("UNNECESSARY_ELSE", 3182032a4c0fSJoe Perches "else is not generally useful after a break or return\n" . $hereprev); 3183032a4c0fSJoe Perches } 3184032a4c0fSJoe Perches } 3185032a4c0fSJoe Perches 3186c00df19aSJoe Perches# check indentation of a line with a break; 3187c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs 3188c00df19aSJoe Perches if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { 3189c00df19aSJoe Perches my $tabs = $1; 3190c00df19aSJoe Perches if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { 3191c00df19aSJoe Perches WARN("UNNECESSARY_BREAK", 3192c00df19aSJoe Perches "break is not useful after a goto or return\n" . $hereprev); 3193c00df19aSJoe Perches } 3194c00df19aSJoe Perches } 3195c00df19aSJoe Perches 3196c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 3197cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 3198000d1cc1SJoe Perches WARN("CVS_KEYWORD", 3199000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 3200c2fdda0dSAndy Whitcroft } 320122f2a2efSAndy Whitcroft 320242e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 320342e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 320442e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3205000d1cc1SJoe Perches ERROR("CSYNC", 3206000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 320742e41c54SMike Frysinger } 320842e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 320942e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 3210000d1cc1SJoe Perches ERROR("SSYNC", 3211000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 321242e41c54SMike Frysinger } 321342e41c54SMike Frysinger 321456e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 321556e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 321656e77d70SJoe Perches WARN("HOTPLUG_SECTION", 321756e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 321856e77d70SJoe Perches } 321956e77d70SJoe Perches 32209c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 32212b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 32222b474a1aSAndy Whitcroft $realline_next); 32233e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 3224ca819864SJoe Perches if ($linenr > $suppress_statement && 32251b5539b1SJoe Perches $realcnt && $sline =~ /.\s*\S/) { 3226170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 3227f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3228171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 3229171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 3230171ae1a4SAndy Whitcroft 32313e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 32323e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 32333e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 32343e469cdcSAndy Whitcroft # until we hit end of it. 32353e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 32363e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 32373e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 32383e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 32393e469cdcSAndy Whitcroft } 3240f74bd194SAndy Whitcroft 32412b474a1aSAndy Whitcroft # Find the real next line. 32422b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 32432b474a1aSAndy Whitcroft if (defined $realline_next && 32442b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 32452b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 32462b474a1aSAndy Whitcroft $realline_next++; 32472b474a1aSAndy Whitcroft } 32482b474a1aSAndy Whitcroft 3249171ae1a4SAndy Whitcroft my $s = $stat; 3250171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 3251cf655043SAndy Whitcroft 3252c2fdda0dSAndy Whitcroft # Ignore goto labels. 3253171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 3254c2fdda0dSAndy Whitcroft 3255c2fdda0dSAndy Whitcroft # Ignore functions being called 3256171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 3257c2fdda0dSAndy Whitcroft 3258463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 3259463f2864SAndy Whitcroft 3260c45dcabdSAndy Whitcroft # declarations always start with types 3261d2506586SAndy 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) { 3262c45dcabdSAndy Whitcroft my $type = $1; 3263c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 3264c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 3265c45dcabdSAndy Whitcroft 32666c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 3267a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 3268c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 3269c2fdda0dSAndy Whitcroft } 32708905a67cSAndy Whitcroft 32716c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 327265863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 3273c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 32749c0ca6f9SAndy Whitcroft } 32758905a67cSAndy Whitcroft 32768905a67cSAndy Whitcroft # Check for any sort of function declaration. 32778905a67cSAndy Whitcroft # int foo(something bar, other baz); 32788905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 3279171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 32808905a67cSAndy Whitcroft my ($name_len) = length($1); 32818905a67cSAndy Whitcroft 3282cf655043SAndy Whitcroft my $ctx = $s; 3283773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 32848905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 3285cf655043SAndy Whitcroft 32868905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 3287c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 32888905a67cSAndy Whitcroft 3289c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 32908905a67cSAndy Whitcroft } 32918905a67cSAndy Whitcroft } 32928905a67cSAndy Whitcroft } 32938905a67cSAndy Whitcroft 32949c0ca6f9SAndy Whitcroft } 32959c0ca6f9SAndy Whitcroft 329600df344fSAndy Whitcroft# 329700df344fSAndy Whitcroft# Checks which may be anchored in the context. 329800df344fSAndy Whitcroft# 329900df344fSAndy Whitcroft 330000df344fSAndy Whitcroft# Check for switch () and associated case and default 330100df344fSAndy Whitcroft# statements should be at the same indent. 330200df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 330300df344fSAndy Whitcroft my $err = ''; 330400df344fSAndy Whitcroft my $sep = ''; 330500df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 330600df344fSAndy Whitcroft shift(@ctx); 330700df344fSAndy Whitcroft for my $ctx (@ctx) { 330800df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 330900df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 331000df344fSAndy Whitcroft $indent != $cindent) { 331100df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 331200df344fSAndy Whitcroft $sep = ''; 331300df344fSAndy Whitcroft } else { 331400df344fSAndy Whitcroft $sep = "[...]\n"; 331500df344fSAndy Whitcroft } 331600df344fSAndy Whitcroft } 331700df344fSAndy Whitcroft if ($err ne '') { 3318000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 3319000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 3320de7d4f0eSAndy Whitcroft } 3321de7d4f0eSAndy Whitcroft } 3322de7d4f0eSAndy Whitcroft 3323de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 3324de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 33250fe3dc2bSJoe Perches if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 3326773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 3327773647a0SAndy Whitcroft 33289c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 33298eef05ddSJoe Perches 33308eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 33318eef05ddSJoe Perches WARN("DEEP_INDENTATION", 33328eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 33338eef05ddSJoe Perches } 33348eef05ddSJoe Perches 3335de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 3336de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 3337de7d4f0eSAndy Whitcroft 3338548596d5SAndy Whitcroft my $ctx_ln = $linenr; 3339548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 3340de7d4f0eSAndy Whitcroft 3341548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 3342548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 3343548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 3344548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 3345548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 3346773647a0SAndy Whitcroft $ctx_ln++; 3347773647a0SAndy Whitcroft } 3348548596d5SAndy Whitcroft 334953210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 335053210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 3351773647a0SAndy Whitcroft 3352773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 3353000d1cc1SJoe Perches ERROR("OPEN_BRACE", 3354000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 335501464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 335600df344fSAndy Whitcroft } 3357773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 3358773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 3359773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 3360773647a0SAndy Whitcroft { 33619c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 33629c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 3363000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 3364000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 336501464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 33669c0ca6f9SAndy Whitcroft } 33679c0ca6f9SAndy Whitcroft } 336800df344fSAndy Whitcroft } 336900df344fSAndy Whitcroft 33704d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 3371f6950a73SJoe Perches if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 33723e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 33733e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 33743e469cdcSAndy Whitcroft if (!defined $stat); 33754d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 33764d001e4dSAndy Whitcroft 33774d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 33784d001e4dSAndy Whitcroft 33799f5af480SJoe Perches # remove inline comments 33809f5af480SJoe Perches $s =~ s/$;/ /g; 33819f5af480SJoe Perches $c =~ s/$;/ /g; 33824d001e4dSAndy Whitcroft 33834d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 33846f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 33856f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 33864d001e4dSAndy Whitcroft 33879f5af480SJoe Perches # Make sure we remove the line prefixes as we have 33889f5af480SJoe Perches # none on the first line, and are going to readd them 33899f5af480SJoe Perches # where necessary. 33909f5af480SJoe Perches $s =~ s/\n./\n/gs; 33919f5af480SJoe Perches while ($s =~ /\n\s+\\\n/) { 33929f5af480SJoe Perches $cond_lines += $s =~ s/\n\s+\\\n/\n/g; 33939f5af480SJoe Perches } 33949f5af480SJoe Perches 33954d001e4dSAndy Whitcroft # We want to check the first line inside the block 33964d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 33974d001e4dSAndy Whitcroft # 1) any blank line termination 33984d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 33994d001e4dSAndy Whitcroft # 3) any do (...) { 34004d001e4dSAndy Whitcroft my $continuation = 0; 34014d001e4dSAndy Whitcroft my $check = 0; 34024d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 34034d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 34044d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 34054d001e4dSAndy Whitcroft $continuation = 1; 34064d001e4dSAndy Whitcroft } 34079bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 34084d001e4dSAndy Whitcroft $check = 1; 34094d001e4dSAndy Whitcroft $cond_lines++; 34104d001e4dSAndy Whitcroft } 34114d001e4dSAndy Whitcroft 34124d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 34134d001e4dSAndy Whitcroft # preprocessor statement. 34144d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 34154d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 34164d001e4dSAndy Whitcroft $check = 0; 34174d001e4dSAndy Whitcroft } 34184d001e4dSAndy Whitcroft 34199bd49efeSAndy Whitcroft my $cond_ptr = -1; 3420740504c6SAndy Whitcroft $continuation = 0; 34219bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 34229bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 34234d001e4dSAndy Whitcroft 3424f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 3425f16fa28fSAndy Whitcroft # is not linear. 3426f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 3427f16fa28fSAndy Whitcroft $check = 0; 3428f16fa28fSAndy Whitcroft } 3429f16fa28fSAndy Whitcroft 34309bd49efeSAndy Whitcroft # Ignore: 34319bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 34329bd49efeSAndy Whitcroft # 2) preprocessor lines, and 34339bd49efeSAndy Whitcroft # 3) labels. 3434740504c6SAndy Whitcroft if ($continuation || 3435740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 34369bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 34379bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 3438740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 343930dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 34409bd49efeSAndy Whitcroft $cond_lines++; 34419bd49efeSAndy Whitcroft } 34424d001e4dSAndy Whitcroft } 344330dad6ebSAndy Whitcroft } 34444d001e4dSAndy Whitcroft 34454d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 34464d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 34474d001e4dSAndy Whitcroft 34484d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 34494d001e4dSAndy Whitcroft # this is not this patch's fault. 34504d001e4dSAndy Whitcroft if (!defined($stat_real) || 34514d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 34524d001e4dSAndy Whitcroft $check = 0; 34534d001e4dSAndy Whitcroft } 34544d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 34554d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 34564d001e4dSAndy Whitcroft } 34574d001e4dSAndy Whitcroft 34589bd49efeSAndy 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"; 34594d001e4dSAndy Whitcroft 34609f5af480SJoe Perches if ($check && $s ne '' && 34619f5af480SJoe Perches (($sindent % 8) != 0 || 34629f5af480SJoe Perches ($sindent < $indent) || 3463f6950a73SJoe Perches ($sindent == $indent && 3464f6950a73SJoe Perches ($s !~ /^\s*(?:\}|\{|else\b)/)) || 34659f5af480SJoe Perches ($sindent > $indent + 8))) { 3466000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 3467000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 34684d001e4dSAndy Whitcroft } 34694d001e4dSAndy Whitcroft } 34704d001e4dSAndy Whitcroft 34716c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 34726c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 34731f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 34741f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 34756c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 3476c2fdda0dSAndy Whitcroft if ($dbg_values) { 3477c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 3478cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 3479cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 34801f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 3481c2fdda0dSAndy Whitcroft } 34826c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 34836c72ffaaSAndy Whitcroft 348400df344fSAndy Whitcroft#ignore lines not being added 34853705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 348600df344fSAndy Whitcroft 348711ca40a0SJoe Perches# check for dereferences that span multiple lines 348811ca40a0SJoe Perches if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && 348911ca40a0SJoe Perches $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { 349011ca40a0SJoe Perches $prevline =~ /($Lval\s*(?:\.|->))\s*$/; 349111ca40a0SJoe Perches my $ref = $1; 349211ca40a0SJoe Perches $line =~ /^.\s*($Lval)/; 349311ca40a0SJoe Perches $ref .= $1; 349411ca40a0SJoe Perches $ref =~ s/\s//g; 349511ca40a0SJoe Perches WARN("MULTILINE_DEREFERENCE", 349611ca40a0SJoe Perches "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); 349711ca40a0SJoe Perches } 349811ca40a0SJoe Perches 3499a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int 3500c8447115SJoe Perches while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { 3501a1ce18e4SJoe Perches my $type = $1; 3502a1ce18e4SJoe Perches my $var = $2; 3503207a8e84SJoe Perches $var = "" if (!defined $var); 3504207a8e84SJoe Perches if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { 3505a1ce18e4SJoe Perches my $sign = $1; 3506a1ce18e4SJoe Perches my $pointer = $2; 3507a1ce18e4SJoe Perches 3508a1ce18e4SJoe Perches $pointer = "" if (!defined $pointer); 3509a1ce18e4SJoe Perches 3510a1ce18e4SJoe Perches if (WARN("UNSPECIFIED_INT", 3511a1ce18e4SJoe Perches "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && 3512a1ce18e4SJoe Perches $fix) { 3513a1ce18e4SJoe Perches my $decl = trim($sign) . " int "; 3514207a8e84SJoe Perches my $comp_pointer = $pointer; 3515207a8e84SJoe Perches $comp_pointer =~ s/\s//g; 3516207a8e84SJoe Perches $decl .= $comp_pointer; 3517207a8e84SJoe Perches $decl = rtrim($decl) if ($var eq ""); 3518207a8e84SJoe Perches $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; 3519a1ce18e4SJoe Perches } 3520a1ce18e4SJoe Perches } 3521a1ce18e4SJoe Perches } 3522a1ce18e4SJoe Perches 3523653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 35247429c690SAndy Whitcroft if ($dbg_type) { 35257429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 3526000d1cc1SJoe Perches ERROR("TEST_TYPE", 3527000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 35287429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 3529000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 3530000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 35317429c690SAndy Whitcroft } 3532653d4876SAndy Whitcroft next; 3533653d4876SAndy Whitcroft } 3534a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 3535a1ef277eSAndy Whitcroft if ($dbg_attr) { 35369360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 3537000d1cc1SJoe Perches ERROR("TEST_ATTR", 3538000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 35399360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 3540000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 3541000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 3542a1ef277eSAndy Whitcroft } 3543a1ef277eSAndy Whitcroft next; 3544a1ef277eSAndy Whitcroft } 3545653d4876SAndy Whitcroft 3546f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 354799423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 354899423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 3549d752fcc8SJoe Perches if (ERROR("OPEN_BRACE", 3550d752fcc8SJoe Perches "that open brace { should be on the previous line\n" . $hereprev) && 3551f2d7e4d4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 3552f2d7e4d4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 3553f2d7e4d4SJoe Perches fix_delete_line($fixlinenr, $rawline); 3554d752fcc8SJoe Perches my $fixedline = $prevrawline; 3555d752fcc8SJoe Perches $fixedline =~ s/\s*=\s*$/ = {/; 3556f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3557d752fcc8SJoe Perches $fixedline = $line; 3558*8d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1/; 3559f2d7e4d4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 3560d752fcc8SJoe Perches } 3561f0a594c1SAndy Whitcroft } 3562f0a594c1SAndy Whitcroft 356300df344fSAndy Whitcroft# 356400df344fSAndy Whitcroft# Checks which are anchored on the added line. 356500df344fSAndy Whitcroft# 356600df344fSAndy Whitcroft 3567653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 3568c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 3569653d4876SAndy Whitcroft my $path = $1; 3570653d4876SAndy Whitcroft if ($path =~ m{//}) { 3571000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 3572495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 3573495e9d84SJoe Perches } 3574495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 3575495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 3576495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 3577653d4876SAndy Whitcroft } 3578653d4876SAndy Whitcroft } 3579653d4876SAndy Whitcroft 358000df344fSAndy Whitcroft# no C99 // comments 358100df344fSAndy Whitcroft if ($line =~ m{//}) { 35823705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 35833705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 35843705ce5bSJoe Perches $fix) { 3585194f66fcSJoe Perches my $line = $fixed[$fixlinenr]; 35863705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 35873705ce5bSJoe Perches my $comment = trim($1); 3588194f66fcSJoe Perches $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; 35893705ce5bSJoe Perches } 35903705ce5bSJoe Perches } 359100df344fSAndy Whitcroft } 359200df344fSAndy Whitcroft # Remove C99 comments. 35930a920b5bSAndy Whitcroft $line =~ s@//.*@@; 35946c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 35950a920b5bSAndy Whitcroft 35962b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 35972b474a1aSAndy Whitcroft# the whole statement. 35982b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 35992b474a1aSAndy Whitcroft if (defined $realline_next && 36002b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 36012b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 36022b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36032b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36043cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 36053cbf62dfSAndy Whitcroft # a prefix: 36063cbf62dfSAndy Whitcroft # XXX(foo); 36073cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 3608653d4876SAndy Whitcroft my $name = $1; 360987a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 36103cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 36113cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 36123cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 36133cbf62dfSAndy Whitcroft 36143cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 36152b474a1aSAndy Whitcroft \n.}\s*$| 361648012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 361748012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 361848012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 36192b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 36202b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 362148012058SAndy Whitcroft )/x) { 36222b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 36232b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 36242b474a1aSAndy Whitcroft } else { 36252b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 36260a920b5bSAndy Whitcroft } 36270a920b5bSAndy Whitcroft } 36282b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 36292b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 36302b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 36312b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 36322b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 36332b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 36342b474a1aSAndy Whitcroft } 36352b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 36362b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 3637000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 3638000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 36392b474a1aSAndy Whitcroft } 36400a920b5bSAndy Whitcroft 36415150bda4SJoe Eloff# check for global initialisers. 36426d32f7a3SJoe Perches if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { 3643d5e616fcSJoe Perches if (ERROR("GLOBAL_INITIALISERS", 36446d32f7a3SJoe Perches "do not initialise globals to $1\n" . $herecurr) && 3645d5e616fcSJoe Perches $fix) { 36466d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; 3647d5e616fcSJoe Perches } 3648f0a594c1SAndy Whitcroft } 36490a920b5bSAndy Whitcroft# check for static initialisers. 36506d32f7a3SJoe Perches if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { 3651d5e616fcSJoe Perches if (ERROR("INITIALISED_STATIC", 36526d32f7a3SJoe Perches "do not initialise statics to $1\n" . 3653d5e616fcSJoe Perches $herecurr) && 3654d5e616fcSJoe Perches $fix) { 36556d32f7a3SJoe Perches $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; 3656d5e616fcSJoe Perches } 36570a920b5bSAndy Whitcroft } 36580a920b5bSAndy Whitcroft 36591813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned 36601813087dSJoe Perches while ($sline =~ m{(\b$TypeMisordered\b)}g) { 36611813087dSJoe Perches my $tmp = trim($1); 36621813087dSJoe Perches WARN("MISORDERED_TYPE", 36631813087dSJoe Perches "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); 36641813087dSJoe Perches } 36651813087dSJoe Perches 3666cb710ecaSJoe Perches# check for static const char * arrays. 3667cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 3668000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3669000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 3670cb710ecaSJoe Perches $herecurr); 3671cb710ecaSJoe Perches } 3672cb710ecaSJoe Perches 3673cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 3674cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 3675000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 3676000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 3677cb710ecaSJoe Perches $herecurr); 3678cb710ecaSJoe Perches } 3679cb710ecaSJoe Perches 3680ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type 3681ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { 3682ab7e23f3SJoe Perches my $found = $1; 3683ab7e23f3SJoe Perches if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { 3684ab7e23f3SJoe Perches WARN("CONST_CONST", 3685ab7e23f3SJoe Perches "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); 3686ab7e23f3SJoe Perches } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { 3687ab7e23f3SJoe Perches WARN("CONST_CONST", 3688ab7e23f3SJoe Perches "'const $found const' should probably be 'const $found'\n" . $herecurr); 3689ab7e23f3SJoe Perches } 3690ab7e23f3SJoe Perches } 3691ab7e23f3SJoe Perches 36929b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations. 36939b0fa60dSJoe Perches if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { 36949b0fa60dSJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 36959b0fa60dSJoe Perches "char * array declaration might be better as static const\n" . 36969b0fa60dSJoe Perches $herecurr); 36979b0fa60dSJoe Perches } 36989b0fa60dSJoe Perches 3699b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) 3700b598b670SJoe Perches if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { 3701b598b670SJoe Perches my $array = $1; 3702b598b670SJoe 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*\))@) { 3703b598b670SJoe Perches my $array_div = $1; 3704b598b670SJoe Perches if (WARN("ARRAY_SIZE", 3705b598b670SJoe Perches "Prefer ARRAY_SIZE($array)\n" . $herecurr) && 3706b598b670SJoe Perches $fix) { 3707b598b670SJoe Perches $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; 3708b598b670SJoe Perches } 3709b598b670SJoe Perches } 3710b598b670SJoe Perches } 3711b598b670SJoe Perches 3712b36190c5SJoe Perches# check for function declarations without arguments like "int foo()" 3713b36190c5SJoe Perches if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { 3714b36190c5SJoe Perches if (ERROR("FUNCTION_WITHOUT_ARGS", 3715b36190c5SJoe Perches "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && 3716b36190c5SJoe Perches $fix) { 3717194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; 3718b36190c5SJoe Perches } 3719b36190c5SJoe Perches } 3720b36190c5SJoe Perches 3721653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 3722653d4876SAndy Whitcroft# make sense. 3723653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 37248054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 3725c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 37268ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 372746d832f5SMichael S. Tsirkin $line !~ /\b__bitwise\b/) { 3728000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 3729000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 37300a920b5bSAndy Whitcroft } 37310a920b5bSAndy Whitcroft 37320a920b5bSAndy Whitcroft# * goes on variable not on type 373365863862SAndy Whitcroft # (char*[ const]) 3734bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 3735bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 37363705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 3737d8aaf121SAndy Whitcroft 373865863862SAndy Whitcroft # Should start with a space. 373965863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 374065863862SAndy Whitcroft # Should not end with a space. 374165863862SAndy Whitcroft $to =~ s/\s+$//; 374265863862SAndy Whitcroft # '*'s should not have spaces between. 3743f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 374465863862SAndy Whitcroft } 3745d8aaf121SAndy Whitcroft 37463705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 374765863862SAndy Whitcroft if ($from ne $to) { 37483705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37493705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 37503705ce5bSJoe Perches $fix) { 37513705ce5bSJoe Perches my $sub_from = $ident; 37523705ce5bSJoe Perches my $sub_to = $ident; 37533705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3754194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37553705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37563705ce5bSJoe Perches } 375765863862SAndy Whitcroft } 3758bfcb2cc7SAndy Whitcroft } 3759bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 3760bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 37613705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 3762d8aaf121SAndy Whitcroft 376365863862SAndy Whitcroft # Should start with a space. 376465863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 376565863862SAndy Whitcroft # Should not end with a space. 376665863862SAndy Whitcroft $to =~ s/\s+$//; 376765863862SAndy Whitcroft # '*'s should not have spaces between. 3768f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 376965863862SAndy Whitcroft } 377065863862SAndy Whitcroft # Modifiers should have spaces. 377165863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 377265863862SAndy Whitcroft 37733705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 3774667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 37753705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 37763705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 37773705ce5bSJoe Perches $fix) { 37783705ce5bSJoe Perches 37793705ce5bSJoe Perches my $sub_from = $match; 37803705ce5bSJoe Perches my $sub_to = $match; 37813705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 3782194f66fcSJoe Perches $fixed[$fixlinenr] =~ 37833705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 37843705ce5bSJoe Perches } 378565863862SAndy Whitcroft } 37860a920b5bSAndy Whitcroft } 37870a920b5bSAndy Whitcroft 37889d3e3c70SJoe Perches# avoid BUG() or BUG_ON() 37899d3e3c70SJoe Perches if ($line =~ /\b(?:BUG|BUG_ON)\b/) { 37909d3e3c70SJoe Perches my $msg_type = \&WARN; 37919d3e3c70SJoe Perches $msg_type = \&CHK if ($file); 37929d3e3c70SJoe Perches &{$msg_type}("AVOID_BUG", 37939d3e3c70SJoe Perches "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); 37949d3e3c70SJoe Perches } 37950a920b5bSAndy Whitcroft 37969d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE 37978905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 3798000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 3799000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 38008905a67cSAndy Whitcroft } 38018905a67cSAndy Whitcroft 380217441227SJoe Perches# check for uses of printk_ratelimit 380317441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 3804000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 3805000d1cc1SJoe Perches "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 380617441227SJoe Perches } 380717441227SJoe Perches 380800df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 380900df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 381000df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 381125985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 381200df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 3813f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 381400df344fSAndy Whitcroft my $ok = 0; 381500df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 381600df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 381725985edcSLucas De Marchi # we have a preceding printk if it ends 381800df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 381900df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 382000df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 382100df344fSAndy Whitcroft $ok = 1; 382200df344fSAndy Whitcroft } 382300df344fSAndy Whitcroft last; 382400df344fSAndy Whitcroft } 382500df344fSAndy Whitcroft } 382600df344fSAndy Whitcroft if ($ok == 0) { 3827000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 3828000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 38290a920b5bSAndy Whitcroft } 383000df344fSAndy Whitcroft } 38310a920b5bSAndy Whitcroft 3832243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 3833243f3803SJoe Perches my $orig = $1; 3834243f3803SJoe Perches my $level = lc($orig); 3835243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 38368f26b837SJoe Perches my $level2 = $level; 38378f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 3838243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 3839daa8b059SYogesh Chaudhari "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 3840243f3803SJoe Perches } 3841243f3803SJoe Perches 3842243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 3843d5e616fcSJoe Perches if (WARN("PREFER_PR_LEVEL", 3844d5e616fcSJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && 3845d5e616fcSJoe Perches $fix) { 3846194f66fcSJoe Perches $fixed[$fixlinenr] =~ 3847d5e616fcSJoe Perches s/\bpr_warning\b/pr_warn/; 3848d5e616fcSJoe Perches } 3849243f3803SJoe Perches } 3850243f3803SJoe Perches 3851dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 3852dc139313SJoe Perches my $orig = $1; 3853dc139313SJoe Perches my $level = lc($orig); 3854dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 3855dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 3856dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 3857dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 3858dc139313SJoe Perches } 3859dc139313SJoe Perches 386091c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else. This will have a small 386191c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at 386291c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning. 386391c9afafSAndy Lutomirski if ($line =~ /\bENOSYS\b/) { 386491c9afafSAndy Lutomirski WARN("ENOSYS", 386591c9afafSAndy Lutomirski "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); 386691c9afafSAndy Lutomirski } 386791c9afafSAndy Lutomirski 3868653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 3869653d4876SAndy Whitcroft# or if closed on same line 38708d182478SJoe Perches if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and 38714e5d56bdSEddie Kovsky !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { 38728d182478SJoe Perches if (ERROR("OPEN_BRACE", 38738d182478SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr) && 38748d182478SJoe Perches $fix) { 38758d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38768d182478SJoe Perches my $fixed_line = $rawline; 38778d182478SJoe Perches $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/; 38788d182478SJoe Perches my $line1 = $1; 38798d182478SJoe Perches my $line2 = $2; 38808d182478SJoe Perches fix_insert_line($fixlinenr, ltrim($line1)); 38818d182478SJoe Perches fix_insert_line($fixlinenr, "\+{"); 38828d182478SJoe Perches if ($line2 !~ /^\s*$/) { 38838d182478SJoe Perches fix_insert_line($fixlinenr, "\+\t" . trim($line2)); 38848d182478SJoe Perches } 38858d182478SJoe Perches } 38860a920b5bSAndy Whitcroft } 3887653d4876SAndy Whitcroft 38888905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 38898905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 38908905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 38918d182478SJoe Perches if (ERROR("OPEN_BRACE", 38928d182478SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev) && 38938d182478SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 38948d182478SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 38958d182478SJoe Perches fix_delete_line($fixlinenr, $rawline); 38968d182478SJoe Perches my $fixedline = rtrim($prevrawline) . " {"; 38978d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 38988d182478SJoe Perches $fixedline = $rawline; 3899*8d81ae05SCyril Bur $fixedline =~ s/^(.\s*)\{\s*/$1\t/; 39008d182478SJoe Perches if ($fixedline !~ /^\+\s*$/) { 39018d182478SJoe Perches fix_insert_line($fixlinenr, $fixedline); 39028d182478SJoe Perches } 39038d182478SJoe Perches } 39048905a67cSAndy Whitcroft } 39058905a67cSAndy Whitcroft 39060c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 39073705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 39083705ce5bSJoe Perches if (WARN("SPACING", 39093705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 39103705ce5bSJoe Perches $fix) { 3911194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39123705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 39133705ce5bSJoe Perches } 39140c73b4ebSAndy Whitcroft } 39150c73b4ebSAndy Whitcroft 391631070b5dSJoe Perches# Function pointer declarations 391731070b5dSJoe Perches# check spacing between type, funcptr, and args 391831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)" 391991f72e9cSJoe Perches if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { 392031070b5dSJoe Perches my $declare = $1; 392131070b5dSJoe Perches my $pre_pointer_space = $2; 392231070b5dSJoe Perches my $post_pointer_space = $3; 392331070b5dSJoe Perches my $funcname = $4; 392431070b5dSJoe Perches my $post_funcname_space = $5; 392531070b5dSJoe Perches my $pre_args_space = $6; 392631070b5dSJoe Perches 392791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type 392891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types 392991f72e9cSJoe Perches# don't need a space so don't warn for those. 393091f72e9cSJoe Perches my $post_declare_space = ""; 393191f72e9cSJoe Perches if ($declare =~ /(\s+)$/) { 393291f72e9cSJoe Perches $post_declare_space = $1; 393391f72e9cSJoe Perches $declare = rtrim($declare); 393491f72e9cSJoe Perches } 393591f72e9cSJoe Perches if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { 393631070b5dSJoe Perches WARN("SPACING", 393731070b5dSJoe Perches "missing space after return type\n" . $herecurr); 393891f72e9cSJoe Perches $post_declare_space = " "; 393931070b5dSJoe Perches } 394031070b5dSJoe Perches 394131070b5dSJoe Perches# unnecessary space "type (*funcptr)(args...)" 394291f72e9cSJoe Perches# This test is not currently implemented because these declarations are 394391f72e9cSJoe Perches# equivalent to 394491f72e9cSJoe Perches# int foo(int bar, ...) 394591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning. 394691f72e9cSJoe Perches# 394791f72e9cSJoe Perches# elsif ($declare =~ /\s{2,}$/) { 394891f72e9cSJoe Perches# WARN("SPACING", 394991f72e9cSJoe Perches# "Multiple spaces after return type\n" . $herecurr); 395091f72e9cSJoe Perches# } 395131070b5dSJoe Perches 395231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)" 395331070b5dSJoe Perches if (defined $pre_pointer_space && 395431070b5dSJoe Perches $pre_pointer_space =~ /^\s/) { 395531070b5dSJoe Perches WARN("SPACING", 395631070b5dSJoe Perches "Unnecessary space after function pointer open parenthesis\n" . $herecurr); 395731070b5dSJoe Perches } 395831070b5dSJoe Perches 395931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)" 396031070b5dSJoe Perches if (defined $post_pointer_space && 396131070b5dSJoe Perches $post_pointer_space =~ /^\s/) { 396231070b5dSJoe Perches WARN("SPACING", 396331070b5dSJoe Perches "Unnecessary space before function pointer name\n" . $herecurr); 396431070b5dSJoe Perches } 396531070b5dSJoe Perches 396631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)" 396731070b5dSJoe Perches if (defined $post_funcname_space && 396831070b5dSJoe Perches $post_funcname_space =~ /^\s/) { 396931070b5dSJoe Perches WARN("SPACING", 397031070b5dSJoe Perches "Unnecessary space after function pointer name\n" . $herecurr); 397131070b5dSJoe Perches } 397231070b5dSJoe Perches 397331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)" 397431070b5dSJoe Perches if (defined $pre_args_space && 397531070b5dSJoe Perches $pre_args_space =~ /^\s/) { 397631070b5dSJoe Perches WARN("SPACING", 397731070b5dSJoe Perches "Unnecessary space before function pointer arguments\n" . $herecurr); 397831070b5dSJoe Perches } 397931070b5dSJoe Perches 398031070b5dSJoe Perches if (show_type("SPACING") && $fix) { 3981194f66fcSJoe Perches $fixed[$fixlinenr] =~ 398291f72e9cSJoe Perches s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; 398331070b5dSJoe Perches } 398431070b5dSJoe Perches } 398531070b5dSJoe Perches 39868d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 39878d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 3988fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 3989fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 39908d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 39918d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 39928d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 3993fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 3994daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 39953705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 39963705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 39973705ce5bSJoe Perches $fix) { 3998194f66fcSJoe Perches $fixed[$fixlinenr] =~ 39993705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 40003705ce5bSJoe Perches } 40018d31cfceSAndy Whitcroft } 40028d31cfceSAndy Whitcroft } 40038d31cfceSAndy Whitcroft 4004f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 40056c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 4006c2fdda0dSAndy Whitcroft my $name = $1; 4007773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 4008773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 4009c2fdda0dSAndy Whitcroft 4010c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 4011773647a0SAndy Whitcroft if ($name =~ /^(?: 4012773647a0SAndy Whitcroft if|for|while|switch|return|case| 4013773647a0SAndy Whitcroft volatile|__volatile__| 4014773647a0SAndy Whitcroft __attribute__|format|__extension__| 4015773647a0SAndy Whitcroft asm|__asm__)$/x) 4016773647a0SAndy Whitcroft { 4017c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 4018c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 4019c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 4020c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 4021773647a0SAndy Whitcroft 4022773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 4023c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 4024c2fdda0dSAndy Whitcroft 4025c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 4026c2fdda0dSAndy Whitcroft # likely a typedef for a function. 4027773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 4028c2fdda0dSAndy Whitcroft 4029c2fdda0dSAndy Whitcroft } else { 40303705ce5bSJoe Perches if (WARN("SPACING", 40313705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 40323705ce5bSJoe Perches $fix) { 4033194f66fcSJoe Perches $fixed[$fixlinenr] =~ 40343705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 40353705ce5bSJoe Perches } 4036f0a594c1SAndy Whitcroft } 40376c72ffaaSAndy Whitcroft } 40389a4cad4eSEric Nelson 4039653d4876SAndy Whitcroft# Check operator spacing. 40400a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 40413705ce5bSJoe Perches my $fixed_line = ""; 40423705ce5bSJoe Perches my $line_fixed = 0; 40433705ce5bSJoe Perches 40449c0ca6f9SAndy Whitcroft my $ops = qr{ 40459c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 40469c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 40479c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 40481f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 404984731623SJoe Perches \?:|\?|: 40509c0ca6f9SAndy Whitcroft }x; 4051cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 40523705ce5bSJoe Perches 40533705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 40543705ce5bSJoe Perches## foreach my $el (@elements) { 40553705ce5bSJoe Perches## print("el: <$el>\n"); 40563705ce5bSJoe Perches## } 40573705ce5bSJoe Perches 40583705ce5bSJoe Perches my @fix_elements = (); 405900df344fSAndy Whitcroft my $off = 0; 40606c72ffaaSAndy Whitcroft 40613705ce5bSJoe Perches foreach my $el (@elements) { 40623705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 40633705ce5bSJoe Perches $off += length($el); 40643705ce5bSJoe Perches } 40653705ce5bSJoe Perches 40663705ce5bSJoe Perches $off = 0; 40673705ce5bSJoe Perches 40686c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 4069b34c648bSJoe Perches my $last_after = -1; 40706c72ffaaSAndy Whitcroft 40710a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 40723705ce5bSJoe Perches 40733705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 40743705ce5bSJoe Perches 40753705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 40763705ce5bSJoe Perches 40774a0df2efSAndy Whitcroft $off += length($elements[$n]); 40784a0df2efSAndy Whitcroft 407925985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 4080773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 4081773647a0SAndy Whitcroft my $cc = ''; 4082773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 4083773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 4084773647a0SAndy Whitcroft } 4085773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 4086773647a0SAndy Whitcroft 40874a0df2efSAndy Whitcroft my $a = ''; 40884a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 40894a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 4090cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 40914a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 40924a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 4093773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 40944a0df2efSAndy Whitcroft 40950a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 40964a0df2efSAndy Whitcroft 40974a0df2efSAndy Whitcroft my $c = ''; 40980a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 40994a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 41004a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 4101cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 41024a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 41034a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 41048b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 41054a0df2efSAndy Whitcroft } else { 41064a0df2efSAndy Whitcroft $c = 'E'; 41070a920b5bSAndy Whitcroft } 41080a920b5bSAndy Whitcroft 41094a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 41104a0df2efSAndy Whitcroft 41114a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 41124a0df2efSAndy Whitcroft 41136c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 4114de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 41150a920b5bSAndy Whitcroft 411674048ed8SAndy Whitcroft # Pull out the value of this operator. 41176c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 41180a920b5bSAndy Whitcroft 41191f65f947SAndy Whitcroft # Get the full operator variant. 41201f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 41211f65f947SAndy Whitcroft 412213214adfSAndy Whitcroft # Ignore operators passed as parameters. 412313214adfSAndy Whitcroft if ($op_type ne 'V' && 4124d7fe8065SSam Bobroff $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { 412513214adfSAndy Whitcroft 4126cf655043SAndy Whitcroft# # Ignore comments 4127cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 412813214adfSAndy Whitcroft 4129d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 413013214adfSAndy Whitcroft } elsif ($op eq ';') { 4131cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 4132cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 41333705ce5bSJoe Perches if (ERROR("SPACING", 41343705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 4135b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 41363705ce5bSJoe Perches $line_fixed = 1; 41373705ce5bSJoe Perches } 4138d8aaf121SAndy Whitcroft } 4139d8aaf121SAndy Whitcroft 4140d8aaf121SAndy Whitcroft # // is a comment 4141d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 41420a920b5bSAndy Whitcroft 4143b00e4814SJoe Perches # : when part of a bitfield 4144b00e4814SJoe Perches } elsif ($opv eq ':B') { 4145b00e4814SJoe Perches # skip the bitfield test for now 4146b00e4814SJoe Perches 41471f65f947SAndy Whitcroft # No spaces for: 41481f65f947SAndy Whitcroft # -> 4149b00e4814SJoe Perches } elsif ($op eq '->') { 41504a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 41513705ce5bSJoe Perches if (ERROR("SPACING", 41523705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 4153b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41543705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 41553705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 41563705ce5bSJoe Perches } 4157b34c648bSJoe Perches $line_fixed = 1; 41583705ce5bSJoe Perches } 41590a920b5bSAndy Whitcroft } 41600a920b5bSAndy Whitcroft 41612381097bSJoe Perches # , must not have a space before and must have a space on the right. 41620a920b5bSAndy Whitcroft } elsif ($op eq ',') { 41632381097bSJoe Perches my $rtrim_before = 0; 41642381097bSJoe Perches my $space_after = 0; 41652381097bSJoe Perches if ($ctx =~ /Wx./) { 41662381097bSJoe Perches if (ERROR("SPACING", 41672381097bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 41682381097bSJoe Perches $line_fixed = 1; 41692381097bSJoe Perches $rtrim_before = 1; 41702381097bSJoe Perches } 41712381097bSJoe Perches } 4172cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 41733705ce5bSJoe Perches if (ERROR("SPACING", 41743705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 41753705ce5bSJoe Perches $line_fixed = 1; 4176b34c648bSJoe Perches $last_after = $n; 41772381097bSJoe Perches $space_after = 1; 41782381097bSJoe Perches } 41792381097bSJoe Perches } 41802381097bSJoe Perches if ($rtrim_before || $space_after) { 41812381097bSJoe Perches if ($rtrim_before) { 41822381097bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 41832381097bSJoe Perches } else { 41842381097bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 41852381097bSJoe Perches } 41862381097bSJoe Perches if ($space_after) { 41872381097bSJoe Perches $good .= " "; 41883705ce5bSJoe Perches } 41890a920b5bSAndy Whitcroft } 41900a920b5bSAndy Whitcroft 41919c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 419274048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 41939c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 41949c0ca6f9SAndy Whitcroft 41959c0ca6f9SAndy Whitcroft # unary operators should have a space before and 41969c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 41979c0ca6f9SAndy Whitcroft # unary operator, or a cast 41989c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 419974048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 42000d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 4201cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 42023705ce5bSJoe Perches if (ERROR("SPACING", 42033705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 4204b34c648bSJoe Perches if ($n != $last_after + 2) { 4205b34c648bSJoe Perches $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); 42063705ce5bSJoe Perches $line_fixed = 1; 42073705ce5bSJoe Perches } 42080a920b5bSAndy Whitcroft } 4209b34c648bSJoe Perches } 4210a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 4211171ae1a4SAndy Whitcroft # A unary '*' may be const 4212171ae1a4SAndy Whitcroft 4213171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 42143705ce5bSJoe Perches if (ERROR("SPACING", 42153705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4216b34c648bSJoe Perches $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); 42173705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42183705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 42193705ce5bSJoe Perches } 4220b34c648bSJoe Perches $line_fixed = 1; 42213705ce5bSJoe Perches } 42220a920b5bSAndy Whitcroft } 42230a920b5bSAndy Whitcroft 42240a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 42250a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 4226773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 42273705ce5bSJoe Perches if (ERROR("SPACING", 42283705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 4229b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; 42303705ce5bSJoe Perches $line_fixed = 1; 42313705ce5bSJoe Perches } 42320a920b5bSAndy Whitcroft } 4233773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 4234773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 42353705ce5bSJoe Perches if (ERROR("SPACING", 42363705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4237b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42383705ce5bSJoe Perches $line_fixed = 1; 42393705ce5bSJoe Perches } 4240653d4876SAndy Whitcroft } 4241773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 42423705ce5bSJoe Perches if (ERROR("SPACING", 42433705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 4244b34c648bSJoe Perches $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); 42453705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 42463705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4247773647a0SAndy Whitcroft } 4248b34c648bSJoe Perches $line_fixed = 1; 42493705ce5bSJoe Perches } 42503705ce5bSJoe Perches } 42510a920b5bSAndy Whitcroft 42520a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 42539c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 42549c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 42559c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 4256c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 4257c2fdda0dSAndy Whitcroft $op eq '%') 42580a920b5bSAndy Whitcroft { 4259d2e025f3SJoe Perches if ($check) { 4260d2e025f3SJoe Perches if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { 4261d2e025f3SJoe Perches if (CHK("SPACING", 4262d2e025f3SJoe Perches "spaces preferred around that '$op' $at\n" . $hereptr)) { 4263d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4264d2e025f3SJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4265d2e025f3SJoe Perches $line_fixed = 1; 4266d2e025f3SJoe Perches } 4267d2e025f3SJoe Perches } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { 4268d2e025f3SJoe Perches if (CHK("SPACING", 4269d2e025f3SJoe Perches "space preferred before that '$op' $at\n" . $hereptr)) { 4270d2e025f3SJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 4271d2e025f3SJoe Perches $line_fixed = 1; 4272d2e025f3SJoe Perches } 4273d2e025f3SJoe Perches } 4274d2e025f3SJoe Perches } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 42753705ce5bSJoe Perches if (ERROR("SPACING", 42763705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 4277b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4278b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4279b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4280b34c648bSJoe Perches } 42813705ce5bSJoe Perches $line_fixed = 1; 42823705ce5bSJoe Perches } 42830a920b5bSAndy Whitcroft } 42840a920b5bSAndy Whitcroft 42851f65f947SAndy Whitcroft # A colon needs no spaces before when it is 42861f65f947SAndy Whitcroft # terminating a case value or a label. 42871f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 42881f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 42893705ce5bSJoe Perches if (ERROR("SPACING", 42903705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 4291b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 42923705ce5bSJoe Perches $line_fixed = 1; 42933705ce5bSJoe Perches } 42941f65f947SAndy Whitcroft } 42951f65f947SAndy Whitcroft 42960a920b5bSAndy Whitcroft # All the others need spaces both sides. 4297cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 42981f65f947SAndy Whitcroft my $ok = 0; 42991f65f947SAndy Whitcroft 430022f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 43011f65f947SAndy Whitcroft if (($op eq '<' && 43021f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 43031f65f947SAndy Whitcroft ($op eq '>' && 43041f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 43051f65f947SAndy Whitcroft { 43061f65f947SAndy Whitcroft $ok = 1; 43071f65f947SAndy Whitcroft } 43081f65f947SAndy Whitcroft 4309e0df7e1fSJoe Perches # for asm volatile statements 4310e0df7e1fSJoe Perches # ignore a colon with another 4311e0df7e1fSJoe Perches # colon immediately before or after 4312e0df7e1fSJoe Perches if (($op eq ':') && 4313e0df7e1fSJoe Perches ($ca =~ /:$/ || $cc =~ /^:/)) { 4314e0df7e1fSJoe Perches $ok = 1; 4315e0df7e1fSJoe Perches } 4316e0df7e1fSJoe Perches 431784731623SJoe Perches # messages are ERROR, but ?: are CHK 43181f65f947SAndy Whitcroft if ($ok == 0) { 431984731623SJoe Perches my $msg_type = \&ERROR; 432084731623SJoe Perches $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); 432184731623SJoe Perches 432284731623SJoe Perches if (&{$msg_type}("SPACING", 43233705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 4324b34c648bSJoe Perches $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 4325b34c648bSJoe Perches if (defined $fix_elements[$n + 2]) { 4326b34c648bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 4327b34c648bSJoe Perches } 43283705ce5bSJoe Perches $line_fixed = 1; 43293705ce5bSJoe Perches } 43300a920b5bSAndy Whitcroft } 433122f2a2efSAndy Whitcroft } 43324a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 43333705ce5bSJoe Perches 43343705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 43353705ce5bSJoe Perches 43363705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 43370a920b5bSAndy Whitcroft } 43383705ce5bSJoe Perches 43393705ce5bSJoe Perches if (($#elements % 2) == 0) { 43403705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 43413705ce5bSJoe Perches } 43423705ce5bSJoe Perches 4343194f66fcSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { 4344194f66fcSJoe Perches $fixed[$fixlinenr] = $fixed_line; 43453705ce5bSJoe Perches } 43463705ce5bSJoe Perches 43473705ce5bSJoe Perches 43480a920b5bSAndy Whitcroft } 43490a920b5bSAndy Whitcroft 4350786b6326SJoe Perches# check for whitespace before a non-naked semicolon 4351d2e248e7SJoe Perches if ($line =~ /^\+.*\S\s+;\s*$/) { 4352786b6326SJoe Perches if (WARN("SPACING", 4353786b6326SJoe Perches "space prohibited before semicolon\n" . $herecurr) && 4354786b6326SJoe Perches $fix) { 4355194f66fcSJoe Perches 1 while $fixed[$fixlinenr] =~ 4356786b6326SJoe Perches s/^(\+.*\S)\s+;/$1;/; 4357786b6326SJoe Perches } 4358786b6326SJoe Perches } 4359786b6326SJoe Perches 4360f0a594c1SAndy Whitcroft# check for multiple assignments 4361f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 4362000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 4363000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 4364f0a594c1SAndy Whitcroft } 4365f0a594c1SAndy Whitcroft 436622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 436722f2a2efSAndy Whitcroft## # continuation. 436822f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 436922f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 437022f2a2efSAndy Whitcroft## 437122f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 437222f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 437322f2a2efSAndy Whitcroft## my $ln = $line; 437422f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 437522f2a2efSAndy Whitcroft## } 437622f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 4377000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 4378000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 437922f2a2efSAndy Whitcroft## } 438022f2a2efSAndy Whitcroft## } 4381f0a594c1SAndy Whitcroft 43820a920b5bSAndy Whitcroft#need space before brace following if, while, etc 43836b8c69e4SGeyslan G. Bem if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || 43844e5d56bdSEddie Kovsky $line =~ /do\{/) { 43853705ce5bSJoe Perches if (ERROR("SPACING", 43863705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 43873705ce5bSJoe Perches $fix) { 4388*8d81ae05SCyril Bur $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; 43893705ce5bSJoe Perches } 4390de7d4f0eSAndy Whitcroft } 4391de7d4f0eSAndy Whitcroft 4392c4a62ef9SJoe Perches## # check for blank lines before declarations 4393c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 4394c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 4395c4a62ef9SJoe Perches## WARN("SPACING", 4396c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 4397c4a62ef9SJoe Perches## } 4398c4a62ef9SJoe Perches## 4399c4a62ef9SJoe Perches 4400de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 4401de7d4f0eSAndy Whitcroft# on the line 4402de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 4403d5e616fcSJoe Perches if (ERROR("SPACING", 4404d5e616fcSJoe Perches "space required after that close brace '}'\n" . $herecurr) && 4405d5e616fcSJoe Perches $fix) { 4406194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4407d5e616fcSJoe Perches s/}((?!(?:,|;|\)))\S)/} $1/; 4408d5e616fcSJoe Perches } 44090a920b5bSAndy Whitcroft } 44100a920b5bSAndy Whitcroft 441122f2a2efSAndy Whitcroft# check spacing on square brackets 441222f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 44133705ce5bSJoe Perches if (ERROR("SPACING", 44143705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 44153705ce5bSJoe Perches $fix) { 4416194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44173705ce5bSJoe Perches s/\[\s+/\[/; 44183705ce5bSJoe Perches } 441922f2a2efSAndy Whitcroft } 442022f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 44213705ce5bSJoe Perches if (ERROR("SPACING", 44223705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 44233705ce5bSJoe Perches $fix) { 4424194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44253705ce5bSJoe Perches s/\s+\]/\]/; 44263705ce5bSJoe Perches } 442722f2a2efSAndy Whitcroft } 442822f2a2efSAndy Whitcroft 4429c45dcabdSAndy Whitcroft# check spacing on parentheses 44309c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 44319c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 44323705ce5bSJoe Perches if (ERROR("SPACING", 44333705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 44343705ce5bSJoe Perches $fix) { 4435194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44363705ce5bSJoe Perches s/\(\s+/\(/; 44373705ce5bSJoe Perches } 443822f2a2efSAndy Whitcroft } 443913214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 4440c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 4441c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 44423705ce5bSJoe Perches if (ERROR("SPACING", 44433705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 44443705ce5bSJoe Perches $fix) { 4445194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44463705ce5bSJoe Perches s/\s+\)/\)/; 44473705ce5bSJoe Perches } 444822f2a2efSAndy Whitcroft } 444922f2a2efSAndy Whitcroft 4450e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals 4451e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar 4452e2826fd0SJoe Perches 4453e2826fd0SJoe Perches while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { 4454ea4acbb1SJoe Perches my $var = $1; 4455ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4456ea4acbb1SJoe Perches "Unnecessary parentheses around $var\n" . $herecurr) && 4457ea4acbb1SJoe Perches $fix) { 4458ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; 4459ea4acbb1SJoe Perches } 4460ea4acbb1SJoe Perches } 4461ea4acbb1SJoe Perches 4462ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses 4463ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar(); 4464ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives 4465ea4acbb1SJoe Perches if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { 4466ea4acbb1SJoe Perches my $var = $2; 4467ea4acbb1SJoe Perches if (CHK("UNNECESSARY_PARENTHESES", 4468ea4acbb1SJoe Perches "Unnecessary parentheses around function pointer $var\n" . $herecurr) && 4469ea4acbb1SJoe Perches $fix) { 4470ea4acbb1SJoe Perches my $var2 = deparenthesize($var); 4471ea4acbb1SJoe Perches $var2 =~ s/\s//g; 4472ea4acbb1SJoe Perches $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; 4473ea4acbb1SJoe Perches } 4474e2826fd0SJoe Perches } 4475e2826fd0SJoe Perches 44760a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 44774a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 44780a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 44793705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 44803705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 44813705ce5bSJoe Perches $fix) { 4482194f66fcSJoe Perches $fixed[$fixlinenr] =~ 44833705ce5bSJoe Perches s/^(.)\s+/$1/; 44843705ce5bSJoe Perches } 44850a920b5bSAndy Whitcroft } 44860a920b5bSAndy Whitcroft 44875b9553abSJoe Perches# return is not a function 4488507e5141SJoe Perches if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { 4489c45dcabdSAndy Whitcroft my $spacing = $1; 4490507e5141SJoe Perches if ($^V && $^V ge 5.10.0 && 44915b9553abSJoe Perches $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { 44925b9553abSJoe Perches my $value = $1; 44935b9553abSJoe Perches $value = deparenthesize($value); 44945b9553abSJoe Perches if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { 4495000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 4496000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 44975b9553abSJoe Perches } 4498c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 4499000d1cc1SJoe Perches ERROR("SPACING", 4500000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 4501c45dcabdSAndy Whitcroft } 4502c45dcabdSAndy Whitcroft } 4503507e5141SJoe Perches 4504b43ae21bSJoe Perches# unnecessary return in a void function 4505b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return; 4506b43ae21bSJoe Perches# and the line before that not a goto label target like "out:" 4507b43ae21bSJoe Perches if ($sline =~ /^[ \+]}\s*$/ && 4508b43ae21bSJoe Perches $prevline =~ /^\+\treturn\s*;\s*$/ && 4509b43ae21bSJoe Perches $linenr >= 3 && 4510b43ae21bSJoe Perches $lines[$linenr - 3] =~ /^[ +]/ && 4511b43ae21bSJoe Perches $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { 45129819cf25SJoe Perches WARN("RETURN_VOID", 4513b43ae21bSJoe Perches "void function return statements are not generally useful\n" . $hereprev); 45149819cf25SJoe Perches } 45159819cf25SJoe Perches 4516189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar)) 4517189248d8SJoe Perches if ($^V && $^V ge 5.10.0 && 4518189248d8SJoe Perches $line =~ /\bif\s*((?:\(\s*){2,})/) { 4519189248d8SJoe Perches my $openparens = $1; 4520189248d8SJoe Perches my $count = $openparens =~ tr@\(@\(@; 4521189248d8SJoe Perches my $msg = ""; 4522189248d8SJoe Perches if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { 4523189248d8SJoe Perches my $comp = $4; #Not $1 because of $LvalOrFunc 4524189248d8SJoe Perches $msg = " - maybe == should be = ?" if ($comp eq "=="); 4525189248d8SJoe Perches WARN("UNNECESSARY_PARENTHESES", 4526189248d8SJoe Perches "Unnecessary parentheses$msg\n" . $herecurr); 4527189248d8SJoe Perches } 4528189248d8SJoe Perches } 4529189248d8SJoe Perches 4530c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left 4531c5595fa2SJoe Perches# avoid cases like "foo + BAR < baz" 4532c5595fa2SJoe Perches# only fix matches surrounded by parentheses to avoid incorrect 4533c5595fa2SJoe Perches# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" 4534c5595fa2SJoe Perches if ($^V && $^V ge 5.10.0 && 4535c5595fa2SJoe Perches $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { 4536c5595fa2SJoe Perches my $lead = $1; 4537c5595fa2SJoe Perches my $const = $2; 4538c5595fa2SJoe Perches my $comp = $3; 4539c5595fa2SJoe Perches my $to = $4; 4540c5595fa2SJoe Perches my $newcomp = $comp; 4541f39e1769SJoe Perches if ($lead !~ /(?:$Operators|\.)\s*$/ && 4542c5595fa2SJoe Perches $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && 4543c5595fa2SJoe Perches WARN("CONSTANT_COMPARISON", 4544c5595fa2SJoe Perches "Comparisons should place the constant on the right side of the test\n" . $herecurr) && 4545c5595fa2SJoe Perches $fix) { 4546c5595fa2SJoe Perches if ($comp eq "<") { 4547c5595fa2SJoe Perches $newcomp = ">"; 4548c5595fa2SJoe Perches } elsif ($comp eq "<=") { 4549c5595fa2SJoe Perches $newcomp = ">="; 4550c5595fa2SJoe Perches } elsif ($comp eq ">") { 4551c5595fa2SJoe Perches $newcomp = "<"; 4552c5595fa2SJoe Perches } elsif ($comp eq ">=") { 4553c5595fa2SJoe Perches $newcomp = "<="; 4554c5595fa2SJoe Perches } 4555c5595fa2SJoe Perches $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; 4556c5595fa2SJoe Perches } 4557c5595fa2SJoe Perches } 4558c5595fa2SJoe Perches 4559f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative 4560f34e4a4fSJoe Perches if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { 456153a3c448SAndy Whitcroft my $name = $1; 456253a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 4563000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 4564f34e4a4fSJoe Perches "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); 456553a3c448SAndy Whitcroft } 456653a3c448SAndy Whitcroft } 4567c45dcabdSAndy Whitcroft 45680a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 45694a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 45703705ce5bSJoe Perches if (ERROR("SPACING", 45713705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 45723705ce5bSJoe Perches $fix) { 4573194f66fcSJoe Perches $fixed[$fixlinenr] =~ 45743705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 45753705ce5bSJoe Perches } 45760a920b5bSAndy Whitcroft } 45770a920b5bSAndy Whitcroft 4578f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 4579f5fe35ddSAndy Whitcroft# statements after the conditional. 4580170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 45813e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 45823e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 45833e469cdcSAndy Whitcroft if (!defined $stat); 4584170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 4585170d3a22SAndy Whitcroft $remain_next, $off_next); 4586170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 4587170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 4588170d3a22SAndy Whitcroft 4589170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 4590170d3a22SAndy Whitcroft # If the statement carries leading newlines, 4591170d3a22SAndy Whitcroft # then count those as offsets. 4592170d3a22SAndy Whitcroft my ($whitespace) = 4593170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 4594170d3a22SAndy Whitcroft my $offset = 4595170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 4596170d3a22SAndy Whitcroft 4597170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 4598170d3a22SAndy Whitcroft $offset} = 1; 4599170d3a22SAndy Whitcroft } 4600170d3a22SAndy Whitcroft } 4601170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 4602c11230f4SJoe Perches defined($stat) && defined($cond) && 4603170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 4604171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 46058905a67cSAndy Whitcroft 4606b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 4607000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 4608000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 46098905a67cSAndy Whitcroft } 46108905a67cSAndy Whitcroft 46118905a67cSAndy Whitcroft # Find out what is on the end of the line after the 46128905a67cSAndy Whitcroft # conditional. 4613773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 46148905a67cSAndy Whitcroft $s =~ s/\n.*//g; 461513214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 461653210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 461753210168SAndy Whitcroft $c !~ /}\s*while\s*/) 4618773647a0SAndy Whitcroft { 4619bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 4620bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 4621bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 462242bdf74cSHidetoshi Seto my $stat_real = ''; 4623bb44ad39SAndy Whitcroft 462442bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 462542bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 4626bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 4627bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 4628bb44ad39SAndy Whitcroft } 4629bb44ad39SAndy Whitcroft 4630000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4631000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 46328905a67cSAndy Whitcroft } 46338905a67cSAndy Whitcroft } 46348905a67cSAndy Whitcroft 463513214adfSAndy Whitcroft# Check for bitwise tests written as boolean 463613214adfSAndy Whitcroft if ($line =~ / 463713214adfSAndy Whitcroft (?: 463813214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 463913214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 464013214adfSAndy Whitcroft (?:\&\&|\|\|) 464113214adfSAndy Whitcroft | 464213214adfSAndy Whitcroft (?:\&\&|\|\|) 464313214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 464413214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 464513214adfSAndy Whitcroft )/x) 464613214adfSAndy Whitcroft { 4647000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 4648000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 464913214adfSAndy Whitcroft } 465013214adfSAndy Whitcroft 46518905a67cSAndy Whitcroft# if and else should not have general statements after it 465213214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 465313214adfSAndy Whitcroft my $s = $1; 465413214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 465513214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 4656000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4657000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 46580a920b5bSAndy Whitcroft } 465913214adfSAndy Whitcroft } 466039667782SAndy Whitcroft# if should not continue a brace 466139667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 4662000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4663048b123fSRasmus Villemoes "trailing statements should be on next line (or did you mean 'else if'?)\n" . 466439667782SAndy Whitcroft $herecurr); 466539667782SAndy Whitcroft } 4666a1080bf8SAndy Whitcroft# case and default should not have general statements after them 4667a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 4668a1080bf8SAndy Whitcroft $line !~ /\G(?: 46693fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 4670a1080bf8SAndy Whitcroft \s*return\s+ 4671a1080bf8SAndy Whitcroft )/xg) 4672a1080bf8SAndy Whitcroft { 4673000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 4674000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 4675a1080bf8SAndy Whitcroft } 46760a920b5bSAndy Whitcroft 46770a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 46780a920b5bSAndy Whitcroft # indent level to be relevant to each other. 46798b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && 46800a920b5bSAndy Whitcroft $previndent == $indent) { 46818b8856f4SJoe Perches if (ERROR("ELSE_AFTER_BRACE", 46828b8856f4SJoe Perches "else should follow close brace '}'\n" . $hereprev) && 46838b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 46848b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 46858b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 46868b8856f4SJoe Perches my $fixedline = $prevrawline; 46878b8856f4SJoe Perches $fixedline =~ s/}\s*$//; 46888b8856f4SJoe Perches if ($fixedline !~ /^\+\s*$/) { 46898b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46908b8856f4SJoe Perches } 46918b8856f4SJoe Perches $fixedline = $rawline; 46928b8856f4SJoe Perches $fixedline =~ s/^(.\s*)else/$1} else/; 46938b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 46948b8856f4SJoe Perches } 46950a920b5bSAndy Whitcroft } 46960a920b5bSAndy Whitcroft 46978b8856f4SJoe Perches if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && 4698c2fdda0dSAndy Whitcroft $previndent == $indent) { 4699c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 4700c2fdda0dSAndy Whitcroft 4701c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 4702c2fdda0dSAndy Whitcroft # conditional. 4703773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 4704c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 4705c2fdda0dSAndy Whitcroft 4706c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 47078b8856f4SJoe Perches if (ERROR("WHILE_AFTER_BRACE", 47088b8856f4SJoe Perches "while should follow close brace '}'\n" . $hereprev) && 47098b8856f4SJoe Perches $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { 47108b8856f4SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 47118b8856f4SJoe Perches fix_delete_line($fixlinenr, $rawline); 47128b8856f4SJoe Perches my $fixedline = $prevrawline; 47138b8856f4SJoe Perches my $trailing = $rawline; 47148b8856f4SJoe Perches $trailing =~ s/^\+//; 47158b8856f4SJoe Perches $trailing = trim($trailing); 47168b8856f4SJoe Perches $fixedline =~ s/}\s*$/} $trailing/; 47178b8856f4SJoe Perches fix_insert_line($fixlinenr, $fixedline); 47188b8856f4SJoe Perches } 4719c2fdda0dSAndy Whitcroft } 4720c2fdda0dSAndy Whitcroft } 4721c2fdda0dSAndy Whitcroft 472295e2c602SJoe Perches#Specific variable tests 4723323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 4724323c1260SJoe Perches my $var = $1; 472595e2c602SJoe Perches 472695e2c602SJoe Perches#gcc binary extension 472795e2c602SJoe Perches if ($var =~ /^$Binary$/) { 4728d5e616fcSJoe Perches if (WARN("GCC_BINARY_CONSTANT", 4729d5e616fcSJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && 4730d5e616fcSJoe Perches $fix) { 4731d5e616fcSJoe Perches my $hexval = sprintf("0x%x", oct($var)); 4732194f66fcSJoe Perches $fixed[$fixlinenr] =~ 4733d5e616fcSJoe Perches s/\b$var\b/$hexval/; 4734d5e616fcSJoe Perches } 473595e2c602SJoe Perches } 473695e2c602SJoe Perches 473795e2c602SJoe Perches#CamelCase 4738807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 4739be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 474022735ce8SJoe Perches#Ignore Page<foo> variants 4741807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 474222735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show) 4743f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && 4744f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz 4745f5123576SJulius Werner $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { 47467e781f67SJoe Perches while ($var =~ m{($Ident)}g) { 47477e781f67SJoe Perches my $word = $1; 47487e781f67SJoe Perches next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); 4749d8b07710SJoe Perches if ($check) { 4750d8b07710SJoe Perches seed_camelcase_includes(); 4751d8b07710SJoe Perches if (!$file && !$camelcase_file_seeded) { 4752d8b07710SJoe Perches seed_camelcase_file($realfile); 4753d8b07710SJoe Perches $camelcase_file_seeded = 1; 4754d8b07710SJoe Perches } 4755d8b07710SJoe Perches } 47567e781f67SJoe Perches if (!defined $camelcase{$word}) { 47577e781f67SJoe Perches $camelcase{$word} = 1; 4758be79794bSJoe Perches CHK("CAMELCASE", 47597e781f67SJoe Perches "Avoid CamelCase: <$word>\n" . $herecurr); 47607e781f67SJoe Perches } 4761323c1260SJoe Perches } 4762323c1260SJoe Perches } 47633445686aSJoe Perches } 47640a920b5bSAndy Whitcroft 47650a920b5bSAndy Whitcroft#no spaces allowed after \ in define 4766d5e616fcSJoe Perches if ($line =~ /\#\s*define.*\\\s+$/) { 4767d5e616fcSJoe Perches if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 4768d5e616fcSJoe Perches "Whitespace after \\ makes next lines useless\n" . $herecurr) && 4769d5e616fcSJoe Perches $fix) { 4770194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\s+$//; 4771d5e616fcSJoe Perches } 47720a920b5bSAndy Whitcroft } 47730a920b5bSAndy Whitcroft 47740e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes 47750e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line) 4776c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 4777e09dec48SAndy Whitcroft my $file = "$1.h"; 4778e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 4779e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 4780e09dec48SAndy Whitcroft $realfile ne $checkfile && 47817840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 4782c45dcabdSAndy Whitcroft { 47830e212e0aSFabian Frederick my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; 47840e212e0aSFabian Frederick if ($asminclude > 0) { 4785e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 4786000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 4787000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4788e09dec48SAndy Whitcroft } else { 4789000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 4790000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 4791e09dec48SAndy Whitcroft } 47920a920b5bSAndy Whitcroft } 47930a920b5bSAndy Whitcroft } 47940e212e0aSFabian Frederick } 47950a920b5bSAndy Whitcroft 4796653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 4797653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 4798cf655043SAndy Whitcroft# in a known good container 4799b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 4800b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 4801d8aaf121SAndy Whitcroft my $ln = $linenr; 4802d8aaf121SAndy Whitcroft my $cnt = $realcnt; 4803c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 4804c45dcabdSAndy Whitcroft my $ctx = ''; 480508a2843eSJoe Perches my $has_flow_statement = 0; 480608a2843eSJoe Perches my $has_arg_concat = 0; 4807c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 4808f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 4809f74bd194SAndy Whitcroft $ctx = $dstat; 4810c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 4811a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 4812c45dcabdSAndy Whitcroft 481308a2843eSJoe Perches $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); 481462e15a6dSJoe Perches $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 481508a2843eSJoe Perches 4816f59b64bfSJoe Perches $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; 4817f59b64bfSJoe Perches my $define_args = $1; 4818f59b64bfSJoe Perches my $define_stmt = $dstat; 4819f59b64bfSJoe Perches my @def_args = (); 4820f59b64bfSJoe Perches 4821f59b64bfSJoe Perches if (defined $define_args && $define_args ne "") { 4822f59b64bfSJoe Perches $define_args = substr($define_args, 1, length($define_args) - 2); 4823f59b64bfSJoe Perches $define_args =~ s/\s*//g; 4824f59b64bfSJoe Perches @def_args = split(",", $define_args); 4825f59b64bfSJoe Perches } 4826f59b64bfSJoe Perches 4827292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 4828c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 4829c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 4830c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 4831c45dcabdSAndy Whitcroft 4832c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 4833bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 4834bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 48356b10df42SVladimir Zapolskiy $dstat =~ s/.\[[^\[\]]*\]/1/) 4836bf30d6edSAndy Whitcroft { 4837c45dcabdSAndy Whitcroft } 4838c45dcabdSAndy Whitcroft 4839e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 484033acb54aSJoe Perches while ($dstat =~ s/($String)\s*$Ident/$1/ || 484133acb54aSJoe Perches $dstat =~ s/$Ident\s*($String)/$1/) 4842e45bab8eSAndy Whitcroft { 4843e45bab8eSAndy Whitcroft } 4844e45bab8eSAndy Whitcroft 484542e15293SJoe Perches # Make asm volatile uses seem like a generic function 484642e15293SJoe Perches $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 484742e15293SJoe Perches 4848c45dcabdSAndy Whitcroft my $exceptions = qr{ 4849c45dcabdSAndy Whitcroft $Declare| 4850c45dcabdSAndy Whitcroft module_param_named| 4851a0a0a7a9SKees Cook MODULE_PARM_DESC| 4852c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 4853c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 4854383099fdSAndy Whitcroft __typeof__\(| 485522fd2d3eSStefani Seibold union| 485622fd2d3eSStefani Seibold struct| 4857ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 48586b10df42SVladimir Zapolskiy ^\"|\"$| 48596b10df42SVladimir Zapolskiy ^\[ 4860c45dcabdSAndy Whitcroft }x; 48615eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 4862f59b64bfSJoe Perches 4863f59b64bfSJoe Perches $ctx =~ s/\n*$//; 4864f59b64bfSJoe Perches my $herectx = $here . "\n"; 4865f59b64bfSJoe Perches my $stmt_cnt = statement_rawlines($ctx); 4866f59b64bfSJoe Perches 4867f59b64bfSJoe Perches for (my $n = 0; $n < $stmt_cnt; $n++) { 4868f59b64bfSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4869f59b64bfSJoe Perches } 4870f59b64bfSJoe Perches 4871f74bd194SAndy Whitcroft if ($dstat ne '' && 4872f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 4873f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 48743cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 4875356fd398SJoe Perches $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants 4876f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 4877f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 4878e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 487972f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 4880f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 4881f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 4882f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 48834e5d56bdSEddie Kovsky $dstat !~ /^\(\{/ && # ({... 4884f95a7e6aSJoe Perches $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) 4885c45dcabdSAndy Whitcroft { 4886e795556aSJoe Perches if ($dstat =~ /^\s*if\b/) { 4887e795556aSJoe Perches ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4888e795556aSJoe Perches "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 4889e795556aSJoe Perches } elsif ($dstat =~ /;/) { 4890f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 4891f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 4892f74bd194SAndy Whitcroft } else { 4893000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 4894388982b5SAndrew Morton "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 4895d8aaf121SAndy Whitcroft } 4896f59b64bfSJoe Perches 4897f59b64bfSJoe Perches } 48985207649bSJoe Perches 48995207649bSJoe Perches # Make $define_stmt single line, comment-free, etc 49005207649bSJoe Perches my @stmt_array = split('\n', $define_stmt); 49015207649bSJoe Perches my $first = 1; 49025207649bSJoe Perches $define_stmt = ""; 49035207649bSJoe Perches foreach my $l (@stmt_array) { 49045207649bSJoe Perches $l =~ s/\\$//; 49055207649bSJoe Perches if ($first) { 49065207649bSJoe Perches $define_stmt = $l; 49075207649bSJoe Perches $first = 0; 49085207649bSJoe Perches } elsif ($l =~ /^[\+ ]/) { 49095207649bSJoe Perches $define_stmt .= substr($l, 1); 49105207649bSJoe Perches } 49115207649bSJoe Perches } 49125207649bSJoe Perches $define_stmt =~ s/$;//g; 49135207649bSJoe Perches $define_stmt =~ s/\s+/ /g; 49145207649bSJoe Perches $define_stmt = trim($define_stmt); 49155207649bSJoe Perches 4916f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type') 4917f59b64bfSJoe Perches foreach my $arg (@def_args) { 4918f59b64bfSJoe Perches next if ($arg =~ /\.\.\./); 49199192d41aSJoe Perches next if ($arg =~ /^type$/i); 4920f59b64bfSJoe Perches my $tmp = $define_stmt; 4921f59b64bfSJoe Perches $tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; 49225207649bSJoe Perches $tmp =~ s/\#+\s*$arg\b//g; 4923f59b64bfSJoe Perches $tmp =~ s/\b$arg\s*\#\#//g; 4924f59b64bfSJoe Perches my $use_cnt = $tmp =~ s/\b$arg\b//g; 4925f59b64bfSJoe Perches if ($use_cnt > 1) { 4926f59b64bfSJoe Perches CHK("MACRO_ARG_REUSE", 4927f59b64bfSJoe Perches "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); 4928f59b64bfSJoe Perches } 49299192d41aSJoe Perches# check if any macro arguments may have other precedence issues 49309192d41aSJoe Perches if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && 49319192d41aSJoe Perches ((defined($1) && $1 ne ',') || 49329192d41aSJoe Perches (defined($2) && $2 ne ','))) { 49339192d41aSJoe Perches CHK("MACRO_ARG_PRECEDENCE", 49349192d41aSJoe Perches "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); 49359192d41aSJoe Perches } 49360a920b5bSAndy Whitcroft } 49375023d347SJoe Perches 493808a2843eSJoe Perches# check for macros with flow control, but without ## concatenation 493908a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those 494008a2843eSJoe Perches if ($has_flow_statement && !$has_arg_concat) { 494108a2843eSJoe Perches my $herectx = $here . "\n"; 494208a2843eSJoe Perches my $cnt = statement_rawlines($ctx); 494308a2843eSJoe Perches 494408a2843eSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 494508a2843eSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 494608a2843eSJoe Perches } 494708a2843eSJoe Perches WARN("MACRO_WITH_FLOW_CONTROL", 494808a2843eSJoe Perches "Macros with flow control statements should be avoided\n" . "$herectx"); 494908a2843eSJoe Perches } 495008a2843eSJoe Perches 4951481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 49525023d347SJoe Perches 49535023d347SJoe Perches } else { 49545023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 4955481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 4956481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 49575023d347SJoe Perches $line =~ /^\+.*\\$/) { 49585023d347SJoe Perches WARN("LINE_CONTINUATIONS", 49595023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 49605023d347SJoe Perches } 4961653d4876SAndy Whitcroft } 49620a920b5bSAndy Whitcroft 4963b13edf7fSJoe Perches# do {} while (0) macro tests: 4964b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 4965b13edf7fSJoe Perches# macro should not end with a semicolon 4966b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 4967b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 4968b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 4969b13edf7fSJoe Perches my $ln = $linenr; 4970b13edf7fSJoe Perches my $cnt = $realcnt; 4971b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 4972b13edf7fSJoe Perches my $ctx = ''; 4973b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 4974b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 4975b13edf7fSJoe Perches $ctx = $dstat; 4976b13edf7fSJoe Perches 4977b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 49781b36b201SJoe Perches $dstat =~ s/$;/ /g; 4979b13edf7fSJoe Perches 4980b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 4981b13edf7fSJoe Perches my $stmts = $2; 4982b13edf7fSJoe Perches my $semis = $3; 4983b13edf7fSJoe Perches 4984b13edf7fSJoe Perches $ctx =~ s/\n*$//; 4985b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 4986b13edf7fSJoe Perches my $herectx = $here . "\n"; 4987b13edf7fSJoe Perches 4988b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 4989b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 4990b13edf7fSJoe Perches } 4991b13edf7fSJoe Perches 4992ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 4993ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 4994b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 4995b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 4996b13edf7fSJoe Perches } 4997b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 4998b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 4999b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 5000b13edf7fSJoe Perches } 5001f5ef95b1SJoe Perches } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { 5002f5ef95b1SJoe Perches $ctx =~ s/\n*$//; 5003f5ef95b1SJoe Perches my $cnt = statement_rawlines($ctx); 5004f5ef95b1SJoe Perches my $herectx = $here . "\n"; 5005f5ef95b1SJoe Perches 5006f5ef95b1SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 5007f5ef95b1SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 5008f5ef95b1SJoe Perches } 5009f5ef95b1SJoe Perches 5010f5ef95b1SJoe Perches WARN("TRAILING_SEMICOLON", 5011f5ef95b1SJoe Perches "macros should not use a trailing semicolon\n" . "$herectx"); 5012b13edf7fSJoe Perches } 5013b13edf7fSJoe Perches } 5014b13edf7fSJoe Perches 5015080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 5016080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 5017080ba929SMike Frysinger# . 5018080ba929SMike Frysinger# ALIGN(...) 5019080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 5020080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 5021000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 5022000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 5023080ba929SMike Frysinger } 5024080ba929SMike Frysinger 5025f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 502613214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 502713214adfSAndy Whitcroft my ($level, $endln, @chunks) = 5028cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 502913214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 5030cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 5031cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 5032aad4f614SJoe Perches my @allowed = (); 5033aad4f614SJoe Perches my $allow = 0; 503413214adfSAndy Whitcroft my $seen = 0; 5035773647a0SAndy Whitcroft my $herectx = $here . "\n"; 5036cf655043SAndy Whitcroft my $ln = $linenr - 1; 503713214adfSAndy Whitcroft for my $chunk (@chunks) { 503813214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 503913214adfSAndy Whitcroft 5040773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 5041773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 5042773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 5043773647a0SAndy Whitcroft 5044aad4f614SJoe Perches $allowed[$allow] = 0; 5045773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 5046773647a0SAndy Whitcroft 5047773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 5048773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 5049773647a0SAndy Whitcroft 5050773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 5051cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 5052cf655043SAndy Whitcroft 5053773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 505413214adfSAndy Whitcroft 505513214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 505613214adfSAndy Whitcroft 5057aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 5058cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5059cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5060aad4f614SJoe Perches $allowed[$allow] = 1; 506113214adfSAndy Whitcroft } 506213214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5063cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5064aad4f614SJoe Perches $allowed[$allow] = 1; 506513214adfSAndy Whitcroft } 5066cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5067cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5068aad4f614SJoe Perches $allowed[$allow] = 1; 506913214adfSAndy Whitcroft } 5070aad4f614SJoe Perches $allow++; 507113214adfSAndy Whitcroft } 5072aad4f614SJoe Perches if ($seen) { 5073aad4f614SJoe Perches my $sum_allowed = 0; 5074aad4f614SJoe Perches foreach (@allowed) { 5075aad4f614SJoe Perches $sum_allowed += $_; 5076aad4f614SJoe Perches } 5077aad4f614SJoe Perches if ($sum_allowed == 0) { 5078000d1cc1SJoe Perches WARN("BRACES", 5079000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 5080aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 5081aad4f614SJoe Perches $seen != $allow) { 5082aad4f614SJoe Perches CHK("BRACES", 5083aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 5084aad4f614SJoe Perches } 508513214adfSAndy Whitcroft } 508613214adfSAndy Whitcroft } 508713214adfSAndy Whitcroft } 5088773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 508913214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 5090cf655043SAndy Whitcroft my $allowed = 0; 5091f0a594c1SAndy Whitcroft 5092cf655043SAndy Whitcroft # Check the pre-context. 5093cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 5094cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 5095cf655043SAndy Whitcroft $allowed = 1; 5096f0a594c1SAndy Whitcroft } 5097773647a0SAndy Whitcroft 5098773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 5099773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 5100773647a0SAndy Whitcroft 5101cf655043SAndy Whitcroft # Check the condition. 5102cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 5103773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 5104cf655043SAndy Whitcroft if (defined $cond) { 5105773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5106cf655043SAndy Whitcroft } 5107cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 5108cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 5109cf655043SAndy Whitcroft $allowed = 1; 5110cf655043SAndy Whitcroft } 5111cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 5112cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 5113cf655043SAndy Whitcroft $allowed = 1; 5114cf655043SAndy Whitcroft } 5115cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 5116cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 5117cf655043SAndy Whitcroft $allowed = 1; 5118cf655043SAndy Whitcroft } 5119cf655043SAndy Whitcroft # Check the post-context. 5120cf655043SAndy Whitcroft if (defined $chunks[1]) { 5121cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 5122cf655043SAndy Whitcroft if (defined $cond) { 5123773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 5124cf655043SAndy Whitcroft } 5125cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 5126cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 5127cf655043SAndy Whitcroft $allowed = 1; 5128cf655043SAndy Whitcroft } 5129cf655043SAndy Whitcroft } 5130cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 513169932487SJustin P. Mattock my $herectx = $here . "\n"; 5132f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 5133cf655043SAndy Whitcroft 5134f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 513569932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 5136cf655043SAndy Whitcroft } 5137cf655043SAndy Whitcroft 5138000d1cc1SJoe Perches WARN("BRACES", 5139000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 5140f0a594c1SAndy Whitcroft } 5141f0a594c1SAndy Whitcroft } 5142f0a594c1SAndy Whitcroft 5143e4c5babdSJoe Perches# check for single line unbalanced braces 514495330473SSven Eckelmann if ($sline =~ /^.\s*\}\s*else\s*$/ || 514595330473SSven Eckelmann $sline =~ /^.\s*else\s*\{\s*$/) { 5146e4c5babdSJoe Perches CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); 5147e4c5babdSJoe Perches } 5148e4c5babdSJoe Perches 51490979ae66SJoe Perches# check for unnecessary blank lines around braces 515077b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 5151f8e58219SJoe Perches if (CHK("BRACES", 5152f8e58219SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && 5153f8e58219SJoe Perches $fix && $prevrawline =~ /^\+/) { 5154f8e58219SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5155f8e58219SJoe Perches } 51560979ae66SJoe Perches } 515777b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 5158f8e58219SJoe Perches if (CHK("BRACES", 5159f8e58219SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && 5160f8e58219SJoe Perches $fix) { 5161f8e58219SJoe Perches fix_delete_line($fixlinenr, $rawline); 5162f8e58219SJoe Perches } 51630979ae66SJoe Perches } 51640979ae66SJoe Perches 51654a0df2efSAndy Whitcroft# no volatiles please 51666c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 51676c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 5168000d1cc1SJoe Perches WARN("VOLATILE", 51698c27ceffSMauro Carvalho Chehab "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); 51704a0df2efSAndy Whitcroft } 51714a0df2efSAndy Whitcroft 51725e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability 51735e4f6ba5SJoe Perches# to grep for the string. Make exceptions when the previous string ends in a 51745e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' 51755e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value 517633acb54aSJoe Perches if ($line =~ /^\+\s*$String/ && 51775e4f6ba5SJoe Perches $prevline =~ /"\s*$/ && 51785e4f6ba5SJoe Perches $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { 51795e4f6ba5SJoe Perches if (WARN("SPLIT_STRING", 51805e4f6ba5SJoe Perches "quoted string split across lines\n" . $hereprev) && 51815e4f6ba5SJoe Perches $fix && 51825e4f6ba5SJoe Perches $prevrawline =~ /^\+.*"\s*$/ && 51835e4f6ba5SJoe Perches $last_coalesced_string_linenr != $linenr - 1) { 51845e4f6ba5SJoe Perches my $extracted_string = get_quoted_string($line, $rawline); 51855e4f6ba5SJoe Perches my $comma_close = ""; 51865e4f6ba5SJoe Perches if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { 51875e4f6ba5SJoe Perches $comma_close = $1; 51885e4f6ba5SJoe Perches } 51895e4f6ba5SJoe Perches 51905e4f6ba5SJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 51915e4f6ba5SJoe Perches fix_delete_line($fixlinenr, $rawline); 51925e4f6ba5SJoe Perches my $fixedline = $prevrawline; 51935e4f6ba5SJoe Perches $fixedline =~ s/"\s*$//; 51945e4f6ba5SJoe Perches $fixedline .= substr($extracted_string, 1) . trim($comma_close); 51955e4f6ba5SJoe Perches fix_insert_line($fixlinenr - 1, $fixedline); 51965e4f6ba5SJoe Perches $fixedline = $rawline; 51975e4f6ba5SJoe Perches $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; 51985e4f6ba5SJoe Perches if ($fixedline !~ /\+\s*$/) { 51995e4f6ba5SJoe Perches fix_insert_line($fixlinenr, $fixedline); 52005e4f6ba5SJoe Perches } 52015e4f6ba5SJoe Perches $last_coalesced_string_linenr = $linenr; 52025e4f6ba5SJoe Perches } 52035e4f6ba5SJoe Perches } 52045e4f6ba5SJoe Perches 52055e4f6ba5SJoe Perches# check for missing a space in a string concatenation 52065e4f6ba5SJoe Perches if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { 52075e4f6ba5SJoe Perches WARN('MISSING_SPACE', 52085e4f6ba5SJoe Perches "break quoted strings at a space character\n" . $hereprev); 52095e4f6ba5SJoe Perches } 52105e4f6ba5SJoe Perches 521177cb8546SJoe Perches# check for an embedded function name in a string when the function is known 5212e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch 5213e4b7d309SJoe Perches# context providing the function name or a single line form for in-file 5214e4b7d309SJoe Perches# function declarations 521577cb8546SJoe Perches if ($line =~ /^\+.*$String/ && 521677cb8546SJoe Perches defined($context_function) && 5217e4b7d309SJoe Perches get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && 5218e4b7d309SJoe Perches length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { 521977cb8546SJoe Perches WARN("EMBEDDED_FUNCTION_NAME", 5220e4b7d309SJoe Perches "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); 522177cb8546SJoe Perches } 522277cb8546SJoe Perches 52235e4f6ba5SJoe Perches# check for spaces before a quoted newline 52245e4f6ba5SJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 52255e4f6ba5SJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 52265e4f6ba5SJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 52275e4f6ba5SJoe Perches $fix) { 52285e4f6ba5SJoe Perches $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 52295e4f6ba5SJoe Perches } 52305e4f6ba5SJoe Perches 52315e4f6ba5SJoe Perches } 52325e4f6ba5SJoe Perches 5233f17dba4fSJoe Perches# concatenated string without spaces between elements 523433acb54aSJoe Perches if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { 5235f17dba4fSJoe Perches CHK("CONCATENATED_STRING", 5236f17dba4fSJoe Perches "Concatenated strings should use spaces between elements\n" . $herecurr); 5237f17dba4fSJoe Perches } 5238f17dba4fSJoe Perches 523990ad30e5SJoe Perches# uncoalesced string fragments 524033acb54aSJoe Perches if ($line =~ /$String\s*"/) { 524190ad30e5SJoe Perches WARN("STRING_FRAGMENTS", 524290ad30e5SJoe Perches "Consecutive strings are generally better as a single string\n" . $herecurr); 524390ad30e5SJoe Perches } 524490ad30e5SJoe Perches 5245522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats 5246522b837cSAlexey Dobriyan my $show_L = 1; #don't show the same defect twice 5247522b837cSAlexey Dobriyan my $show_Z = 1; 52485e4f6ba5SJoe Perches while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 5249522b837cSAlexey Dobriyan my $string = substr($rawline, $-[1], $+[1] - $-[1]); 52505e4f6ba5SJoe Perches $string =~ s/%%/__/g; 5251522b837cSAlexey Dobriyan # check for %L 5252522b837cSAlexey Dobriyan if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { 52535e4f6ba5SJoe Perches WARN("PRINTF_L", 5254522b837cSAlexey Dobriyan "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); 5255522b837cSAlexey Dobriyan $show_L = 0; 52565e4f6ba5SJoe Perches } 5257522b837cSAlexey Dobriyan # check for %Z 5258522b837cSAlexey Dobriyan if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { 5259522b837cSAlexey Dobriyan WARN("PRINTF_Z", 5260522b837cSAlexey Dobriyan "%Z$1 is non-standard C, use %z$1\n" . $herecurr); 5261522b837cSAlexey Dobriyan $show_Z = 0; 5262522b837cSAlexey Dobriyan } 5263522b837cSAlexey Dobriyan # check for 0x<decimal> 5264522b837cSAlexey Dobriyan if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { 5265522b837cSAlexey Dobriyan ERROR("PRINTF_0XDECIMAL", 52666e300757SJoe Perches "Prefixing 0x with decimal output is defective\n" . $herecurr); 52676e300757SJoe Perches } 52685e4f6ba5SJoe Perches } 52695e4f6ba5SJoe Perches 52705e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of " 52715e4f6ba5SJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 52725e4f6ba5SJoe Perches WARN("LINE_CONTINUATIONS", 52735e4f6ba5SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 52745e4f6ba5SJoe Perches } 52755e4f6ba5SJoe Perches 527600df344fSAndy Whitcroft# warn about #if 0 5277c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 5278000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 5279000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 5280de7d4f0eSAndy Whitcroft $herecurr); 52814a0df2efSAndy Whitcroft } 52824a0df2efSAndy Whitcroft 528303df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 528403df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 5285100425deSJoe Perches my $tested = quotemeta($1); 5286100425deSJoe Perches my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; 5287100425deSJoe Perches if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { 5288100425deSJoe Perches my $func = $1; 5289100425deSJoe Perches if (WARN('NEEDLESS_IF', 5290100425deSJoe Perches "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && 5291100425deSJoe Perches $fix) { 5292100425deSJoe Perches my $do_fix = 1; 5293100425deSJoe Perches my $leading_tabs = ""; 5294100425deSJoe Perches my $new_leading_tabs = ""; 5295100425deSJoe Perches if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { 5296100425deSJoe Perches $leading_tabs = $1; 5297100425deSJoe Perches } else { 5298100425deSJoe Perches $do_fix = 0; 5299100425deSJoe Perches } 5300100425deSJoe Perches if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { 5301100425deSJoe Perches $new_leading_tabs = $1; 5302100425deSJoe Perches if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { 5303100425deSJoe Perches $do_fix = 0; 5304100425deSJoe Perches } 5305100425deSJoe Perches } else { 5306100425deSJoe Perches $do_fix = 0; 5307100425deSJoe Perches } 5308100425deSJoe Perches if ($do_fix) { 5309100425deSJoe Perches fix_delete_line($fixlinenr - 1, $prevrawline); 5310100425deSJoe Perches $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; 5311100425deSJoe Perches } 5312100425deSJoe Perches } 53134c432a8fSGreg Kroah-Hartman } 53144c432a8fSGreg Kroah-Hartman } 5315f0a594c1SAndy Whitcroft 5316ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages 5317ebfdc409SJoe Perches if ($line =~ /^\+.*\b$logFunctions\s*\(/ && 5318ebfdc409SJoe Perches $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && 5319ebfdc409SJoe Perches (defined $1 || defined $3) && 5320ebfdc409SJoe Perches $linenr > 3) { 5321ebfdc409SJoe Perches my $testval = $2; 5322ebfdc409SJoe Perches my $testline = $lines[$linenr - 3]; 5323ebfdc409SJoe Perches 5324ebfdc409SJoe Perches my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); 5325ebfdc409SJoe Perches# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); 5326ebfdc409SJoe Perches 5327fb0d0e08SJoe 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)/) { 5328ebfdc409SJoe Perches WARN("OOM_MESSAGE", 5329ebfdc409SJoe Perches "Possible unnecessary 'out of memory' message\n" . $hereprev); 5330ebfdc409SJoe Perches } 5331ebfdc409SJoe Perches } 5332ebfdc409SJoe Perches 5333f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL> 5334dcaf1123SPaolo Bonzini if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && 5335f78d98f6SJoe Perches $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { 5336f78d98f6SJoe Perches my $level = $1; 5337f78d98f6SJoe Perches if (WARN("UNNECESSARY_KERN_LEVEL", 5338f78d98f6SJoe Perches "Possible unnecessary $level\n" . $herecurr) && 5339f78d98f6SJoe Perches $fix) { 5340f78d98f6SJoe Perches $fixed[$fixlinenr] =~ s/\s*$level\s*//; 5341f78d98f6SJoe Perches } 5342f78d98f6SJoe Perches } 5343f78d98f6SJoe Perches 534445c55e92SJoe Perches# check for logging continuations 534545c55e92SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { 534645c55e92SJoe Perches WARN("LOGGING_CONTINUATION", 534745c55e92SJoe Perches "Avoid logging continuation uses where feasible\n" . $herecurr); 534845c55e92SJoe Perches } 534945c55e92SJoe Perches 5350abb08a53SJoe Perches# check for mask then right shift without a parentheses 5351abb08a53SJoe Perches if ($^V && $^V ge 5.10.0 && 5352abb08a53SJoe Perches $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && 5353abb08a53SJoe Perches $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so 5354abb08a53SJoe Perches WARN("MASK_THEN_SHIFT", 5355abb08a53SJoe Perches "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); 5356abb08a53SJoe Perches } 5357abb08a53SJoe Perches 5358b75ac618SJoe Perches# check for pointer comparisons to NULL 5359b75ac618SJoe Perches if ($^V && $^V ge 5.10.0) { 5360b75ac618SJoe Perches while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { 5361b75ac618SJoe Perches my $val = $1; 5362b75ac618SJoe Perches my $equal = "!"; 5363b75ac618SJoe Perches $equal = "" if ($4 eq "!="); 5364b75ac618SJoe Perches if (CHK("COMPARISON_TO_NULL", 5365b75ac618SJoe Perches "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && 5366b75ac618SJoe Perches $fix) { 5367b75ac618SJoe Perches $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; 5368b75ac618SJoe Perches } 5369b75ac618SJoe Perches } 5370b75ac618SJoe Perches } 5371b75ac618SJoe Perches 53728716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata) 53738716de38SJoe Perches if ($line =~ /(\b$InitAttribute\b)/) { 53748716de38SJoe Perches my $attr = $1; 53758716de38SJoe Perches if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { 53768716de38SJoe Perches my $ptr = $1; 53778716de38SJoe Perches my $var = $2; 53788716de38SJoe Perches if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && 53798716de38SJoe Perches ERROR("MISPLACED_INIT", 53808716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr)) || 53818716de38SJoe Perches ($ptr !~ /\b(union|struct)\s+$attr\b/ && 53828716de38SJoe Perches WARN("MISPLACED_INIT", 53838716de38SJoe Perches "$attr should be placed after $var\n" . $herecurr))) && 53848716de38SJoe Perches $fix) { 5385194f66fcSJoe 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; 53868716de38SJoe Perches } 53878716de38SJoe Perches } 53888716de38SJoe Perches } 53898716de38SJoe Perches 5390e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const 5391e970b884SJoe Perches if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { 5392e970b884SJoe Perches my $attr = $1; 5393e970b884SJoe Perches $attr =~ /($InitAttributePrefix)(.*)/; 5394e970b884SJoe Perches my $attr_prefix = $1; 5395e970b884SJoe Perches my $attr_type = $2; 5396e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5397e970b884SJoe Perches "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && 5398e970b884SJoe Perches $fix) { 5399194f66fcSJoe Perches $fixed[$fixlinenr] =~ 5400e970b884SJoe Perches s/$InitAttributeData/${attr_prefix}initconst/; 5401e970b884SJoe Perches } 5402e970b884SJoe Perches } 5403e970b884SJoe Perches 5404e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const 5405e970b884SJoe Perches if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { 5406e970b884SJoe Perches my $attr = $1; 5407e970b884SJoe Perches if (ERROR("INIT_ATTRIBUTE", 5408e970b884SJoe Perches "Use of $attr requires a separate use of const\n" . $herecurr) && 5409e970b884SJoe Perches $fix) { 5410194f66fcSJoe Perches my $lead = $fixed[$fixlinenr] =~ 5411e970b884SJoe Perches /(^\+\s*(?:static\s+))/; 5412e970b884SJoe Perches $lead = rtrim($1); 5413e970b884SJoe Perches $lead = "$lead " if ($lead !~ /^\+$/); 5414e970b884SJoe Perches $lead = "${lead}const "; 5415194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; 5416e970b884SJoe Perches } 5417e970b884SJoe Perches } 5418e970b884SJoe Perches 5419c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const) 5420c17893c7SJoe Perches if ($line =~ /\b__read_mostly\b/ && 5421c17893c7SJoe Perches $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { 5422c17893c7SJoe Perches if (ERROR("CONST_READ_MOSTLY", 5423c17893c7SJoe Perches "Invalid use of __read_mostly with const type\n" . $herecurr) && 5424c17893c7SJoe Perches $fix) { 5425c17893c7SJoe Perches $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; 5426c17893c7SJoe Perches } 5427c17893c7SJoe Perches } 5428c17893c7SJoe Perches 5429fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/ 5430fbdb8138SJoe Perches if ($realfile !~ m@^include/uapi/@ && 5431fbdb8138SJoe Perches $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { 5432fbdb8138SJoe Perches my $constant_func = $1; 5433fbdb8138SJoe Perches my $func = $constant_func; 5434fbdb8138SJoe Perches $func =~ s/^__constant_//; 5435fbdb8138SJoe Perches if (WARN("CONSTANT_CONVERSION", 5436fbdb8138SJoe Perches "$constant_func should be $func\n" . $herecurr) && 5437fbdb8138SJoe Perches $fix) { 5438194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; 5439fbdb8138SJoe Perches } 5440fbdb8138SJoe Perches } 5441fbdb8138SJoe Perches 54421a15a250SPatrick Pannuto# prefer usleep_range over udelay 544337581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 544443c1d77cSJoe Perches my $delay = $1; 54451a15a250SPatrick Pannuto # ignore udelay's < 10, however 544643c1d77cSJoe Perches if (! ($delay < 10) ) { 5447000d1cc1SJoe Perches CHK("USLEEP_RANGE", 544843c1d77cSJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); 544943c1d77cSJoe Perches } 545043c1d77cSJoe Perches if ($delay > 2000) { 545143c1d77cSJoe Perches WARN("LONG_UDELAY", 545243c1d77cSJoe Perches "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); 54531a15a250SPatrick Pannuto } 54541a15a250SPatrick Pannuto } 54551a15a250SPatrick Pannuto 545609ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 545709ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 545809ef8725SPatrick Pannuto if ($1 < 20) { 5459000d1cc1SJoe Perches WARN("MSLEEP", 546043c1d77cSJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); 546109ef8725SPatrick Pannuto } 546209ef8725SPatrick Pannuto } 546309ef8725SPatrick Pannuto 546436ec1939SJoe Perches# check for comparisons of jiffies 546536ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 546636ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 546736ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 546836ec1939SJoe Perches } 546936ec1939SJoe Perches 54709d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 54719d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 54729d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 54739d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 54749d7a34a5SJoe Perches } 54759d7a34a5SJoe Perches 547600df344fSAndy Whitcroft# warn about #ifdefs in C files 5477c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 547800df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 547900df344fSAndy Whitcroft# print "$herecurr"; 548000df344fSAndy Whitcroft# $clean = 0; 548100df344fSAndy Whitcroft# } 548200df344fSAndy Whitcroft 548322f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 5484c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 54853705ce5bSJoe Perches if (ERROR("SPACING", 54863705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 54873705ce5bSJoe Perches $fix) { 5488194f66fcSJoe Perches $fixed[$fixlinenr] =~ 54893705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 54903705ce5bSJoe Perches } 54913705ce5bSJoe Perches 549222f2a2efSAndy Whitcroft } 549322f2a2efSAndy Whitcroft 54944a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 5495171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 5496171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 54974a0df2efSAndy Whitcroft my $which = $1; 54984a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5499000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 5500000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 55014a0df2efSAndy Whitcroft } 55024a0df2efSAndy Whitcroft } 55034a0df2efSAndy Whitcroft# check for memory barriers without a comment. 5504402c2553SMichael S. Tsirkin 5505402c2553SMichael S. Tsirkin my $barriers = qr{ 5506402c2553SMichael S. Tsirkin mb| 5507402c2553SMichael S. Tsirkin rmb| 5508402c2553SMichael S. Tsirkin wmb| 5509402c2553SMichael S. Tsirkin read_barrier_depends 5510402c2553SMichael S. Tsirkin }x; 5511402c2553SMichael S. Tsirkin my $barrier_stems = qr{ 5512402c2553SMichael S. Tsirkin mb__before_atomic| 5513402c2553SMichael S. Tsirkin mb__after_atomic| 5514402c2553SMichael S. Tsirkin store_release| 5515402c2553SMichael S. Tsirkin load_acquire| 5516402c2553SMichael S. Tsirkin store_mb| 5517402c2553SMichael S. Tsirkin (?:$barriers) 5518402c2553SMichael S. Tsirkin }x; 5519402c2553SMichael S. Tsirkin my $all_barriers = qr{ 5520402c2553SMichael S. Tsirkin (?:$barriers)| 552143e361f2SMichael S. Tsirkin smp_(?:$barrier_stems)| 552243e361f2SMichael S. Tsirkin virt_(?:$barrier_stems) 5523402c2553SMichael S. Tsirkin }x; 5524402c2553SMichael S. Tsirkin 5525402c2553SMichael S. Tsirkin if ($line =~ /\b(?:$all_barriers)\s*\(/) { 55264a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 5527c1fd7bb9SJoe Perches WARN("MEMORY_BARRIER", 5528000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 55294a0df2efSAndy Whitcroft } 55304a0df2efSAndy Whitcroft } 55313ad81779SPaul E. McKenney 5532f4073b0fSMichael S. Tsirkin my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; 5533f4073b0fSMichael S. Tsirkin 5534f4073b0fSMichael S. Tsirkin if ($realfile !~ m@^include/asm-generic/@ && 5535f4073b0fSMichael S. Tsirkin $realfile !~ m@/barrier\.h$@ && 5536f4073b0fSMichael S. Tsirkin $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && 5537f4073b0fSMichael S. Tsirkin $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { 5538f4073b0fSMichael S. Tsirkin WARN("MEMORY_BARRIER", 5539f4073b0fSMichael S. Tsirkin "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); 5540f4073b0fSMichael S. Tsirkin } 5541f4073b0fSMichael S. Tsirkin 5542cb426e99SJoe Perches# check for waitqueue_active without a comment. 5543cb426e99SJoe Perches if ($line =~ /\bwaitqueue_active\s*\(/) { 5544cb426e99SJoe Perches if (!ctx_has_comment($first_line, $linenr)) { 5545cb426e99SJoe Perches WARN("WAITQUEUE_ACTIVE", 5546cb426e99SJoe Perches "waitqueue_active without comment\n" . $herecurr); 5547cb426e99SJoe Perches } 5548cb426e99SJoe Perches } 55493ad81779SPaul E. McKenney 55504a0df2efSAndy Whitcroft# check of hardware specific defines 5551c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 5552000d1cc1SJoe Perches CHK("ARCH_DEFINES", 5553000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 55540a920b5bSAndy Whitcroft } 5555653d4876SAndy Whitcroft 5556d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 5557d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 5558000d1cc1SJoe Perches WARN("STORAGE_CLASS", 5559000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 5560d4977c78STobias Klauser } 5561d4977c78STobias Klauser 5562de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 5563de7d4f0eSAndy Whitcroft# storage class and type. 55649c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 55659c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 5566000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 5567000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 5568de7d4f0eSAndy Whitcroft } 5569de7d4f0eSAndy Whitcroft 55708905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 55712b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55722b7ab453SJoe Perches $line =~ /\b(__inline__|__inline)\b/) { 5573d5e616fcSJoe Perches if (WARN("INLINE", 5574d5e616fcSJoe Perches "plain inline is preferred over $1\n" . $herecurr) && 5575d5e616fcSJoe Perches $fix) { 5576194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 5577d5e616fcSJoe Perches 5578d5e616fcSJoe Perches } 55798905a67cSAndy Whitcroft } 55808905a67cSAndy Whitcroft 55813d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 55822b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55832b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 5584000d1cc1SJoe Perches WARN("PREFER_PACKED", 5585000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 55863d130fd0SJoe Perches } 55873d130fd0SJoe Perches 558839b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 55892b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55902b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 5591000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 5592000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 559339b7e287SJoe Perches } 559439b7e287SJoe Perches 55955f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 55962b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 55972b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 5598d5e616fcSJoe Perches if (WARN("PREFER_PRINTF", 5599d5e616fcSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && 5600d5e616fcSJoe Perches $fix) { 5601194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; 5602d5e616fcSJoe Perches 5603d5e616fcSJoe Perches } 56045f14d3bdSJoe Perches } 56055f14d3bdSJoe Perches 56066061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 56072b7ab453SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 56082b7ab453SJoe Perches $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 5609d5e616fcSJoe Perches if (WARN("PREFER_SCANF", 5610d5e616fcSJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && 5611d5e616fcSJoe Perches $fix) { 5612194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; 5613d5e616fcSJoe Perches } 56146061d949SJoe Perches } 56156061d949SJoe Perches 5616619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues) 5617619a908aSJoe Perches if ($^V && $^V ge 5.10.0 && 5618619a908aSJoe Perches $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && 5619619a908aSJoe Perches ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || 5620619a908aSJoe Perches $line =~ /\b__weak\b/)) { 5621619a908aSJoe Perches ERROR("WEAK_DECLARATION", 5622619a908aSJoe Perches "Using weak declarations can have unintended link defects\n" . $herecurr); 5623619a908aSJoe Perches } 5624619a908aSJoe Perches 5625fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/ 5626e6176fa4SJoe Perches if ($realfile !~ m@\binclude/uapi/@ && 5627fd39f904STomas Winkler $realfile !~ m@\btools/@ && 5628e6176fa4SJoe Perches $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { 5629e6176fa4SJoe Perches my $type = $1; 5630e6176fa4SJoe Perches if ($type =~ /\b($typeC99Typedefs)\b/) { 5631e6176fa4SJoe Perches $type = $1; 5632e6176fa4SJoe Perches my $kernel_type = 'u'; 5633e6176fa4SJoe Perches $kernel_type = 's' if ($type =~ /^_*[si]/); 5634e6176fa4SJoe Perches $type =~ /(\d+)/; 5635e6176fa4SJoe Perches $kernel_type .= $1; 5636e6176fa4SJoe Perches if (CHK("PREFER_KERNEL_TYPES", 5637e6176fa4SJoe Perches "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && 5638e6176fa4SJoe Perches $fix) { 5639e6176fa4SJoe Perches $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; 5640e6176fa4SJoe Perches } 5641e6176fa4SJoe Perches } 5642e6176fa4SJoe Perches } 5643e6176fa4SJoe Perches 5644938224b5SJoe Perches# check for cast of C90 native int or longer types constants 5645938224b5SJoe Perches if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { 5646938224b5SJoe Perches my $cast = $1; 5647938224b5SJoe Perches my $const = $2; 5648938224b5SJoe Perches if (WARN("TYPECAST_INT_CONSTANT", 5649938224b5SJoe Perches "Unnecessary typecast of c90 int constant\n" . $herecurr) && 5650938224b5SJoe Perches $fix) { 5651938224b5SJoe Perches my $suffix = ""; 5652938224b5SJoe Perches my $newconst = $const; 5653938224b5SJoe Perches $newconst =~ s/${Int_type}$//; 5654938224b5SJoe Perches $suffix .= 'U' if ($cast =~ /\bunsigned\b/); 5655938224b5SJoe Perches if ($cast =~ /\blong\s+long\b/) { 5656938224b5SJoe Perches $suffix .= 'LL'; 5657938224b5SJoe Perches } elsif ($cast =~ /\blong\b/) { 5658938224b5SJoe Perches $suffix .= 'L'; 5659938224b5SJoe Perches } 5660938224b5SJoe Perches $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; 5661938224b5SJoe Perches } 5662938224b5SJoe Perches } 5663938224b5SJoe Perches 56648f53a9b8SJoe Perches# check for sizeof(&) 56658f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 5666000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 5667000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 56688f53a9b8SJoe Perches } 56698f53a9b8SJoe Perches 567066c80b60SJoe Perches# check for sizeof without parenthesis 567166c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 5672d5e616fcSJoe Perches if (WARN("SIZEOF_PARENTHESIS", 5673d5e616fcSJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr) && 5674d5e616fcSJoe Perches $fix) { 5675194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; 5676d5e616fcSJoe Perches } 567766c80b60SJoe Perches } 567866c80b60SJoe Perches 567988982feaSJoe Perches# check for struct spinlock declarations 568088982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 568188982feaSJoe Perches WARN("USE_SPINLOCK_T", 568288982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 568388982feaSJoe Perches } 568488982feaSJoe Perches 5685a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 568606668727SJoe Perches if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { 5687a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 5688caac1d5fSHeba Aamer $fmt =~ s/%%//g; 5689caac1d5fSHeba Aamer if ($fmt !~ /%/) { 5690d5e616fcSJoe Perches if (WARN("PREFER_SEQ_PUTS", 5691d5e616fcSJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr) && 5692d5e616fcSJoe Perches $fix) { 5693194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; 5694d5e616fcSJoe Perches } 5695a6962d72SJoe Perches } 5696a6962d72SJoe Perches } 5697a6962d72SJoe Perches 56980b523769SJoe Perches # check for vsprintf extension %p<foo> misuses 56990b523769SJoe Perches if ($^V && $^V ge 5.10.0 && 57000b523769SJoe Perches defined $stat && 57010b523769SJoe Perches $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && 57020b523769SJoe Perches $1 !~ /^_*volatile_*$/) { 57030b523769SJoe Perches my $bad_extension = ""; 57040b523769SJoe Perches my $lc = $stat =~ tr@\n@@; 57050b523769SJoe Perches $lc = $lc + $linenr; 57060b523769SJoe Perches for (my $count = $linenr; $count <= $lc; $count++) { 57070b523769SJoe Perches my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); 57080b523769SJoe Perches $fmt =~ s/%%//g; 5709ce4fecf1SPantelis Antoniou if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { 57100b523769SJoe Perches $bad_extension = $1; 57110b523769SJoe Perches last; 57120b523769SJoe Perches } 57130b523769SJoe Perches } 57140b523769SJoe Perches if ($bad_extension ne "") { 57150b523769SJoe Perches my $stat_real = raw_line($linenr, 0); 57160b523769SJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 57170b523769SJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 57180b523769SJoe Perches } 57190b523769SJoe Perches WARN("VSPRINTF_POINTER_EXTENSION", 57200b523769SJoe Perches "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); 57210b523769SJoe Perches } 57220b523769SJoe Perches } 57230b523769SJoe Perches 5724554e165cSAndy Whitcroft# Check for misused memsets 5725d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5726d1fe9c09SJoe Perches defined $stat && 57279e20a853SMateusz Kulikowski $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 5728554e165cSAndy Whitcroft 5729d7c76ba7SJoe Perches my $ms_addr = $2; 5730d1fe9c09SJoe Perches my $ms_val = $7; 5731d1fe9c09SJoe Perches my $ms_size = $12; 5732d7c76ba7SJoe Perches 5733554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 5734554e165cSAndy Whitcroft ERROR("MEMSET", 5735d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 5736554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 5737554e165cSAndy Whitcroft WARN("MEMSET", 5738d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 5739d7c76ba7SJoe Perches } 5740d7c76ba7SJoe Perches } 5741d7c76ba7SJoe Perches 574298a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) 5743f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5744f333195dSJoe Perches# defined $stat && 5745f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5746f333195dSJoe Perches# if (WARN("PREFER_ETHER_ADDR_COPY", 5747f333195dSJoe Perches# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && 5748f333195dSJoe Perches# $fix) { 5749f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; 5750f333195dSJoe Perches# } 5751f333195dSJoe Perches# } 575298a9bba5SJoe Perches 5753b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) 5754f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5755f333195dSJoe Perches# defined $stat && 5756f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5757f333195dSJoe Perches# WARN("PREFER_ETHER_ADDR_EQUAL", 5758f333195dSJoe Perches# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") 5759f333195dSJoe Perches# } 5760b6117d17SMateusz Kulikowski 57618617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr 57628617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr 5763f333195dSJoe Perches# if ($^V && $^V ge 5.10.0 && 5764f333195dSJoe Perches# defined $stat && 5765f333195dSJoe Perches# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { 5766f333195dSJoe Perches# 5767f333195dSJoe Perches# my $ms_val = $7; 5768f333195dSJoe Perches# 5769f333195dSJoe Perches# if ($ms_val =~ /^(?:0x|)0+$/i) { 5770f333195dSJoe Perches# if (WARN("PREFER_ETH_ZERO_ADDR", 5771f333195dSJoe Perches# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && 5772f333195dSJoe Perches# $fix) { 5773f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; 5774f333195dSJoe Perches# } 5775f333195dSJoe Perches# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { 5776f333195dSJoe Perches# if (WARN("PREFER_ETH_BROADCAST_ADDR", 5777f333195dSJoe Perches# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && 5778f333195dSJoe Perches# $fix) { 5779f333195dSJoe Perches# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; 5780f333195dSJoe Perches# } 5781f333195dSJoe Perches# } 5782f333195dSJoe Perches# } 57838617cd09SMateusz Kulikowski 5784d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 5785d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 5786d1fe9c09SJoe Perches defined $stat && 5787d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 5788d1fe9c09SJoe Perches if (defined $2 || defined $7) { 5789d7c76ba7SJoe Perches my $call = $1; 5790d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 5791d7c76ba7SJoe Perches my $arg1 = $3; 5792d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 5793d1fe9c09SJoe Perches my $arg2 = $8; 5794d7c76ba7SJoe Perches my $cast; 5795d7c76ba7SJoe Perches 5796d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 5797d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 5798d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 5799d7c76ba7SJoe Perches $cast = $cast1; 5800d7c76ba7SJoe Perches } else { 5801d7c76ba7SJoe Perches $cast = $cast2; 5802d7c76ba7SJoe Perches } 5803d7c76ba7SJoe Perches WARN("MINMAX", 5804d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 5805554e165cSAndy Whitcroft } 5806554e165cSAndy Whitcroft } 5807554e165cSAndy Whitcroft 58084a273195SJoe Perches# check usleep_range arguments 58094a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 58104a273195SJoe Perches defined $stat && 58114a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 58124a273195SJoe Perches my $min = $1; 58134a273195SJoe Perches my $max = $7; 58144a273195SJoe Perches if ($min eq $max) { 58154a273195SJoe Perches WARN("USLEEP_RANGE", 58164a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58174a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 58184a273195SJoe Perches $min > $max) { 58194a273195SJoe Perches WARN("USLEEP_RANGE", 58204a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 58214a273195SJoe Perches } 58224a273195SJoe Perches } 58234a273195SJoe Perches 5824823b794cSJoe Perches# check for naked sscanf 5825823b794cSJoe Perches if ($^V && $^V ge 5.10.0 && 5826823b794cSJoe Perches defined $stat && 58276c8bd707SJoe Perches $line =~ /\bsscanf\b/ && 5828823b794cSJoe Perches ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && 5829823b794cSJoe Perches $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && 5830823b794cSJoe Perches $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { 5831823b794cSJoe Perches my $lc = $stat =~ tr@\n@@; 5832823b794cSJoe Perches $lc = $lc + $linenr; 5833823b794cSJoe Perches my $stat_real = raw_line($linenr, 0); 5834823b794cSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5835823b794cSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5836823b794cSJoe Perches } 5837823b794cSJoe Perches WARN("NAKED_SSCANF", 5838823b794cSJoe Perches "unchecked sscanf return value\n" . "$here\n$stat_real\n"); 5839823b794cSJoe Perches } 5840823b794cSJoe Perches 5841afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo> 5842afc819abSJoe Perches if ($^V && $^V ge 5.10.0 && 5843afc819abSJoe Perches defined $stat && 5844afc819abSJoe Perches $line =~ /\bsscanf\b/) { 5845afc819abSJoe Perches my $lc = $stat =~ tr@\n@@; 5846afc819abSJoe Perches $lc = $lc + $linenr; 5847afc819abSJoe Perches my $stat_real = raw_line($linenr, 0); 5848afc819abSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 5849afc819abSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 5850afc819abSJoe Perches } 5851afc819abSJoe Perches if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { 5852afc819abSJoe Perches my $format = $6; 5853afc819abSJoe Perches my $count = $format =~ tr@%@%@; 5854afc819abSJoe Perches if ($count == 1 && 5855afc819abSJoe Perches $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { 5856afc819abSJoe Perches WARN("SSCANF_TO_KSTRTO", 5857afc819abSJoe Perches "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); 5858afc819abSJoe Perches } 5859afc819abSJoe Perches } 5860afc819abSJoe Perches } 5861afc819abSJoe Perches 586270dc8a48SJoe Perches# check for new externs in .h files. 586370dc8a48SJoe Perches if ($realfile =~ /\.h$/ && 586470dc8a48SJoe Perches $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { 5865d1d85780SJoe Perches if (CHK("AVOID_EXTERNS", 586670dc8a48SJoe Perches "extern prototypes should be avoided in .h files\n" . $herecurr) && 586770dc8a48SJoe Perches $fix) { 5868194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; 586970dc8a48SJoe Perches } 587070dc8a48SJoe Perches } 587170dc8a48SJoe Perches 5872de7d4f0eSAndy Whitcroft# check for new externs in .c files. 5873171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 5874c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 5875171ae1a4SAndy Whitcroft { 5876c45dcabdSAndy Whitcroft my $function_name = $1; 5877c45dcabdSAndy Whitcroft my $paren_space = $2; 5878171ae1a4SAndy Whitcroft 5879171ae1a4SAndy Whitcroft my $s = $stat; 5880171ae1a4SAndy Whitcroft if (defined $cond) { 5881171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 5882171ae1a4SAndy Whitcroft } 5883c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 5884c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 5885c45dcabdSAndy Whitcroft { 5886000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5887000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5888de7d4f0eSAndy Whitcroft } 5889de7d4f0eSAndy Whitcroft 5890171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 5891000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 5892000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 5893171ae1a4SAndy Whitcroft } 58949c9ba34eSAndy Whitcroft 58959c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 58969c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 58979c9ba34eSAndy Whitcroft { 5898000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 5899000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 5900171ae1a4SAndy Whitcroft } 5901171ae1a4SAndy Whitcroft 5902a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names 5903a0ad7596SJoe Perches if (defined $stat && 5904ca0d8929SJoe Perches $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && 5905ca0d8929SJoe Perches $1 ne "void") { 5906ca0d8929SJoe Perches my $args = trim($1); 5907ca0d8929SJoe Perches while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { 5908ca0d8929SJoe Perches my $arg = trim($1); 5909ca0d8929SJoe Perches if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { 5910ca0d8929SJoe Perches WARN("FUNCTION_ARGUMENTS", 5911ca0d8929SJoe Perches "function definition argument '$arg' should also have an identifier name\n" . $herecurr); 5912ca0d8929SJoe Perches } 5913ca0d8929SJoe Perches } 5914ca0d8929SJoe Perches } 5915ca0d8929SJoe Perches 5916a0ad7596SJoe Perches# check for function definitions 5917a0ad7596SJoe Perches if ($^V && $^V ge 5.10.0 && 5918a0ad7596SJoe Perches defined $stat && 5919a0ad7596SJoe Perches $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { 5920a0ad7596SJoe Perches $context_function = $1; 5921a0ad7596SJoe Perches 5922a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace 5923a0ad7596SJoe Perches my $ok = 0; 5924a0ad7596SJoe Perches my $cnt = statement_rawlines($stat); 5925a0ad7596SJoe Perches my $herectx = $here . "\n"; 5926a0ad7596SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 5927a0ad7596SJoe Perches my $rl = raw_line($linenr, $n); 5928a0ad7596SJoe Perches $herectx .= $rl . "\n"; 5929a0ad7596SJoe Perches $ok = 1 if ($rl =~ /^[ \+]\{/); 5930a0ad7596SJoe Perches $ok = 1 if ($rl =~ /\{/ && $n == 0); 5931a0ad7596SJoe Perches last if $rl =~ /^[ \+].*\{/; 5932a0ad7596SJoe Perches } 5933a0ad7596SJoe Perches if (!$ok) { 5934a0ad7596SJoe Perches ERROR("OPEN_BRACE", 5935a0ad7596SJoe Perches "open brace '{' following function definitions go on the next line\n" . $herectx); 5936a0ad7596SJoe Perches } 5937a0ad7596SJoe Perches } 5938a0ad7596SJoe Perches 5939de7d4f0eSAndy Whitcroft# checks for new __setup's 5940de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 5941de7d4f0eSAndy Whitcroft my $name = $1; 5942de7d4f0eSAndy Whitcroft 5943de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 5944000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 59458c27ceffSMauro Carvalho Chehab "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); 5946de7d4f0eSAndy Whitcroft } 5947653d4876SAndy Whitcroft } 59489c0ca6f9SAndy Whitcroft 59499c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 5950caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 5951000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 5952000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 59539c0ca6f9SAndy Whitcroft } 595413214adfSAndy Whitcroft 5955a640d25cSJoe Perches# alloc style 5956a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 5957a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 5958a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 5959a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 5960a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 5961a640d25cSJoe Perches } 5962a640d25cSJoe Perches 596360a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc 596460a55369SJoe Perches if ($^V && $^V ge 5.10.0 && 59651b4a2ed4SJoe Perches defined $stat && 59661b4a2ed4SJoe Perches $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { 596760a55369SJoe Perches my $oldfunc = $3; 596860a55369SJoe Perches my $a1 = $4; 596960a55369SJoe Perches my $a2 = $10; 597060a55369SJoe Perches my $newfunc = "kmalloc_array"; 597160a55369SJoe Perches $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); 597260a55369SJoe Perches my $r1 = $a1; 597360a55369SJoe Perches my $r2 = $a2; 597460a55369SJoe Perches if ($a1 =~ /^sizeof\s*\S/) { 597560a55369SJoe Perches $r1 = $a2; 597660a55369SJoe Perches $r2 = $a1; 597760a55369SJoe Perches } 5978e367455aSJoe Perches if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && 5979e367455aSJoe Perches !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { 59801b4a2ed4SJoe Perches my $ctx = ''; 59811b4a2ed4SJoe Perches my $herectx = $here . "\n"; 59821b4a2ed4SJoe Perches my $cnt = statement_rawlines($stat); 59831b4a2ed4SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 59841b4a2ed4SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 59851b4a2ed4SJoe Perches } 5986e367455aSJoe Perches if (WARN("ALLOC_WITH_MULTIPLY", 59871b4a2ed4SJoe Perches "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && 59881b4a2ed4SJoe Perches $cnt == 1 && 5989e367455aSJoe Perches $fix) { 5990194f66fcSJoe 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; 599160a55369SJoe Perches } 599260a55369SJoe Perches } 599360a55369SJoe Perches } 599460a55369SJoe Perches 5995972fdea2SJoe Perches# check for krealloc arg reuse 5996972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 5997972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 5998972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 5999972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 6000972fdea2SJoe Perches } 6001972fdea2SJoe Perches 60025ce59ae0SJoe Perches# check for alloc argument mismatch 60035ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 60045ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 60055ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 60065ce59ae0SJoe Perches } 60075ce59ae0SJoe Perches 6008caf2a54fSJoe Perches# check for multiple semicolons 6009caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 6010d5e616fcSJoe Perches if (WARN("ONE_SEMICOLON", 6011d5e616fcSJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr) && 6012d5e616fcSJoe Perches $fix) { 6013194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; 6014d5e616fcSJoe Perches } 6015d1e2ad07SJoe Perches } 6016d1e2ad07SJoe Perches 6017cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi 6018cec3aaa5STomas Winkler if ($realfile !~ m@^include/uapi/@ && 6019cec3aaa5STomas Winkler $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { 60200ab90191SJoe Perches my $ull = ""; 60210ab90191SJoe Perches $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); 60220ab90191SJoe Perches if (CHK("BIT_MACRO", 60230ab90191SJoe Perches "Prefer using the BIT$ull macro\n" . $herecurr) && 60240ab90191SJoe Perches $fix) { 60250ab90191SJoe Perches $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; 60260ab90191SJoe Perches } 60270ab90191SJoe Perches } 60280ab90191SJoe Perches 60292d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE 60302d632745SJoe 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*$/) { 60312d632745SJoe Perches my $config = $1; 60322d632745SJoe Perches if (WARN("PREFER_IS_ENABLED", 60332d632745SJoe Perches "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) && 60342d632745SJoe Perches $fix) { 60352d632745SJoe Perches $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; 60362d632745SJoe Perches } 60372d632745SJoe Perches } 60382d632745SJoe Perches 6039e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch 6040c34c09a8SJoe Perches if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { 6041c34c09a8SJoe Perches my $has_break = 0; 6042c34c09a8SJoe Perches my $has_statement = 0; 6043c34c09a8SJoe Perches my $count = 0; 6044c34c09a8SJoe Perches my $prevline = $linenr; 6045e81f239bSJoe Perches while ($prevline > 1 && ($file || $count < 3) && !$has_break) { 6046c34c09a8SJoe Perches $prevline--; 6047c34c09a8SJoe Perches my $rline = $rawlines[$prevline - 1]; 6048c34c09a8SJoe Perches my $fline = $lines[$prevline - 1]; 6049c34c09a8SJoe Perches last if ($fline =~ /^\@\@/); 6050c34c09a8SJoe Perches next if ($fline =~ /^\-/); 6051c34c09a8SJoe Perches next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); 6052c34c09a8SJoe Perches $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); 6053c34c09a8SJoe Perches next if ($fline =~ /^.[\s$;]*$/); 6054c34c09a8SJoe Perches $has_statement = 1; 6055c34c09a8SJoe Perches $count++; 6056c34c09a8SJoe Perches $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); 6057c34c09a8SJoe Perches } 6058c34c09a8SJoe Perches if (!$has_break && $has_statement) { 6059c34c09a8SJoe Perches WARN("MISSING_BREAK", 6060224236d9SAndrew Morton "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); 6061c34c09a8SJoe Perches } 6062c34c09a8SJoe Perches } 6063c34c09a8SJoe Perches 6064d1e2ad07SJoe Perches# check for switch/default statements without a break; 6065d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 6066d1e2ad07SJoe Perches defined $stat && 6067d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 6068d1e2ad07SJoe Perches my $ctx = ''; 6069d1e2ad07SJoe Perches my $herectx = $here . "\n"; 6070d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 6071d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 6072d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 6073d1e2ad07SJoe Perches } 6074d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 6075d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 6076caf2a54fSJoe Perches } 6077caf2a54fSJoe Perches 607813214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 6079d5e616fcSJoe Perches if ($line =~ /\b__FUNCTION__\b/) { 6080d5e616fcSJoe Perches if (WARN("USE_FUNC", 6081d5e616fcSJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && 6082d5e616fcSJoe Perches $fix) { 6083194f66fcSJoe Perches $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; 6084d5e616fcSJoe Perches } 608513214adfSAndy Whitcroft } 6086773647a0SAndy Whitcroft 608762ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__ 608862ec818fSJoe Perches while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { 608962ec818fSJoe Perches ERROR("DATE_TIME", 609062ec818fSJoe Perches "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); 609162ec818fSJoe Perches } 609262ec818fSJoe Perches 60932c92488aSJoe Perches# check for use of yield() 60942c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 60952c92488aSJoe Perches WARN("YIELD", 60962c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 60972c92488aSJoe Perches } 60982c92488aSJoe Perches 6099179f8f40SJoe Perches# check for comparisons against true and false 6100179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 6101179f8f40SJoe Perches my $lead = $1; 6102179f8f40SJoe Perches my $arg = $2; 6103179f8f40SJoe Perches my $test = $3; 6104179f8f40SJoe Perches my $otype = $4; 6105179f8f40SJoe Perches my $trail = $5; 6106179f8f40SJoe Perches my $op = "!"; 6107179f8f40SJoe Perches 6108179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 6109179f8f40SJoe Perches 6110179f8f40SJoe Perches my $type = lc($otype); 6111179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 6112179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 6113179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 6114179f8f40SJoe Perches $op = ""; 6115179f8f40SJoe Perches } 6116179f8f40SJoe Perches 6117179f8f40SJoe Perches CHK("BOOL_COMPARISON", 6118179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 6119179f8f40SJoe Perches 6120179f8f40SJoe Perches## maybe suggesting a correct construct would better 6121179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 6122179f8f40SJoe Perches 6123179f8f40SJoe Perches } 6124179f8f40SJoe Perches } 6125179f8f40SJoe Perches 61264882720bSThomas Gleixner# check for semaphores initialized locked 61274882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 6128000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 6129000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 6130773647a0SAndy Whitcroft } 61316712d858SJoe Perches 613267d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 613367d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 6134000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 613567d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 6136773647a0SAndy Whitcroft } 61376712d858SJoe Perches 6138ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please 6139f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 6140000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 6141ae3ccc46SFabian Frederick "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6142f3db6639SMichael Ellerman } 61436712d858SJoe Perches 61440f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree) 6145d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {' 61466903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 6147d9190e4eSJoe Perches $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { 6148000d1cc1SJoe Perches WARN("CONST_STRUCT", 6149d9190e4eSJoe Perches "struct $1 should normally be const\n" . $herecurr); 61502b6db5cbSAndy Whitcroft } 6151773647a0SAndy Whitcroft 6152773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 6153773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 6154773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 6155c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 6156c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 6157171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 6158171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 6159171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 6160773647a0SAndy Whitcroft { 6161000d1cc1SJoe Perches WARN("NR_CPUS", 6162000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 6163773647a0SAndy Whitcroft } 61649c9ba34eSAndy Whitcroft 616552ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. 616652ea8506SJoe Perches if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { 616752ea8506SJoe Perches ERROR("DEFINE_ARCH_HAS", 616852ea8506SJoe Perches "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); 616952ea8506SJoe Perches } 617052ea8506SJoe Perches 6171acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)" 6172acd9362cSJoe Perches if ($^V && $^V ge 5.10.0 && 6173acd9362cSJoe Perches $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { 6174acd9362cSJoe Perches WARN("LIKELY_MISUSE", 6175acd9362cSJoe Perches "Using $1 should generally have parentheses around the comparison\n" . $herecurr); 6176acd9362cSJoe Perches } 6177acd9362cSJoe Perches 6178691d77b6SAndy Whitcroft# whine mightly about in_atomic 6179691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 6180691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 6181000d1cc1SJoe Perches ERROR("IN_ATOMIC", 6182000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 6183f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 6184000d1cc1SJoe Perches WARN("IN_ATOMIC", 6185000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 6186691d77b6SAndy Whitcroft } 6187691d77b6SAndy Whitcroft } 61881704f47bSPeter Zijlstra 6189481aea5cSJoe Perches# whine about ACCESS_ONCE 6190481aea5cSJoe Perches if ($^V && $^V ge 5.10.0 && 6191481aea5cSJoe Perches $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { 6192481aea5cSJoe Perches my $par = $1; 6193481aea5cSJoe Perches my $eq = $2; 6194481aea5cSJoe Perches my $fun = $3; 6195481aea5cSJoe Perches $par =~ s/^\(\s*(.*)\s*\)$/$1/; 6196481aea5cSJoe Perches if (defined($eq)) { 6197481aea5cSJoe Perches if (WARN("PREFER_WRITE_ONCE", 6198481aea5cSJoe Perches "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && 6199481aea5cSJoe Perches $fix) { 6200481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; 6201481aea5cSJoe Perches } 6202481aea5cSJoe Perches } else { 6203481aea5cSJoe Perches if (WARN("PREFER_READ_ONCE", 6204481aea5cSJoe Perches "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && 6205481aea5cSJoe Perches $fix) { 6206481aea5cSJoe Perches $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; 6207481aea5cSJoe Perches } 6208481aea5cSJoe Perches } 6209481aea5cSJoe Perches } 6210481aea5cSJoe Perches 62110f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage 62120f5225b0SPeter Zijlstra if ($line =~ /mutex_trylock_recursive/) { 62130f5225b0SPeter Zijlstra ERROR("LOCKING", 62140f5225b0SPeter Zijlstra "recursive locking is bad, do not use this ever.\n" . $herecurr); 62150f5225b0SPeter Zijlstra } 62160f5225b0SPeter Zijlstra 62171704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 62181704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 62191704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 62201704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 62211704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 62221704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 6223000d1cc1SJoe Perches ERROR("LOCKDEP", 6224000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 62251704f47bSPeter Zijlstra } 62261704f47bSPeter Zijlstra } 622788f8831cSDave Jones 6228b392c64fSJoe Perches if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || 6229b392c64fSJoe Perches $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { 6230000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 6231000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 623288f8831cSDave Jones } 62332435880fSJoe Perches 6234515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal 6235515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop 6236515a235eSJoe Perches if ($^V && $^V ge 5.10.0 && 6237459cf0aeSJoe Perches defined $stat && 6238515a235eSJoe Perches $line =~ /$mode_perms_search/) { 62392435880fSJoe Perches foreach my $entry (@mode_permission_funcs) { 62402435880fSJoe Perches my $func = $entry->[0]; 62412435880fSJoe Perches my $arg_pos = $entry->[1]; 62422435880fSJoe Perches 6243459cf0aeSJoe Perches my $lc = $stat =~ tr@\n@@; 6244459cf0aeSJoe Perches $lc = $lc + $linenr; 6245459cf0aeSJoe Perches my $stat_real = raw_line($linenr, 0); 6246459cf0aeSJoe Perches for (my $count = $linenr + 1; $count <= $lc; $count++) { 6247459cf0aeSJoe Perches $stat_real = $stat_real . "\n" . raw_line($count, 0); 6248459cf0aeSJoe Perches } 6249459cf0aeSJoe Perches 62502435880fSJoe Perches my $skip_args = ""; 62512435880fSJoe Perches if ($arg_pos > 1) { 62522435880fSJoe Perches $arg_pos--; 62532435880fSJoe Perches $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; 62542435880fSJoe Perches } 6255f90774e1SJoe Perches my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; 6256459cf0aeSJoe Perches if ($stat =~ /$test/) { 62572435880fSJoe Perches my $val = $1; 62582435880fSJoe Perches $val = $6 if ($skip_args ne ""); 6259f90774e1SJoe Perches if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || 6260f90774e1SJoe Perches ($val =~ /^$Octal$/ && length($val) ne 4)) { 62612435880fSJoe Perches ERROR("NON_OCTAL_PERMISSIONS", 6262459cf0aeSJoe Perches "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); 6263f90774e1SJoe Perches } 6264f90774e1SJoe Perches if ($val =~ /^$Octal$/ && (oct($val) & 02)) { 6265c0a5c898SJoe Perches ERROR("EXPORTED_WORLD_WRITABLE", 6266459cf0aeSJoe Perches "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); 62672435880fSJoe Perches } 6268459cf0aeSJoe Perches } 6269459cf0aeSJoe Perches } 6270459cf0aeSJoe Perches } 6271459cf0aeSJoe Perches 6272459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability 6273459cf0aeSJoe Perches if ($line =~ /\b$mode_perms_string_search\b/) { 6274459cf0aeSJoe Perches my $val = ""; 6275459cf0aeSJoe Perches my $oval = ""; 6276f90774e1SJoe Perches my $to = 0; 6277459cf0aeSJoe Perches my $curpos = 0; 6278459cf0aeSJoe Perches my $lastpos = 0; 6279459cf0aeSJoe Perches while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { 6280459cf0aeSJoe Perches $curpos = pos($line); 6281459cf0aeSJoe Perches my $match = $2; 6282459cf0aeSJoe Perches my $omatch = $1; 6283459cf0aeSJoe Perches last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); 6284459cf0aeSJoe Perches $lastpos = $curpos; 6285459cf0aeSJoe Perches $to |= $mode_permission_string_types{$match}; 6286459cf0aeSJoe Perches $val .= '\s*\|\s*' if ($val ne ""); 6287459cf0aeSJoe Perches $val .= $match; 6288459cf0aeSJoe Perches $oval .= $omatch; 6289f90774e1SJoe Perches } 6290459cf0aeSJoe Perches $oval =~ s/^\s*\|\s*//; 6291459cf0aeSJoe Perches $oval =~ s/\s*\|\s*$//; 6292459cf0aeSJoe Perches my $octal = sprintf("%04o", $to); 6293f90774e1SJoe Perches if (WARN("SYMBOLIC_PERMS", 6294459cf0aeSJoe Perches "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && 6295f90774e1SJoe Perches $fix) { 6296459cf0aeSJoe Perches $fixed[$fixlinenr] =~ s/$val/$octal/; 62972435880fSJoe Perches } 629813214adfSAndy Whitcroft } 62995a6d20ceSBjorn Andersson 63005a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h 63015a6d20ceSBjorn Andersson if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { 63025a6d20ceSBjorn Andersson my $extracted_string = get_quoted_string($line, $rawline); 63035a6d20ceSBjorn Andersson my $valid_licenses = qr{ 63045a6d20ceSBjorn Andersson GPL| 63055a6d20ceSBjorn Andersson GPL\ v2| 63065a6d20ceSBjorn Andersson GPL\ and\ additional\ rights| 63075a6d20ceSBjorn Andersson Dual\ BSD/GPL| 63085a6d20ceSBjorn Andersson Dual\ MIT/GPL| 63095a6d20ceSBjorn Andersson Dual\ MPL/GPL| 63105a6d20ceSBjorn Andersson Proprietary 63115a6d20ceSBjorn Andersson }x; 63125a6d20ceSBjorn Andersson if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { 63135a6d20ceSBjorn Andersson WARN("MODULE_LICENSE", 63145a6d20ceSBjorn Andersson "unknown module license " . $extracted_string . "\n" . $herecurr); 63155a6d20ceSBjorn Andersson } 63165a6d20ceSBjorn Andersson } 6317515a235eSJoe Perches } 631813214adfSAndy Whitcroft 631913214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 632013214adfSAndy Whitcroft # so just keep quiet. 632113214adfSAndy Whitcroft if ($#rawlines == -1) { 632213214adfSAndy Whitcroft exit(0); 63230a920b5bSAndy Whitcroft } 63240a920b5bSAndy Whitcroft 63258905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 63268905a67cSAndy Whitcroft # things that appear to be patches. 63278905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 63288905a67cSAndy Whitcroft exit(0); 63298905a67cSAndy Whitcroft } 63308905a67cSAndy Whitcroft 63318905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 63328905a67cSAndy Whitcroft # just keep quiet. 63338905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 63348905a67cSAndy Whitcroft exit(0); 63358905a67cSAndy Whitcroft } 63368905a67cSAndy Whitcroft 633706330fc4SJoe Perches if (!$is_patch && $file !~ /cover-letter\.patch$/) { 6338000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 6339000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 63400a920b5bSAndy Whitcroft } 6341ed43c4e5SAllen Hubbe if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { 6342000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 6343000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 63440a920b5bSAndy Whitcroft } 63450a920b5bSAndy Whitcroft 6346f0a594c1SAndy Whitcroft print report_dump(); 634713214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 634813214adfSAndy Whitcroft print "$filename " if ($summary_file); 63496c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 63506c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 63516c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 63526c72ffaaSAndy Whitcroft } 63538905a67cSAndy Whitcroft 6354d2c0a235SAndy Whitcroft if ($quiet == 0) { 6355ef212196SJoe Perches # If there were any defects found and not already fixing them 6356ef212196SJoe Perches if (!$clean and !$fix) { 6357ef212196SJoe Perches print << "EOM" 6358ef212196SJoe Perches 6359ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to 6360ef212196SJoe Perches mechanically convert to the typical style using --fix or --fix-inplace. 6361ef212196SJoe PerchesEOM 6362ef212196SJoe Perches } 6363d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 6364d2c0a235SAndy Whitcroft # then suggest that. 6365d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 6366b0781216SMike Frysinger $rpt_cleaners = 0; 6367d8469f16SJoe Perches print << "EOM" 6368d8469f16SJoe Perches 6369d8469f16SJoe PerchesNOTE: Whitespace errors detected. 6370d8469f16SJoe Perches You may wish to use scripts/cleanpatch or scripts/cleanfile 6371d8469f16SJoe PerchesEOM 6372d2c0a235SAndy Whitcroft } 6373d2c0a235SAndy Whitcroft } 6374d2c0a235SAndy Whitcroft 6375d752fcc8SJoe Perches if ($clean == 0 && $fix && 6376d752fcc8SJoe Perches ("@rawlines" ne "@fixed" || 6377d752fcc8SJoe Perches $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { 63789624b8d6SJoe Perches my $newfile = $filename; 63799624b8d6SJoe Perches $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); 63803705ce5bSJoe Perches my $linecount = 0; 63813705ce5bSJoe Perches my $f; 63823705ce5bSJoe Perches 6383d752fcc8SJoe Perches @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); 6384d752fcc8SJoe Perches 63853705ce5bSJoe Perches open($f, '>', $newfile) 63863705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 63873705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 63883705ce5bSJoe Perches $linecount++; 63893705ce5bSJoe Perches if ($file) { 63903705ce5bSJoe Perches if ($linecount > 3) { 63913705ce5bSJoe Perches $fixed_line =~ s/^\+//; 63923705ce5bSJoe Perches print $f $fixed_line . "\n"; 63933705ce5bSJoe Perches } 63943705ce5bSJoe Perches } else { 63953705ce5bSJoe Perches print $f $fixed_line . "\n"; 63963705ce5bSJoe Perches } 63973705ce5bSJoe Perches } 63983705ce5bSJoe Perches close($f); 63993705ce5bSJoe Perches 64003705ce5bSJoe Perches if (!$quiet) { 64013705ce5bSJoe Perches print << "EOM"; 6402d8469f16SJoe Perches 64033705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 64043705ce5bSJoe Perches 64053705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 64063705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 64073705ce5bSJoe Perches 64083705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 64093705ce5bSJoe PerchesNo warranties, expressed or implied... 64103705ce5bSJoe PerchesEOM 64113705ce5bSJoe Perches } 64123705ce5bSJoe Perches } 64133705ce5bSJoe Perches 6414d8469f16SJoe Perches if ($quiet == 0) { 6415d8469f16SJoe Perches print "\n"; 6416d8469f16SJoe Perches if ($clean == 1) { 6417d8469f16SJoe Perches print "$vname has no obvious style problems and is ready for submission.\n"; 6418d8469f16SJoe Perches } else { 6419d8469f16SJoe Perches print "$vname has style problems, please review.\n"; 64200a920b5bSAndy Whitcroft } 64210a920b5bSAndy Whitcroft } 64220a920b5bSAndy Whitcroft return $clean; 64230a920b5bSAndy Whitcroft} 6424