10a920b5bSAndy Whitcroft#!/usr/bin/perl -w 20a920b5bSAndy Whitcroft# (c) 2001, Dave Jones. <[email protected]> (the file handling bit) 300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 40a920b5bSAndy Whitcroft# (c) 2007, Andy Whitcroft <[email protected]> (new conditions, test suite, etc) 50a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2 60a920b5bSAndy Whitcroft 70a920b5bSAndy Whitcroftuse strict; 80a920b5bSAndy Whitcroft 90a920b5bSAndy Whitcroftmy $P = $0; 1000df344fSAndy Whitcroft$P =~ s@.*/@@g; 110a920b5bSAndy Whitcroft 12*c2fdda0dSAndy Whitcroftmy $V = '0.13'; 130a920b5bSAndy Whitcroft 140a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 150a920b5bSAndy Whitcroft 160a920b5bSAndy Whitcroftmy $quiet = 0; 170a920b5bSAndy Whitcroftmy $tree = 1; 180a920b5bSAndy Whitcroftmy $chk_signoff = 1; 190a920b5bSAndy Whitcroftmy $chk_patch = 1; 20653d4876SAndy Whitcroftmy $tst_type = 0; 216c72ffaaSAndy Whitcroftmy $emacs = 0; 228905a67cSAndy Whitcroftmy $terse = 0; 236c72ffaaSAndy Whitcroftmy $file = 0; 246c72ffaaSAndy Whitcroftmy $check = 0; 258905a67cSAndy Whitcroftmy $summary = 1; 268905a67cSAndy Whitcroftmy $mailback = 0; 276c72ffaaSAndy Whitcroftmy $root; 28*c2fdda0dSAndy Whitcroftmy %debug; 290a920b5bSAndy WhitcroftGetOptions( 306c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 310a920b5bSAndy Whitcroft 'tree!' => \$tree, 320a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 330a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 34653d4876SAndy Whitcroft 'test-type!' => \$tst_type, 356c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 368905a67cSAndy Whitcroft 'terse!' => \$terse, 376c72ffaaSAndy Whitcroft 'file!' => \$file, 386c72ffaaSAndy Whitcroft 'subjective!' => \$check, 396c72ffaaSAndy Whitcroft 'strict!' => \$check, 406c72ffaaSAndy Whitcroft 'root=s' => \$root, 418905a67cSAndy Whitcroft 'summary!' => \$summary, 428905a67cSAndy Whitcroft 'mailback!' => \$mailback, 43*c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 440a920b5bSAndy Whitcroft) or exit; 450a920b5bSAndy Whitcroft 460a920b5bSAndy Whitcroftmy $exit = 0; 470a920b5bSAndy Whitcroft 480a920b5bSAndy Whitcroftif ($#ARGV < 0) { 4900df344fSAndy Whitcroft print "usage: $P [options] patchfile\n"; 500a920b5bSAndy Whitcroft print "version: $V\n"; 510a920b5bSAndy Whitcroft print "options: -q => quiet\n"; 520a920b5bSAndy Whitcroft print " --no-tree => run without a kernel tree\n"; 538905a67cSAndy Whitcroft print " --terse => one line per report\n"; 546c72ffaaSAndy Whitcroft print " --emacs => emacs compile window format\n"; 556c72ffaaSAndy Whitcroft print " --file => check a source file\n"; 566c72ffaaSAndy Whitcroft print " --strict => enable more subjective tests\n"; 576c72ffaaSAndy Whitcroft print " --root => path to the kernel tree root\n"; 580a920b5bSAndy Whitcroft exit(1); 590a920b5bSAndy Whitcroft} 600a920b5bSAndy Whitcroft 61*c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 62*c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 63*c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 64*c2fdda0dSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';" 65*c2fdda0dSAndy Whitcroft} 66*c2fdda0dSAndy Whitcroft 678905a67cSAndy Whitcroftif ($terse) { 688905a67cSAndy Whitcroft $emacs = 1; 698905a67cSAndy Whitcroft $quiet++; 708905a67cSAndy Whitcroft} 718905a67cSAndy Whitcroft 726c72ffaaSAndy Whitcroftif ($tree) { 736c72ffaaSAndy Whitcroft if (defined $root) { 746c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 756c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 766c72ffaaSAndy Whitcroft } 776c72ffaaSAndy Whitcroft } else { 786c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 796c72ffaaSAndy Whitcroft $root = '.'; 806c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 816c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 826c72ffaaSAndy Whitcroft $root = $1; 836c72ffaaSAndy Whitcroft } 846c72ffaaSAndy Whitcroft } 856c72ffaaSAndy Whitcroft 866c72ffaaSAndy Whitcroft if (!defined $root) { 870a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 880a920b5bSAndy Whitcroft exit(2); 890a920b5bSAndy Whitcroft } 906c72ffaaSAndy Whitcroft} 916c72ffaaSAndy Whitcroft 926c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 936c72ffaaSAndy Whitcroft 946c72ffaaSAndy Whitcroftour $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; 956c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 966c72ffaaSAndy Whitcroftour $Sparse = qr{ 976c72ffaaSAndy Whitcroft __user| 986c72ffaaSAndy Whitcroft __kernel| 996c72ffaaSAndy Whitcroft __force| 1006c72ffaaSAndy Whitcroft __iomem| 1016c72ffaaSAndy Whitcroft __must_check| 1026c72ffaaSAndy Whitcroft __init_refok| 1036c72ffaaSAndy Whitcroft __kprobes| 1046c72ffaaSAndy Whitcroft fastcall 1056c72ffaaSAndy Whitcroft }x; 1066c72ffaaSAndy Whitcroftour $Attribute = qr{ 1076c72ffaaSAndy Whitcroft const| 1086c72ffaaSAndy Whitcroft __read_mostly| 1096c72ffaaSAndy Whitcroft __kprobes| 1106c72ffaaSAndy Whitcroft __(?:mem|cpu|dev|)(?:initdata|init) 1116c72ffaaSAndy Whitcroft }x; 1126c72ffaaSAndy Whitcroftour $Inline = qr{inline|__always_inline|noinline}; 1136c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 1146c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 1156c72ffaaSAndy Whitcroft 1166c72ffaaSAndy Whitcroftour $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; 1176c72ffaaSAndy Whitcroftour $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; 1186c72ffaaSAndy Whitcroftour $Operators = qr{ 1196c72ffaaSAndy Whitcroft <=|>=|==|!=| 1206c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 121*c2fdda0dSAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% 1226c72ffaaSAndy Whitcroft }x; 1236c72ffaaSAndy Whitcroft 1248905a67cSAndy Whitcroftour $NonptrType; 1258905a67cSAndy Whitcroftour $Type; 1268905a67cSAndy Whitcroftour $Declare; 1278905a67cSAndy Whitcroft 1288905a67cSAndy Whitcroftour @typeList = ( 1298905a67cSAndy Whitcroft qr{void}, 1308905a67cSAndy Whitcroft qr{char}, 1318905a67cSAndy Whitcroft qr{short}, 1328905a67cSAndy Whitcroft qr{int}, 1338905a67cSAndy Whitcroft qr{long}, 1348905a67cSAndy Whitcroft qr{unsigned}, 1358905a67cSAndy Whitcroft qr{float}, 1368905a67cSAndy Whitcroft qr{double}, 1378905a67cSAndy Whitcroft qr{bool}, 1388905a67cSAndy Whitcroft qr{long\s+int}, 1398905a67cSAndy Whitcroft qr{long\s+long}, 1408905a67cSAndy Whitcroft qr{long\s+long\s+int}, 1418905a67cSAndy Whitcroft qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)}, 1428905a67cSAndy Whitcroft qr{struct\s+$Ident}, 1438905a67cSAndy Whitcroft qr{union\s+$Ident}, 1448905a67cSAndy Whitcroft qr{enum\s+$Ident}, 1458905a67cSAndy Whitcroft qr{${Ident}_t}, 1468905a67cSAndy Whitcroft qr{${Ident}_handler}, 1478905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 1488905a67cSAndy Whitcroft); 1498905a67cSAndy Whitcroft 1508905a67cSAndy Whitcroftsub build_types { 1518905a67cSAndy Whitcroft my $all = "(?: \n" . join("|\n ", @typeList) . "\n)"; 1528905a67cSAndy Whitcroft $NonptrType = qr{ 1538905a67cSAndy Whitcroft \b 1548905a67cSAndy Whitcroft (?:const\s+)? 1558905a67cSAndy Whitcroft (?:unsigned\s+)? 1568905a67cSAndy Whitcroft $all 1578905a67cSAndy Whitcroft (?:\s+$Sparse|\s+const)* 1588905a67cSAndy Whitcroft \b 1598905a67cSAndy Whitcroft }x; 1608905a67cSAndy Whitcroft $Type = qr{ 1618905a67cSAndy Whitcroft \b$NonptrType\b 1628905a67cSAndy Whitcroft (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 163*c2fdda0dSAndy Whitcroft (?:\s+$Inline|\s+$Sparse|\s+$Attribute)* 1648905a67cSAndy Whitcroft }x; 1658905a67cSAndy Whitcroft $Declare = qr{(?:$Storage\s+)?$Type}; 1668905a67cSAndy Whitcroft} 1678905a67cSAndy Whitcroftbuild_types(); 1686c72ffaaSAndy Whitcroft 1696c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 1700a920b5bSAndy Whitcroft 1714a0df2efSAndy Whitcroftmy @dep_includes = (); 1724a0df2efSAndy Whitcroftmy @dep_functions = (); 1736c72ffaaSAndy Whitcroftmy $removal = "Documentation/feature-removal-schedule.txt"; 1746c72ffaaSAndy Whitcroftif ($tree && -f "$root/$removal") { 1756c72ffaaSAndy Whitcroft open(REMOVE, "<$root/$removal") || 1766c72ffaaSAndy Whitcroft die "$P: $removal: open failed - $!\n"; 1770a920b5bSAndy Whitcroft while (<REMOVE>) { 178f0a594c1SAndy Whitcroft if (/^Check:\s+(.*\S)/) { 179f0a594c1SAndy Whitcroft for my $entry (split(/[, ]+/, $1)) { 180f0a594c1SAndy Whitcroft if ($entry =~ m@include/(.*)@) { 1814a0df2efSAndy Whitcroft push(@dep_includes, $1); 1824a0df2efSAndy Whitcroft 183f0a594c1SAndy Whitcroft } elsif ($entry !~ m@/@) { 184f0a594c1SAndy Whitcroft push(@dep_functions, $entry); 185f0a594c1SAndy Whitcroft } 1864a0df2efSAndy Whitcroft } 1870a920b5bSAndy Whitcroft } 1880a920b5bSAndy Whitcroft } 1890a920b5bSAndy Whitcroft} 1900a920b5bSAndy Whitcroft 19100df344fSAndy Whitcroftmy @rawlines = (); 192*c2fdda0dSAndy Whitcroftmy @lines = (); 193*c2fdda0dSAndy Whitcroftmy $vname; 1946c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 1956c72ffaaSAndy Whitcroft if ($file) { 1966c72ffaaSAndy Whitcroft open(FILE, "diff -u /dev/null $filename|") || 1976c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 1986c72ffaaSAndy Whitcroft } else { 1996c72ffaaSAndy Whitcroft open(FILE, "<$filename") || 2006c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 2016c72ffaaSAndy Whitcroft } 202*c2fdda0dSAndy Whitcroft if ($filename eq '-') { 203*c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 204*c2fdda0dSAndy Whitcroft } else { 205*c2fdda0dSAndy Whitcroft $vname = $filename; 206*c2fdda0dSAndy Whitcroft } 2076c72ffaaSAndy Whitcroft while (<FILE>) { 2080a920b5bSAndy Whitcroft chomp; 20900df344fSAndy Whitcroft push(@rawlines, $_); 2106c72ffaaSAndy Whitcroft } 2116c72ffaaSAndy Whitcroft close(FILE); 212*c2fdda0dSAndy Whitcroft if (!process($filename)) { 2130a920b5bSAndy Whitcroft $exit = 1; 2140a920b5bSAndy Whitcroft } 21500df344fSAndy Whitcroft @rawlines = (); 2160a920b5bSAndy Whitcroft} 2170a920b5bSAndy Whitcroft 2180a920b5bSAndy Whitcroftexit($exit); 2190a920b5bSAndy Whitcroft 2200a920b5bSAndy Whitcroftsub top_of_kernel_tree { 2216c72ffaaSAndy Whitcroft my ($root) = @_; 2226c72ffaaSAndy Whitcroft 2236c72ffaaSAndy Whitcroft my @tree_check = ( 2246c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 2256c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 2266c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 2276c72ffaaSAndy Whitcroft ); 2286c72ffaaSAndy Whitcroft 2296c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 2306c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 2310a920b5bSAndy Whitcroft return 0; 2320a920b5bSAndy Whitcroft } 2336c72ffaaSAndy Whitcroft } 2346c72ffaaSAndy Whitcroft return 1; 2356c72ffaaSAndy Whitcroft} 2360a920b5bSAndy Whitcroft 2370a920b5bSAndy Whitcroftsub expand_tabs { 2380a920b5bSAndy Whitcroft my ($str) = @_; 2390a920b5bSAndy Whitcroft 2400a920b5bSAndy Whitcroft my $res = ''; 2410a920b5bSAndy Whitcroft my $n = 0; 2420a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 2430a920b5bSAndy Whitcroft if ($c eq "\t") { 2440a920b5bSAndy Whitcroft $res .= ' '; 2450a920b5bSAndy Whitcroft $n++; 2460a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 2470a920b5bSAndy Whitcroft $res .= ' '; 2480a920b5bSAndy Whitcroft } 2490a920b5bSAndy Whitcroft next; 2500a920b5bSAndy Whitcroft } 2510a920b5bSAndy Whitcroft $res .= $c; 2520a920b5bSAndy Whitcroft $n++; 2530a920b5bSAndy Whitcroft } 2540a920b5bSAndy Whitcroft 2550a920b5bSAndy Whitcroft return $res; 2560a920b5bSAndy Whitcroft} 2576c72ffaaSAndy Whitcroftsub copy_spacing { 2586c72ffaaSAndy Whitcroft my ($str) = @_; 2596c72ffaaSAndy Whitcroft 2606c72ffaaSAndy Whitcroft my $res = ''; 2616c72ffaaSAndy Whitcroft for my $c (split(//, $str)) { 2626c72ffaaSAndy Whitcroft if ($c eq "\t") { 2636c72ffaaSAndy Whitcroft $res .= $c; 2646c72ffaaSAndy Whitcroft } else { 2656c72ffaaSAndy Whitcroft $res .= ' '; 2666c72ffaaSAndy Whitcroft } 2676c72ffaaSAndy Whitcroft } 2686c72ffaaSAndy Whitcroft 2696c72ffaaSAndy Whitcroft return $res; 2706c72ffaaSAndy Whitcroft} 2710a920b5bSAndy Whitcroft 2724a0df2efSAndy Whitcroftsub line_stats { 2734a0df2efSAndy Whitcroft my ($line) = @_; 2744a0df2efSAndy Whitcroft 2754a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 2764a0df2efSAndy Whitcroft $line =~ s/^.//; 2774a0df2efSAndy Whitcroft $line = expand_tabs($line); 2784a0df2efSAndy Whitcroft 2794a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 2804a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 2814a0df2efSAndy Whitcroft 2824a0df2efSAndy Whitcroft return (length($line), length($white)); 2834a0df2efSAndy Whitcroft} 2844a0df2efSAndy Whitcroft 28500df344fSAndy Whitcroftsub sanitise_line { 28600df344fSAndy Whitcroft my ($line) = @_; 28700df344fSAndy Whitcroft 28800df344fSAndy Whitcroft my $res = ''; 28900df344fSAndy Whitcroft my $l = ''; 29000df344fSAndy Whitcroft 29100df344fSAndy Whitcroft my $quote = ''; 292*c2fdda0dSAndy Whitcroft my $qlen = 0; 29300df344fSAndy Whitcroft 29400df344fSAndy Whitcroft foreach my $c (split(//, $line)) { 295*c2fdda0dSAndy Whitcroft # The second backslash of a pair is not a "quote". 296*c2fdda0dSAndy Whitcroft if ($l eq "\\" && $c eq "\\") { 297*c2fdda0dSAndy Whitcroft $c = 'X'; 298*c2fdda0dSAndy Whitcroft } 29900df344fSAndy Whitcroft if ($l ne "\\" && ($c eq "'" || $c eq '"')) { 30000df344fSAndy Whitcroft if ($quote eq '') { 30100df344fSAndy Whitcroft $quote = $c; 30200df344fSAndy Whitcroft $res .= $c; 30300df344fSAndy Whitcroft $l = $c; 304*c2fdda0dSAndy Whitcroft $qlen = 0; 30500df344fSAndy Whitcroft next; 30600df344fSAndy Whitcroft } elsif ($quote eq $c) { 30700df344fSAndy Whitcroft $quote = ''; 30800df344fSAndy Whitcroft } 30900df344fSAndy Whitcroft } 310*c2fdda0dSAndy Whitcroft if ($quote eq "'" && $qlen > 1) { 311*c2fdda0dSAndy Whitcroft $quote = ''; 312*c2fdda0dSAndy Whitcroft } 31300df344fSAndy Whitcroft if ($quote && $c ne "\t") { 31400df344fSAndy Whitcroft $res .= "X"; 315*c2fdda0dSAndy Whitcroft $qlen++; 31600df344fSAndy Whitcroft } else { 31700df344fSAndy Whitcroft $res .= $c; 31800df344fSAndy Whitcroft } 31900df344fSAndy Whitcroft 32000df344fSAndy Whitcroft $l = $c; 32100df344fSAndy Whitcroft } 32200df344fSAndy Whitcroft 323*c2fdda0dSAndy Whitcroft # Clear out the comments. 324*c2fdda0dSAndy Whitcroft while ($res =~ m@(/\*.*?\*/)@) { 325*c2fdda0dSAndy Whitcroft substr($res, $-[1], $+[1] - $-[1]) = ' ' x ($+[1] - $-[1]); 326*c2fdda0dSAndy Whitcroft } 327*c2fdda0dSAndy Whitcroft if ($res =~ m@(/\*.*)@) { 328*c2fdda0dSAndy Whitcroft substr($res, $-[1], $+[1] - $-[1]) = ' ' x ($+[1] - $-[1]); 329*c2fdda0dSAndy Whitcroft } 330*c2fdda0dSAndy Whitcroft if ($res =~ m@^.(.*\*/)@) { 331*c2fdda0dSAndy Whitcroft substr($res, $-[1], $+[1] - $-[1]) = ' ' x ($+[1] - $-[1]); 332*c2fdda0dSAndy Whitcroft } 333*c2fdda0dSAndy Whitcroft 334*c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 335*c2fdda0dSAndy Whitcroft if ($res =~ /^.#\s*include\s+\<(.*)\>/) { 336*c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 337*c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 338*c2fdda0dSAndy Whitcroft 339*c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 340*c2fdda0dSAndy Whitcroft } elsif ($res =~ /^.#\s*(?:error|warning)\s+(.*)\b/) { 341*c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 342*c2fdda0dSAndy Whitcroft $res =~ s@(#\s*(?:error|warning)\s+).*@$1$clean@; 343*c2fdda0dSAndy Whitcroft } 344*c2fdda0dSAndy Whitcroft 34500df344fSAndy Whitcroft return $res; 34600df344fSAndy Whitcroft} 34700df344fSAndy Whitcroft 3488905a67cSAndy Whitcroftsub ctx_statement_block { 3498905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 3508905a67cSAndy Whitcroft my $line = $linenr - 1; 3518905a67cSAndy Whitcroft my $blk = ''; 3528905a67cSAndy Whitcroft my $soff = $off; 3538905a67cSAndy Whitcroft my $coff = $off - 1; 3548905a67cSAndy Whitcroft 3558905a67cSAndy Whitcroft my $type = ''; 3568905a67cSAndy Whitcroft my $level = 0; 3578905a67cSAndy Whitcroft my $c; 3588905a67cSAndy Whitcroft my $len = 0; 3598905a67cSAndy Whitcroft while (1) { 3608905a67cSAndy Whitcroft #warn "CSB: blk<$blk>\n"; 3618905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 3628905a67cSAndy Whitcroft # context. 3638905a67cSAndy Whitcroft if ($off >= $len) { 3648905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 365*c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 3668905a67cSAndy Whitcroft $remain--; 367*c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 3688905a67cSAndy Whitcroft $len = length($blk); 3698905a67cSAndy Whitcroft $line++; 3708905a67cSAndy Whitcroft last; 3718905a67cSAndy Whitcroft } 3728905a67cSAndy Whitcroft # Bail if there is no further context. 3738905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 3748905a67cSAndy Whitcroft if ($off == $len) { 3758905a67cSAndy Whitcroft last; 3768905a67cSAndy Whitcroft } 3778905a67cSAndy Whitcroft } 3788905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 3798905a67cSAndy Whitcroft 3808905a67cSAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level>\n"; 3818905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 3828905a67cSAndy Whitcroft # outermost level. 3838905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 3848905a67cSAndy Whitcroft last; 3858905a67cSAndy Whitcroft } 3868905a67cSAndy Whitcroft 3878905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 3888905a67cSAndy Whitcroft $level++; 3898905a67cSAndy Whitcroft $type = '('; 3908905a67cSAndy Whitcroft } 3918905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 3928905a67cSAndy Whitcroft $level--; 3938905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 3948905a67cSAndy Whitcroft 3958905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 3968905a67cSAndy Whitcroft $coff = $off; 3978905a67cSAndy Whitcroft } 3988905a67cSAndy Whitcroft } 3998905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 4008905a67cSAndy Whitcroft $level++; 4018905a67cSAndy Whitcroft $type = '{'; 4028905a67cSAndy Whitcroft } 4038905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 4048905a67cSAndy Whitcroft $level--; 4058905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 4068905a67cSAndy Whitcroft 4078905a67cSAndy Whitcroft if ($level == 0) { 4088905a67cSAndy Whitcroft last; 4098905a67cSAndy Whitcroft } 4108905a67cSAndy Whitcroft } 4118905a67cSAndy Whitcroft $off++; 4128905a67cSAndy Whitcroft } 4138905a67cSAndy Whitcroft 4148905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 4158905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 4168905a67cSAndy Whitcroft 4178905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 4188905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 4198905a67cSAndy Whitcroft 4208905a67cSAndy Whitcroft return ($statement, $condition); 4218905a67cSAndy Whitcroft} 4228905a67cSAndy Whitcroft 4234a0df2efSAndy Whitcroftsub ctx_block_get { 424f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 4254a0df2efSAndy Whitcroft my $line; 4264a0df2efSAndy Whitcroft my $start = $linenr - 1; 4274a0df2efSAndy Whitcroft my $blk = ''; 4284a0df2efSAndy Whitcroft my @o; 4294a0df2efSAndy Whitcroft my @c; 4304a0df2efSAndy Whitcroft my @res = (); 4314a0df2efSAndy Whitcroft 432f0a594c1SAndy Whitcroft my $level = 0; 43300df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 43400df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 43500df344fSAndy Whitcroft $remain--; 43600df344fSAndy Whitcroft 43700df344fSAndy Whitcroft $blk .= $rawlines[$line]; 438f0a594c1SAndy Whitcroft foreach my $c (split(//, $rawlines[$line])) { 439f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 440f0a594c1SAndy Whitcroft if ($off > 0) { 441f0a594c1SAndy Whitcroft $off--; 442f0a594c1SAndy Whitcroft next; 443f0a594c1SAndy Whitcroft } 4444a0df2efSAndy Whitcroft 445f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 446f0a594c1SAndy Whitcroft $level--; 447f0a594c1SAndy Whitcroft last if ($level == 0); 448f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 449f0a594c1SAndy Whitcroft $level++; 450f0a594c1SAndy Whitcroft } 451f0a594c1SAndy Whitcroft } 4524a0df2efSAndy Whitcroft 453f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 45400df344fSAndy Whitcroft push(@res, $rawlines[$line]); 4554a0df2efSAndy Whitcroft } 4564a0df2efSAndy Whitcroft 457f0a594c1SAndy Whitcroft last if ($level == 0); 4584a0df2efSAndy Whitcroft } 4594a0df2efSAndy Whitcroft 460f0a594c1SAndy Whitcroft return ($level, @res); 4614a0df2efSAndy Whitcroft} 4624a0df2efSAndy Whitcroftsub ctx_block_outer { 4634a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 4644a0df2efSAndy Whitcroft 465f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 466f0a594c1SAndy Whitcroft return @r; 4674a0df2efSAndy Whitcroft} 4684a0df2efSAndy Whitcroftsub ctx_block { 4694a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 4704a0df2efSAndy Whitcroft 471f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 472f0a594c1SAndy Whitcroft return @r; 473653d4876SAndy Whitcroft} 474653d4876SAndy Whitcroftsub ctx_statement { 475f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 476f0a594c1SAndy Whitcroft 477f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 478f0a594c1SAndy Whitcroft return @r; 479f0a594c1SAndy Whitcroft} 480f0a594c1SAndy Whitcroftsub ctx_block_level { 481653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 482653d4876SAndy Whitcroft 483f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 4844a0df2efSAndy Whitcroft} 4859c0ca6f9SAndy Whitcroftsub ctx_statement_level { 4869c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 4879c0ca6f9SAndy Whitcroft 4889c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 4899c0ca6f9SAndy Whitcroft} 4904a0df2efSAndy Whitcroft 4914a0df2efSAndy Whitcroftsub ctx_locate_comment { 4924a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 4934a0df2efSAndy Whitcroft 4944a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 49500df344fSAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@); 4964a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 4974a0df2efSAndy Whitcroft 4984a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 4994a0df2efSAndy Whitcroft # comment. 5004a0df2efSAndy Whitcroft my $in_comment = 0; 5014a0df2efSAndy Whitcroft $current_comment = ''; 5024a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 50300df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 50400df344fSAndy Whitcroft #warn " $line\n"; 5054a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 5064a0df2efSAndy Whitcroft $in_comment = 1; 5074a0df2efSAndy Whitcroft } 5084a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 5094a0df2efSAndy Whitcroft $in_comment = 1; 5104a0df2efSAndy Whitcroft } 5114a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 5124a0df2efSAndy Whitcroft $current_comment = ''; 5134a0df2efSAndy Whitcroft } 5144a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 5154a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 5164a0df2efSAndy Whitcroft $in_comment = 0; 5174a0df2efSAndy Whitcroft } 5184a0df2efSAndy Whitcroft } 5194a0df2efSAndy Whitcroft 5204a0df2efSAndy Whitcroft chomp($current_comment); 5214a0df2efSAndy Whitcroft return($current_comment); 5224a0df2efSAndy Whitcroft} 5234a0df2efSAndy Whitcroftsub ctx_has_comment { 5244a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 5254a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 5264a0df2efSAndy Whitcroft 52700df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 5284a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 5294a0df2efSAndy Whitcroft 5304a0df2efSAndy Whitcroft return ($cmt ne ''); 5314a0df2efSAndy Whitcroft} 5324a0df2efSAndy Whitcroft 5330a920b5bSAndy Whitcroftsub cat_vet { 5340a920b5bSAndy Whitcroft my ($vet) = @_; 5359c0ca6f9SAndy Whitcroft my ($res, $coded); 5360a920b5bSAndy Whitcroft 5379c0ca6f9SAndy Whitcroft $res = ''; 5386c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 5396c72ffaaSAndy Whitcroft $res .= $1; 5406c72ffaaSAndy Whitcroft if ($2 ne '') { 5419c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 5426c72ffaaSAndy Whitcroft $res .= $coded; 5436c72ffaaSAndy Whitcroft } 5449c0ca6f9SAndy Whitcroft } 5459c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 5460a920b5bSAndy Whitcroft 5479c0ca6f9SAndy Whitcroft return $res; 5480a920b5bSAndy Whitcroft} 5490a920b5bSAndy Whitcroft 550*c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 551*c2fdda0dSAndy Whitcroftmy $av_paren = 0; 552*c2fdda0dSAndy Whitcroftmy @av_paren_type; 553*c2fdda0dSAndy Whitcroft 554*c2fdda0dSAndy Whitcroftsub annotate_reset { 555*c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 556*c2fdda0dSAndy Whitcroft $av_paren = 0; 557*c2fdda0dSAndy Whitcroft @av_paren_type = (); 558*c2fdda0dSAndy Whitcroft} 559*c2fdda0dSAndy Whitcroft 5606c72ffaaSAndy Whitcroftsub annotate_values { 5616c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 5626c72ffaaSAndy Whitcroft 5636c72ffaaSAndy Whitcroft my $res; 5646c72ffaaSAndy Whitcroft my $cur = $stream; 5656c72ffaaSAndy Whitcroft 566*c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 5676c72ffaaSAndy Whitcroft 5686c72ffaaSAndy Whitcroft while (length($cur)) { 569*c2fdda0dSAndy Whitcroft print " <$type> " if ($dbg_values > 1); 5706c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 571*c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 572*c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 573*c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 5746c72ffaaSAndy Whitcroft $type = 'N'; 5756c72ffaaSAndy Whitcroft } 5766c72ffaaSAndy Whitcroft 5778905a67cSAndy Whitcroft } elsif ($cur =~ /^($Type)/) { 578*c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 5796c72ffaaSAndy Whitcroft $type = 'T'; 5806c72ffaaSAndy Whitcroft 5816c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { 582*c2fdda0dSAndy Whitcroft print "DEFINE($1)\n" if ($dbg_values > 1); 583*c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 584*c2fdda0dSAndy Whitcroft $av_paren_type[$av_paren] = 'N'; 5856c72ffaaSAndy Whitcroft 586*c2fdda0dSAndy Whitcroft } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) { 587*c2fdda0dSAndy Whitcroft print "PRE($1)\n" if ($dbg_values > 1); 588*c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 5896c72ffaaSAndy Whitcroft $type = 'N'; 5906c72ffaaSAndy Whitcroft 5916c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 592*c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 5936c72ffaaSAndy Whitcroft 5946c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 595*c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 5966c72ffaaSAndy Whitcroft if (defined $2) { 597*c2fdda0dSAndy Whitcroft $av_paren_type[$av_paren] = 'V'; 5986c72ffaaSAndy Whitcroft } 5996c72ffaaSAndy Whitcroft $type = 'N'; 6006c72ffaaSAndy Whitcroft 6018905a67cSAndy Whitcroft } elsif ($cur =~ /^(if|while|typeof|for)\b/o) { 602*c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 603*c2fdda0dSAndy Whitcroft $av_paren_type[$av_paren] = 'N'; 6046c72ffaaSAndy Whitcroft $type = 'N'; 6056c72ffaaSAndy Whitcroft 6066c72ffaaSAndy Whitcroft } elsif ($cur =~/^(return|case|else)/o) { 607*c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 6086c72ffaaSAndy Whitcroft $type = 'N'; 6096c72ffaaSAndy Whitcroft 6106c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 611*c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 612*c2fdda0dSAndy Whitcroft $av_paren++; 6136c72ffaaSAndy Whitcroft $type = 'N'; 6146c72ffaaSAndy Whitcroft 6156c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 616*c2fdda0dSAndy Whitcroft $av_paren-- if ($av_paren > 0); 617*c2fdda0dSAndy Whitcroft if (defined $av_paren_type[$av_paren]) { 618*c2fdda0dSAndy Whitcroft $type = $av_paren_type[$av_paren]; 619*c2fdda0dSAndy Whitcroft undef $av_paren_type[$av_paren]; 620*c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 621*c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 6226c72ffaaSAndy Whitcroft } else { 623*c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 6246c72ffaaSAndy Whitcroft } 6256c72ffaaSAndy Whitcroft 6266c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident)\(/o) { 627*c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 628*c2fdda0dSAndy Whitcroft $av_paren_type[$av_paren] = 'V'; 6296c72ffaaSAndy Whitcroft 6306c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 631*c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 6326c72ffaaSAndy Whitcroft $type = 'V'; 6336c72ffaaSAndy Whitcroft 6346c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 635*c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 6366c72ffaaSAndy Whitcroft $type = 'N'; 6376c72ffaaSAndy Whitcroft 6386c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { 639*c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 6406c72ffaaSAndy Whitcroft $type = 'N'; 6416c72ffaaSAndy Whitcroft 6426c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 643*c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 6446c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 6456c72ffaaSAndy Whitcroft $type = 'N'; 6466c72ffaaSAndy Whitcroft } 6476c72ffaaSAndy Whitcroft 6486c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 649*c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 6506c72ffaaSAndy Whitcroft } 6516c72ffaaSAndy Whitcroft if (defined $1) { 6526c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 6536c72ffaaSAndy Whitcroft $res .= $type x length($1); 6546c72ffaaSAndy Whitcroft } 6556c72ffaaSAndy Whitcroft } 6566c72ffaaSAndy Whitcroft 6576c72ffaaSAndy Whitcroft return $res; 6586c72ffaaSAndy Whitcroft} 6596c72ffaaSAndy Whitcroft 6608905a67cSAndy Whitcroftsub possible { 6618905a67cSAndy Whitcroft my ($possible) = @_; 6628905a67cSAndy Whitcroft 6638905a67cSAndy Whitcroft #print "CHECK<$possible>\n"; 6648905a67cSAndy Whitcroft if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && 6658905a67cSAndy Whitcroft $possible ne 'goto' && $possible ne 'return' && 6668905a67cSAndy Whitcroft $possible ne 'struct' && $possible ne 'enum' && 6678905a67cSAndy Whitcroft $possible ne 'case' && $possible ne 'else' && 6688905a67cSAndy Whitcroft $possible ne 'typedef') { 669*c2fdda0dSAndy Whitcroft warn "POSSIBLE: $possible\n" if ($dbg_possible); 6708905a67cSAndy Whitcroft push(@typeList, $possible); 6718905a67cSAndy Whitcroft build_types(); 6728905a67cSAndy Whitcroft } 6738905a67cSAndy Whitcroft} 6748905a67cSAndy Whitcroft 6756c72ffaaSAndy Whitcroftmy $prefix = ''; 6766c72ffaaSAndy Whitcroft 677f0a594c1SAndy Whitcroftmy @report = (); 678f0a594c1SAndy Whitcroftsub report { 6798905a67cSAndy Whitcroft my $line = $prefix . $_[0]; 6808905a67cSAndy Whitcroft 6818905a67cSAndy Whitcroft $line = (split('\n', $line))[0] . "\n" if ($terse); 6828905a67cSAndy Whitcroft 6838905a67cSAndy Whitcroft push(@report, $line); 684f0a594c1SAndy Whitcroft} 685f0a594c1SAndy Whitcroftsub report_dump { 686f0a594c1SAndy Whitcroft @report; 687f0a594c1SAndy Whitcroft} 688de7d4f0eSAndy Whitcroftsub ERROR { 689f0a594c1SAndy Whitcroft report("ERROR: $_[0]\n"); 690de7d4f0eSAndy Whitcroft our $clean = 0; 6916c72ffaaSAndy Whitcroft our $cnt_error++; 692de7d4f0eSAndy Whitcroft} 693de7d4f0eSAndy Whitcroftsub WARN { 694f0a594c1SAndy Whitcroft report("WARNING: $_[0]\n"); 695de7d4f0eSAndy Whitcroft our $clean = 0; 6966c72ffaaSAndy Whitcroft our $cnt_warn++; 697de7d4f0eSAndy Whitcroft} 698de7d4f0eSAndy Whitcroftsub CHK { 6996c72ffaaSAndy Whitcroft if ($check) { 700f0a594c1SAndy Whitcroft report("CHECK: $_[0]\n"); 701de7d4f0eSAndy Whitcroft our $clean = 0; 7026c72ffaaSAndy Whitcroft our $cnt_chk++; 7036c72ffaaSAndy Whitcroft } 704de7d4f0eSAndy Whitcroft} 705de7d4f0eSAndy Whitcroft 7060a920b5bSAndy Whitcroftsub process { 7070a920b5bSAndy Whitcroft my $filename = shift; 7080a920b5bSAndy Whitcroft 7090a920b5bSAndy Whitcroft my $linenr=0; 7100a920b5bSAndy Whitcroft my $prevline=""; 711*c2fdda0dSAndy Whitcroft my $prevrawline=""; 7120a920b5bSAndy Whitcroft my $stashline=""; 713*c2fdda0dSAndy Whitcroft my $stashrawline=""; 7140a920b5bSAndy Whitcroft 7154a0df2efSAndy Whitcroft my $length; 7160a920b5bSAndy Whitcroft my $indent; 7170a920b5bSAndy Whitcroft my $previndent=0; 7180a920b5bSAndy Whitcroft my $stashindent=0; 7190a920b5bSAndy Whitcroft 720de7d4f0eSAndy Whitcroft our $clean = 1; 7210a920b5bSAndy Whitcroft my $signoff = 0; 7220a920b5bSAndy Whitcroft my $is_patch = 0; 7230a920b5bSAndy Whitcroft 7246c72ffaaSAndy Whitcroft our $cnt_lines = 0; 7256c72ffaaSAndy Whitcroft our $cnt_error = 0; 7266c72ffaaSAndy Whitcroft our $cnt_warn = 0; 7276c72ffaaSAndy Whitcroft our $cnt_chk = 0; 7286c72ffaaSAndy Whitcroft 7290a920b5bSAndy Whitcroft # Trace the real file/line as we go. 7300a920b5bSAndy Whitcroft my $realfile = ''; 7310a920b5bSAndy Whitcroft my $realline = 0; 7320a920b5bSAndy Whitcroft my $realcnt = 0; 7330a920b5bSAndy Whitcroft my $here = ''; 7340a920b5bSAndy Whitcroft my $in_comment = 0; 735*c2fdda0dSAndy Whitcroft my $comment_edge = 0; 7360a920b5bSAndy Whitcroft my $first_line = 0; 7370a920b5bSAndy Whitcroft 7386c72ffaaSAndy Whitcroft my $prev_values = 'N'; 739653d4876SAndy Whitcroft 740*c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 741de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 742*c2fdda0dSAndy Whitcroft # 743de7d4f0eSAndy Whitcroft my @setup_docs = (); 744de7d4f0eSAndy Whitcroft my $setup_docs = 0; 745*c2fdda0dSAndy Whitcroft my $line; 746*c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 747*c2fdda0dSAndy Whitcroft # Standardise the strings and chars within the input to 748*c2fdda0dSAndy Whitcroft # simplify matching. 749*c2fdda0dSAndy Whitcroft $line = sanitise_line($rawline); 750*c2fdda0dSAndy Whitcroft push(@lines, $line); 751*c2fdda0dSAndy Whitcroft 752*c2fdda0dSAndy Whitcroft ##print "==>$rawline\n"; 753*c2fdda0dSAndy Whitcroft ##print "-->$line\n"; 754*c2fdda0dSAndy Whitcroft 755de7d4f0eSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 756de7d4f0eSAndy Whitcroft $setup_docs = 0; 757de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 758de7d4f0eSAndy Whitcroft $setup_docs = 1; 759de7d4f0eSAndy Whitcroft } 760de7d4f0eSAndy Whitcroft next; 761de7d4f0eSAndy Whitcroft } 762de7d4f0eSAndy Whitcroft 763de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 764de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 765de7d4f0eSAndy Whitcroft } 766de7d4f0eSAndy Whitcroft } 767de7d4f0eSAndy Whitcroft 7686c72ffaaSAndy Whitcroft $prefix = ''; 7696c72ffaaSAndy Whitcroft 7700a920b5bSAndy Whitcroft foreach my $line (@lines) { 7710a920b5bSAndy Whitcroft $linenr++; 7720a920b5bSAndy Whitcroft 773*c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 7746c72ffaaSAndy Whitcroft 7750a920b5bSAndy Whitcroft#extract the filename as it passes 7760a920b5bSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 7770a920b5bSAndy Whitcroft $realfile=$1; 77800df344fSAndy Whitcroft $realfile =~ s@^[^/]*/@@; 7790a920b5bSAndy Whitcroft $in_comment = 0; 7800a920b5bSAndy Whitcroft next; 7810a920b5bSAndy Whitcroft } 7820a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 7836c72ffaaSAndy Whitcroft if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 7840a920b5bSAndy Whitcroft $is_patch = 1; 7854a0df2efSAndy Whitcroft $first_line = $linenr + 1; 7860a920b5bSAndy Whitcroft $in_comment = 0; 7870a920b5bSAndy Whitcroft $realline=$1-1; 7880a920b5bSAndy Whitcroft if (defined $2) { 7890a920b5bSAndy Whitcroft $realcnt=$3+1; 7900a920b5bSAndy Whitcroft } else { 7910a920b5bSAndy Whitcroft $realcnt=1+1; 7920a920b5bSAndy Whitcroft } 793*c2fdda0dSAndy Whitcroft annotate_reset(); 7946c72ffaaSAndy Whitcroft $prev_values = 'N'; 7950a920b5bSAndy Whitcroft next; 7960a920b5bSAndy Whitcroft } 7970a920b5bSAndy Whitcroft 7984a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 7994a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 8004a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 8014a0df2efSAndy Whitcroft if ($line =~ /^( |\+|$)/) { 8020a920b5bSAndy Whitcroft $realline++; 803d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 8040a920b5bSAndy Whitcroft 8058905a67cSAndy Whitcroft # Guestimate if this is a continuing comment. Run 8068905a67cSAndy Whitcroft # the context looking for a comment "edge". If this 8078905a67cSAndy Whitcroft # edge is a close comment then we must be in a comment 8088905a67cSAndy Whitcroft # at context start. 8098905a67cSAndy Whitcroft if ($linenr == $first_line) { 8108905a67cSAndy Whitcroft my $edge; 8118905a67cSAndy Whitcroft for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) { 812*c2fdda0dSAndy Whitcroft ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@); 8138905a67cSAndy Whitcroft last if (defined $edge); 8148905a67cSAndy Whitcroft } 8158905a67cSAndy Whitcroft if (defined $edge && $edge eq '*/') { 8168905a67cSAndy Whitcroft $in_comment = 1; 8178905a67cSAndy Whitcroft } 8188905a67cSAndy Whitcroft } 8198905a67cSAndy Whitcroft 8200a920b5bSAndy Whitcroft # Guestimate if this is a continuing comment. If this 8210a920b5bSAndy Whitcroft # is the start of a diff block and this line starts 8220a920b5bSAndy Whitcroft # ' *' then it is very likely a comment. 823*c2fdda0dSAndy Whitcroft if ($linenr == $first_line and $rawline =~ m@^.\s* \*(?:\s|$)@) { 8240a920b5bSAndy Whitcroft $in_comment = 1; 8250a920b5bSAndy Whitcroft } 8268905a67cSAndy Whitcroft 8278905a67cSAndy Whitcroft # Find the last comment edge on _this_ line. 828*c2fdda0dSAndy Whitcroft $comment_edge = 0; 829*c2fdda0dSAndy Whitcroft while (($rawline =~ m@(/\*|\*/)@g)) { 8308905a67cSAndy Whitcroft if ($1 eq '/*') { 8310a920b5bSAndy Whitcroft $in_comment = 1; 8328905a67cSAndy Whitcroft } else { 8330a920b5bSAndy Whitcroft $in_comment = 0; 8340a920b5bSAndy Whitcroft } 835*c2fdda0dSAndy Whitcroft $comment_edge = 1; 8368905a67cSAndy Whitcroft } 8370a920b5bSAndy Whitcroft 8384a0df2efSAndy Whitcroft # Measure the line length and indent. 839*c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 8400a920b5bSAndy Whitcroft 8410a920b5bSAndy Whitcroft # Track the previous line. 8420a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 8430a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 844*c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 845*c2fdda0dSAndy Whitcroft 846*c2fdda0dSAndy Whitcroft #warn "ic<$in_comment> ce<$comment_edge> line<$line>\n"; 8476c72ffaaSAndy Whitcroft 848d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 849d8aaf121SAndy Whitcroft $realcnt--; 8500a920b5bSAndy Whitcroft } 8510a920b5bSAndy Whitcroft 8520a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 8536c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 8546c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 855389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 8560a920b5bSAndy Whitcroft 857*c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 858*c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 859*c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 8600a920b5bSAndy Whitcroft 8616c72ffaaSAndy Whitcroft $prefix = "$filename:$realline: " if ($emacs && $file); 8626c72ffaaSAndy Whitcroft $prefix = "$filename:$linenr: " if ($emacs && !$file); 8636c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 8646c72ffaaSAndy Whitcroft 8650a920b5bSAndy Whitcroft#check the patch for a signoff: 866d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 8674a0df2efSAndy Whitcroft # This is a signoff, if ugly, so do not double report. 8684a0df2efSAndy Whitcroft $signoff++; 8690a920b5bSAndy Whitcroft if (!($line =~ /^\s*Signed-off-by:/)) { 870de7d4f0eSAndy Whitcroft WARN("Signed-off-by: is the preferred form\n" . 871de7d4f0eSAndy Whitcroft $herecurr); 8720a920b5bSAndy Whitcroft } 8730a920b5bSAndy Whitcroft if ($line =~ /^\s*signed-off-by:\S/i) { 874de7d4f0eSAndy Whitcroft WARN("need space after Signed-off-by:\n" . 875de7d4f0eSAndy Whitcroft $herecurr); 8760a920b5bSAndy Whitcroft } 8770a920b5bSAndy Whitcroft } 8780a920b5bSAndy Whitcroft 87900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 8808905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 881de7d4f0eSAndy Whitcroft ERROR("patch seems to be corrupt (line wrapped?)\n" . 8826c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 883de7d4f0eSAndy Whitcroft } 884de7d4f0eSAndy Whitcroft 885de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 886de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 887*c2fdda0dSAndy Whitcroft !($rawline =~ m/^( 888de7d4f0eSAndy Whitcroft [\x09\x0A\x0D\x20-\x7E] # ASCII 889de7d4f0eSAndy Whitcroft | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 890de7d4f0eSAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 891de7d4f0eSAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 892de7d4f0eSAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 893de7d4f0eSAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 894de7d4f0eSAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 895de7d4f0eSAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 896de7d4f0eSAndy Whitcroft )*$/x )) { 897*c2fdda0dSAndy Whitcroft ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $herecurr); 89800df344fSAndy Whitcroft } 8990a920b5bSAndy Whitcroft 90000df344fSAndy Whitcroft#ignore lines being removed 90100df344fSAndy Whitcroft if ($line=~/^-/) {next;} 90200df344fSAndy Whitcroft 90300df344fSAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 90400df344fSAndy Whitcroft next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 9050a920b5bSAndy Whitcroft 9060a920b5bSAndy Whitcroft#trailing whitespace 9079c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 908*c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 9099c0ca6f9SAndy Whitcroft ERROR("DOS line endings\n" . $herevet); 9109c0ca6f9SAndy Whitcroft 911*c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 912*c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 913de7d4f0eSAndy Whitcroft ERROR("trailing whitespace\n" . $herevet); 9140a920b5bSAndy Whitcroft } 9150a920b5bSAndy Whitcroft#80 column limit 916*c2fdda0dSAndy Whitcroft if ($line =~ /^\+/ && !($prevrawline=~/\/\*\*/) && $length > 80) { 917de7d4f0eSAndy Whitcroft WARN("line over 80 characters\n" . $herecurr); 9180a920b5bSAndy Whitcroft } 9190a920b5bSAndy Whitcroft 9208905a67cSAndy Whitcroft# check for adding lines without a newline. 9218905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 9228905a67cSAndy Whitcroft WARN("adding a line without newline at end of file\n" . $herecurr); 9238905a67cSAndy Whitcroft } 9248905a67cSAndy Whitcroft 9250a920b5bSAndy Whitcroft# check we are in a valid source file *.[hc] if not then ignore this hunk 9260a920b5bSAndy Whitcroft next if ($realfile !~ /\.[hc]$/); 9270a920b5bSAndy Whitcroft 9280a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 9290a920b5bSAndy Whitcroft# more than 8 must use tabs. 930*c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 931*c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 932*c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 933de7d4f0eSAndy Whitcroft ERROR("use tabs not spaces\n" . $herevet); 9340a920b5bSAndy Whitcroft } 9350a920b5bSAndy Whitcroft 936*c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 937*c2fdda0dSAndy Whitcroft if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) { 938*c2fdda0dSAndy Whitcroft WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 939*c2fdda0dSAndy Whitcroft } 94022f2a2efSAndy Whitcroft 94122f2a2efSAndy Whitcroft# The rest of our checks refer specifically to C style 94222f2a2efSAndy Whitcroft# only apply those _outside_ comments. Only skip 94322f2a2efSAndy Whitcroft# lines in the middle of comments. 94422f2a2efSAndy Whitcroft next if (!$comment_edge && $in_comment); 94500df344fSAndy Whitcroft 9469c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 947*c2fdda0dSAndy Whitcroft if ($realcnt) { 948*c2fdda0dSAndy Whitcroft # Ignore goto labels. 949*c2fdda0dSAndy Whitcroft if ($line =~ /$Ident:\*$/) { 950*c2fdda0dSAndy Whitcroft 951*c2fdda0dSAndy Whitcroft # Ignore functions being called 952*c2fdda0dSAndy Whitcroft } elsif ($line =~ /^.\s*$Ident\s*\(/) { 953*c2fdda0dSAndy Whitcroft 9546c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 955*c2fdda0dSAndy Whitcroft } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { 9568905a67cSAndy Whitcroft possible($1); 9578905a67cSAndy Whitcroft 9586c72ffaaSAndy Whitcroft # declarations always start with types 959*c2fdda0dSAndy Whitcroft } elsif ($prev_values eq 'N' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=)/) { 9608905a67cSAndy Whitcroft possible($1); 961*c2fdda0dSAndy Whitcroft } 9628905a67cSAndy Whitcroft 9636c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 964*c2fdda0dSAndy Whitcroft while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { 9658905a67cSAndy Whitcroft possible($1); 9669c0ca6f9SAndy Whitcroft } 9678905a67cSAndy Whitcroft 9688905a67cSAndy Whitcroft # Check for any sort of function declaration. 9698905a67cSAndy Whitcroft # int foo(something bar, other baz); 9708905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 971*c2fdda0dSAndy Whitcroft if ($prev_values eq 'N' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { 9728905a67cSAndy Whitcroft my ($name_len) = length($1); 9738905a67cSAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len); 9748905a67cSAndy Whitcroft my $ctx = join("\n", @ctx); 9758905a67cSAndy Whitcroft 9768905a67cSAndy Whitcroft $ctx =~ s/\n.//; 9778905a67cSAndy Whitcroft substr($ctx, 0, $name_len + 1) = ''; 9788905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 9798905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 9808905a67cSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { 9818905a67cSAndy Whitcroft 9828905a67cSAndy Whitcroft possible($1); 9838905a67cSAndy Whitcroft } 9848905a67cSAndy Whitcroft } 9858905a67cSAndy Whitcroft } 9868905a67cSAndy Whitcroft 9879c0ca6f9SAndy Whitcroft } 9889c0ca6f9SAndy Whitcroft 98900df344fSAndy Whitcroft# 99000df344fSAndy Whitcroft# Checks which may be anchored in the context. 99100df344fSAndy Whitcroft# 99200df344fSAndy Whitcroft 99300df344fSAndy Whitcroft# Check for switch () and associated case and default 99400df344fSAndy Whitcroft# statements should be at the same indent. 99500df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 99600df344fSAndy Whitcroft my $err = ''; 99700df344fSAndy Whitcroft my $sep = ''; 99800df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 99900df344fSAndy Whitcroft shift(@ctx); 100000df344fSAndy Whitcroft for my $ctx (@ctx) { 100100df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 100200df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 100300df344fSAndy Whitcroft $indent != $cindent) { 100400df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 100500df344fSAndy Whitcroft $sep = ''; 100600df344fSAndy Whitcroft } else { 100700df344fSAndy Whitcroft $sep = "[...]\n"; 100800df344fSAndy Whitcroft } 100900df344fSAndy Whitcroft } 101000df344fSAndy Whitcroft if ($err ne '') { 10119c0ca6f9SAndy Whitcroft ERROR("switch and case should be at the same indent\n$hereline$err"); 1012de7d4f0eSAndy Whitcroft } 1013de7d4f0eSAndy Whitcroft } 1014de7d4f0eSAndy Whitcroft 1015de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 1016de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 1017de7d4f0eSAndy Whitcroft if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { 10189c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 1019de7d4f0eSAndy Whitcroft my $ctx_ln = $linenr + $#ctx + 1; 1020de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 1021de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 1022de7d4f0eSAndy Whitcroft 10239c0ca6f9SAndy Whitcroft # Skip over any removed lines in the context following statement. 1024de7d4f0eSAndy Whitcroft while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) { 1025de7d4f0eSAndy Whitcroft $ctx_ln++; 1026de7d4f0eSAndy Whitcroft $ctx_cnt--; 1027de7d4f0eSAndy Whitcroft } 1028de7d4f0eSAndy Whitcroft ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>"; 1029de7d4f0eSAndy Whitcroft 1030de7d4f0eSAndy Whitcroft if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 1031f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . 1032de7d4f0eSAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 103300df344fSAndy Whitcroft } 10349c0ca6f9SAndy Whitcroft if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) { 10359c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 10369c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 10379c0ca6f9SAndy Whitcroft WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" . 10389c0ca6f9SAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 10399c0ca6f9SAndy Whitcroft } 10409c0ca6f9SAndy Whitcroft } 104100df344fSAndy Whitcroft } 104200df344fSAndy Whitcroft 10436c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 10446c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 10456c72ffaaSAndy Whitcroft my $curr_values = annotate_values($opline . "\n", $prev_values); 10466c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 1047*c2fdda0dSAndy Whitcroft if ($dbg_values) { 1048*c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 1049*c2fdda0dSAndy Whitcroft warn "--> .$outline\n"; 1050*c2fdda0dSAndy Whitcroft warn "--> $curr_values\n"; 1051*c2fdda0dSAndy Whitcroft } 10526c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 10536c72ffaaSAndy Whitcroft 105400df344fSAndy Whitcroft#ignore lines not being added 105500df344fSAndy Whitcroft if ($line=~/^[^\+]/) {next;} 105600df344fSAndy Whitcroft 1057653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 1058653d4876SAndy Whitcroft if ($tst_type && $line =~ /^.$Declare$/) { 1059de7d4f0eSAndy Whitcroft ERROR("TEST: is type $Declare\n" . $herecurr); 1060653d4876SAndy Whitcroft next; 1061653d4876SAndy Whitcroft } 1062653d4876SAndy Whitcroft 1063f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 1064f0a594c1SAndy Whitcroft if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 1065f0a594c1SAndy Whitcroft $line =~ /^.\s*{/) { 1066f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . $hereprev); 1067f0a594c1SAndy Whitcroft } 1068f0a594c1SAndy Whitcroft 106900df344fSAndy Whitcroft# 107000df344fSAndy Whitcroft# Checks which are anchored on the added line. 107100df344fSAndy Whitcroft# 107200df344fSAndy Whitcroft 1073653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 1074653d4876SAndy Whitcroft if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { 1075653d4876SAndy Whitcroft my $path = $1; 1076653d4876SAndy Whitcroft if ($path =~ m{//}) { 1077de7d4f0eSAndy Whitcroft ERROR("malformed #include filename\n" . 1078de7d4f0eSAndy Whitcroft $herecurr); 1079653d4876SAndy Whitcroft } 1080653d4876SAndy Whitcroft } 1081653d4876SAndy Whitcroft 108200df344fSAndy Whitcroft# no C99 // comments 108300df344fSAndy Whitcroft if ($line =~ m{//}) { 1084de7d4f0eSAndy Whitcroft ERROR("do not use C99 // comments\n" . $herecurr); 108500df344fSAndy Whitcroft } 108600df344fSAndy Whitcroft # Remove C99 comments. 10870a920b5bSAndy Whitcroft $line =~ s@//.*@@; 10886c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 10890a920b5bSAndy Whitcroft 10900a920b5bSAndy Whitcroft#EXPORT_SYMBOL should immediately follow its function closing }. 1091653d4876SAndy Whitcroft if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 1092653d4876SAndy Whitcroft ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1093653d4876SAndy Whitcroft my $name = $1; 10940a920b5bSAndy Whitcroft if (($prevline !~ /^}/) && 10950a920b5bSAndy Whitcroft ($prevline !~ /^\+}/) && 1096653d4876SAndy Whitcroft ($prevline !~ /^ }/) && 109722f2a2efSAndy Whitcroft ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { 1098de7d4f0eSAndy Whitcroft WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 10990a920b5bSAndy Whitcroft } 11000a920b5bSAndy Whitcroft } 11010a920b5bSAndy Whitcroft 1102f0a594c1SAndy Whitcroft# check for external initialisers. 1103f0a594c1SAndy Whitcroft if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) { 1104f0a594c1SAndy Whitcroft ERROR("do not initialise externals to 0 or NULL\n" . 1105f0a594c1SAndy Whitcroft $herecurr); 1106f0a594c1SAndy Whitcroft } 11070a920b5bSAndy Whitcroft# check for static initialisers. 1108f0a594c1SAndy Whitcroft if ($line =~ /\s*static\s.*=\s*(0|NULL);/) { 1109de7d4f0eSAndy Whitcroft ERROR("do not initialise statics to 0 or NULL\n" . 1110de7d4f0eSAndy Whitcroft $herecurr); 11110a920b5bSAndy Whitcroft } 11120a920b5bSAndy Whitcroft 1113653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 1114653d4876SAndy Whitcroft# make sense. 1115653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 11169c0ca6f9SAndy Whitcroft $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && 1117653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 1118de7d4f0eSAndy Whitcroft WARN("do not add new typedefs\n" . $herecurr); 11190a920b5bSAndy Whitcroft } 11200a920b5bSAndy Whitcroft 11210a920b5bSAndy Whitcroft# * goes on variable not on type 1122d8aaf121SAndy Whitcroft if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) { 1123de7d4f0eSAndy Whitcroft ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" . 1124de7d4f0eSAndy Whitcroft $herecurr); 1125d8aaf121SAndy Whitcroft 1126d8aaf121SAndy Whitcroft } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) { 1127de7d4f0eSAndy Whitcroft ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" . 1128de7d4f0eSAndy Whitcroft $herecurr); 1129d8aaf121SAndy Whitcroft 11309c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) { 1131de7d4f0eSAndy Whitcroft ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" . 1132de7d4f0eSAndy Whitcroft $herecurr); 1133d8aaf121SAndy Whitcroft 11349c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) { 1135de7d4f0eSAndy Whitcroft ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" . 1136de7d4f0eSAndy Whitcroft $herecurr); 11370a920b5bSAndy Whitcroft } 11380a920b5bSAndy Whitcroft 11390a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 11400a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 11410a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 11420a920b5bSAndy Whitcroft# print "$herecurr"; 11430a920b5bSAndy Whitcroft# $clean = 0; 11440a920b5bSAndy Whitcroft# } 11450a920b5bSAndy Whitcroft 11468905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 1147*c2fdda0dSAndy Whitcroft WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 11488905a67cSAndy Whitcroft } 11498905a67cSAndy Whitcroft 115000df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 115100df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 115200df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 115300df344fSAndy Whitcroft# printk includes all preceeding printk's which have no newline on the end. 115400df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 1155f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 115600df344fSAndy Whitcroft my $ok = 0; 115700df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 115800df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 115900df344fSAndy Whitcroft # we have a preceeding printk if it ends 116000df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 116100df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 116200df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 116300df344fSAndy Whitcroft $ok = 1; 116400df344fSAndy Whitcroft } 116500df344fSAndy Whitcroft last; 116600df344fSAndy Whitcroft } 116700df344fSAndy Whitcroft } 116800df344fSAndy Whitcroft if ($ok == 0) { 1169de7d4f0eSAndy Whitcroft WARN("printk() should include KERN_ facility level\n" . $herecurr); 11700a920b5bSAndy Whitcroft } 117100df344fSAndy Whitcroft } 11720a920b5bSAndy Whitcroft 1173653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 1174653d4876SAndy Whitcroft# or if closed on same line 1175*c2fdda0dSAndy Whitcroft if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).*\s{/) and 11760a920b5bSAndy Whitcroft !($line=~/\#define.*do\s{/) and !($line=~/}/)) { 1177de7d4f0eSAndy Whitcroft ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 11780a920b5bSAndy Whitcroft } 1179653d4876SAndy Whitcroft 11808905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 11818905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 11828905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 11838905a67cSAndy Whitcroft ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); 11848905a67cSAndy Whitcroft } 11858905a67cSAndy Whitcroft 1186f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 11876c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 1188*c2fdda0dSAndy Whitcroft my $name = $1; 1189*c2fdda0dSAndy Whitcroft my $ctx = substr($line, 0, $-[1]); 1190*c2fdda0dSAndy Whitcroft 1191*c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 1192*c2fdda0dSAndy Whitcroft if ($name =~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/) { 1193*c2fdda0dSAndy Whitcroft 1194*c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 1195*c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 1196*c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 1197*c2fdda0dSAndy Whitcroft } elsif ($ctx =~ /^.\#\s*define\s*$/) { 1198*c2fdda0dSAndy Whitcroft 1199*c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 1200*c2fdda0dSAndy Whitcroft # likely a typedef for a function. 1201*c2fdda0dSAndy Whitcroft } elsif ("$ctx$name" =~ /$Type$/) { 1202*c2fdda0dSAndy Whitcroft 1203*c2fdda0dSAndy Whitcroft } else { 120422f2a2efSAndy Whitcroft WARN("no space between function name and open parenthesis '('\n" . $herecurr); 1205f0a594c1SAndy Whitcroft } 12066c72ffaaSAndy Whitcroft } 1207653d4876SAndy Whitcroft# Check operator spacing. 12080a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 12099c0ca6f9SAndy Whitcroft my $ops = qr{ 12109c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 12119c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 12129c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 1213*c2fdda0dSAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% 12149c0ca6f9SAndy Whitcroft }x; 12159c0ca6f9SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 121600df344fSAndy Whitcroft my $off = 0; 12176c72ffaaSAndy Whitcroft 12186c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 12196c72ffaaSAndy Whitcroft 12200a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 12214a0df2efSAndy Whitcroft $off += length($elements[$n]); 12224a0df2efSAndy Whitcroft 12234a0df2efSAndy Whitcroft my $a = ''; 12244a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 12254a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 12264a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 12274a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 12284a0df2efSAndy Whitcroft $a = 'E' if ($elements[$n] eq '' && $n == 0); 12294a0df2efSAndy Whitcroft 12300a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 12314a0df2efSAndy Whitcroft 12324a0df2efSAndy Whitcroft my $c = ''; 12330a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 12344a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 12354a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 12364a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 12374a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 123822f2a2efSAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); 12394a0df2efSAndy Whitcroft } else { 12404a0df2efSAndy Whitcroft $c = 'E'; 12410a920b5bSAndy Whitcroft } 12420a920b5bSAndy Whitcroft 124300df344fSAndy Whitcroft # Pick up the preceeding and succeeding characters. 1244de7d4f0eSAndy Whitcroft my $ca = substr($opline, 0, $off); 124500df344fSAndy Whitcroft my $cc = ''; 1246653d4876SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 1247d8aaf121SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 124800df344fSAndy Whitcroft } 1249de7d4f0eSAndy Whitcroft my $cb = "$ca$;$cc"; 125000df344fSAndy Whitcroft 12514a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 12524a0df2efSAndy Whitcroft 12534a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 12544a0df2efSAndy Whitcroft 12556c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 1256de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 12570a920b5bSAndy Whitcroft 12589c0ca6f9SAndy Whitcroft # Classify operators into binary, unary, or 12599c0ca6f9SAndy Whitcroft # definitions (* only) where they have more 12609c0ca6f9SAndy Whitcroft # than one mode. 12616c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 12626c72ffaaSAndy Whitcroft my $op_left = substr($curr_values, $off, 1); 12636c72ffaaSAndy Whitcroft my $is_unary; 12646c72ffaaSAndy Whitcroft if ($op_type eq 'T') { 12659c0ca6f9SAndy Whitcroft $is_unary = 2; 12666c72ffaaSAndy Whitcroft } elsif ($op_left eq 'V') { 12676c72ffaaSAndy Whitcroft $is_unary = 0; 12686c72ffaaSAndy Whitcroft } else { 12696c72ffaaSAndy Whitcroft $is_unary = 1; 12709c0ca6f9SAndy Whitcroft } 12719c0ca6f9SAndy Whitcroft #if ($op eq '-' || $op eq '&' || $op eq '*') { 12726c72ffaaSAndy Whitcroft # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; 12739c0ca6f9SAndy Whitcroft #} 12740a920b5bSAndy Whitcroft 1275d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 1276d8aaf121SAndy Whitcroft if ($op eq ';') { 1277de7d4f0eSAndy Whitcroft if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && 1278de7d4f0eSAndy Whitcroft $cc !~ /^;/) { 1279de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 1280d8aaf121SAndy Whitcroft } 1281d8aaf121SAndy Whitcroft 1282d8aaf121SAndy Whitcroft # // is a comment 1283d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 12840a920b5bSAndy Whitcroft 12850a920b5bSAndy Whitcroft # -> should have no spaces 12860a920b5bSAndy Whitcroft } elsif ($op eq '->') { 12874a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 1288de7d4f0eSAndy Whitcroft ERROR("no spaces around that '$op' $at\n" . $hereptr); 12890a920b5bSAndy Whitcroft } 12900a920b5bSAndy Whitcroft 12910a920b5bSAndy Whitcroft # , must have a space on the right. 12920a920b5bSAndy Whitcroft } elsif ($op eq ',') { 1293d8aaf121SAndy Whitcroft if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { 1294de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 12950a920b5bSAndy Whitcroft } 12960a920b5bSAndy Whitcroft 12979c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 12989c0ca6f9SAndy Whitcroft } elsif ($op eq '*' && $is_unary == 2) { 12999c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 13009c0ca6f9SAndy Whitcroft 13019c0ca6f9SAndy Whitcroft # unary operators should have a space before and 13029c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 13039c0ca6f9SAndy Whitcroft # unary operator, or a cast 13049c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 13059c0ca6f9SAndy Whitcroft ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { 13069c0ca6f9SAndy Whitcroft if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 1307de7d4f0eSAndy Whitcroft ERROR("need space before that '$op' $at\n" . $hereptr); 13080a920b5bSAndy Whitcroft } 13094a0df2efSAndy Whitcroft if ($ctx =~ /.xW/) { 1310de7d4f0eSAndy Whitcroft ERROR("no space after that '$op' $at\n" . $hereptr); 13110a920b5bSAndy Whitcroft } 13120a920b5bSAndy Whitcroft 13130a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 13140a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 1315d8aaf121SAndy Whitcroft if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { 1316de7d4f0eSAndy Whitcroft ERROR("need space one side of that '$op' $at\n" . $hereptr); 13170a920b5bSAndy Whitcroft } 1318d8aaf121SAndy Whitcroft if ($ctx =~ /Wx./ && $cc =~ /^;/) { 1319de7d4f0eSAndy Whitcroft ERROR("no space before that '$op' $at\n" . $hereptr); 1320653d4876SAndy Whitcroft } 13210a920b5bSAndy Whitcroft 13220a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 13239c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 13249c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 13259c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 1326*c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 1327*c2fdda0dSAndy Whitcroft $op eq '%') 13280a920b5bSAndy Whitcroft { 13299c0ca6f9SAndy Whitcroft if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) { 1330de7d4f0eSAndy Whitcroft ERROR("need consistent spacing around '$op' $at\n" . 1331de7d4f0eSAndy Whitcroft $hereptr); 13320a920b5bSAndy Whitcroft } 13330a920b5bSAndy Whitcroft 13340a920b5bSAndy Whitcroft # All the others need spaces both sides. 13354a0df2efSAndy Whitcroft } elsif ($ctx !~ /[EW]x[WE]/) { 133622f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 133722f2a2efSAndy Whitcroft if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && 133822f2a2efSAndy Whitcroft !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { 1339de7d4f0eSAndy Whitcroft ERROR("need spaces around that '$op' $at\n" . $hereptr); 13400a920b5bSAndy Whitcroft } 134122f2a2efSAndy Whitcroft } 13424a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 13430a920b5bSAndy Whitcroft } 13440a920b5bSAndy Whitcroft } 13450a920b5bSAndy Whitcroft 1346f0a594c1SAndy Whitcroft# check for multiple assignments 1347f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 13486c72ffaaSAndy Whitcroft CHK("multiple assignments should be avoided\n" . $herecurr); 1349f0a594c1SAndy Whitcroft } 1350f0a594c1SAndy Whitcroft 135122f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 135222f2a2efSAndy Whitcroft## # continuation. 135322f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 135422f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 135522f2a2efSAndy Whitcroft## 135622f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 135722f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 135822f2a2efSAndy Whitcroft## my $ln = $line; 135922f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 136022f2a2efSAndy Whitcroft## } 136122f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 136222f2a2efSAndy Whitcroft## WARN("declaring multiple variables together should be avoided\n" . $herecurr); 136322f2a2efSAndy Whitcroft## } 136422f2a2efSAndy Whitcroft## } 1365f0a594c1SAndy Whitcroft 13660a920b5bSAndy Whitcroft#need space before brace following if, while, etc 136722f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 136822f2a2efSAndy Whitcroft $line =~ /do{/) { 1369de7d4f0eSAndy Whitcroft ERROR("need a space before the open brace '{'\n" . $herecurr); 1370de7d4f0eSAndy Whitcroft } 1371de7d4f0eSAndy Whitcroft 1372de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 1373de7d4f0eSAndy Whitcroft# on the line 1374de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 1375de7d4f0eSAndy Whitcroft ERROR("need a space after that close brace '}'\n" . $herecurr); 13760a920b5bSAndy Whitcroft } 13770a920b5bSAndy Whitcroft 137822f2a2efSAndy Whitcroft# check spacing on square brackets 137922f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 138022f2a2efSAndy Whitcroft ERROR("no space after that open square bracket '['\n" . $herecurr); 138122f2a2efSAndy Whitcroft } 138222f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 138322f2a2efSAndy Whitcroft ERROR("no space before that close square bracket ']'\n" . $herecurr); 138422f2a2efSAndy Whitcroft } 138522f2a2efSAndy Whitcroft 138622f2a2efSAndy Whitcroft# check spacing on paretheses 13879c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 13889c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 138922f2a2efSAndy Whitcroft ERROR("no space after that open parenthesis '('\n" . $herecurr); 139022f2a2efSAndy Whitcroft } 13919c0ca6f9SAndy Whitcroft if ($line =~ /\s\)/ && $line !~ /^.\s*\)/ && 13929c0ca6f9SAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/) { 139322f2a2efSAndy Whitcroft ERROR("no space before that close parenthesis ')'\n" . $herecurr); 139422f2a2efSAndy Whitcroft } 139522f2a2efSAndy Whitcroft 13960a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 13974a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 13980a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 1399de7d4f0eSAndy Whitcroft WARN("labels should not be indented\n" . $herecurr); 14000a920b5bSAndy Whitcroft } 14010a920b5bSAndy Whitcroft 14020a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 14034a0df2efSAndy Whitcroft if ($line=~/\b(if|while|for|switch)\(/) { 1404de7d4f0eSAndy Whitcroft ERROR("need a space before the open parenthesis '('\n" . $herecurr); 14050a920b5bSAndy Whitcroft } 14060a920b5bSAndy Whitcroft 14070a920b5bSAndy Whitcroft# Check for illegal assignment in if conditional. 14088905a67cSAndy Whitcroft if ($line =~ /\bif\s*\(/) { 14098905a67cSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 14108905a67cSAndy Whitcroft 14118905a67cSAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { 1412*c2fdda0dSAndy Whitcroft ERROR("do not use assignment in if condition\n" . $herecurr); 14138905a67cSAndy Whitcroft } 14148905a67cSAndy Whitcroft 14158905a67cSAndy Whitcroft # Find out what is on the end of the line after the 14168905a67cSAndy Whitcroft # conditional. 14178905a67cSAndy Whitcroft substr($s, 0, length($c)) = ''; 14188905a67cSAndy Whitcroft $s =~ s/\n.*//g; 14198905a67cSAndy Whitcroft 14208905a67cSAndy Whitcroft if (length($c) && $s !~ /^\s*({|;|\/\*.*\*\/)?\s*\\*\s*$/) { 14218905a67cSAndy Whitcroft ERROR("trailing statements should be on next line\n" . $herecurr); 14228905a67cSAndy Whitcroft } 14238905a67cSAndy Whitcroft } 14248905a67cSAndy Whitcroft 14258905a67cSAndy Whitcroft# if and else should not have general statements after it 14268905a67cSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ && 14278905a67cSAndy Whitcroft $1 !~ /^\s*(?:\sif|{|\\|$)/) { 14288905a67cSAndy Whitcroft ERROR("trailing statements should be on next line\n" . $herecurr); 14290a920b5bSAndy Whitcroft } 14300a920b5bSAndy Whitcroft 14310a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 14320a920b5bSAndy Whitcroft # indent level to be relevant to each other. 14330a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 14340a920b5bSAndy Whitcroft $previndent == $indent) { 1435de7d4f0eSAndy Whitcroft ERROR("else should follow close brace '}'\n" . $hereprev); 14360a920b5bSAndy Whitcroft } 14370a920b5bSAndy Whitcroft 1438*c2fdda0dSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 1439*c2fdda0dSAndy Whitcroft $previndent == $indent) { 1440*c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 1441*c2fdda0dSAndy Whitcroft 1442*c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 1443*c2fdda0dSAndy Whitcroft # conditional. 1444*c2fdda0dSAndy Whitcroft substr($s, 0, length($c)) = ''; 1445*c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 1446*c2fdda0dSAndy Whitcroft 1447*c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 1448*c2fdda0dSAndy Whitcroft ERROR("while should follow close brace '}'\n" . $hereprev); 1449*c2fdda0dSAndy Whitcroft } 1450*c2fdda0dSAndy Whitcroft } 1451*c2fdda0dSAndy Whitcroft 14520a920b5bSAndy Whitcroft#studly caps, commented out until figure out how to distinguish between use of existing and adding new 14530a920b5bSAndy Whitcroft# if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { 14540a920b5bSAndy Whitcroft# print "No studly caps, use _\n"; 14550a920b5bSAndy Whitcroft# print "$herecurr"; 14560a920b5bSAndy Whitcroft# $clean = 0; 14570a920b5bSAndy Whitcroft# } 14580a920b5bSAndy Whitcroft 14590a920b5bSAndy Whitcroft#no spaces allowed after \ in define 14600a920b5bSAndy Whitcroft if ($line=~/\#define.*\\\s$/) { 1461de7d4f0eSAndy Whitcroft WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); 14620a920b5bSAndy Whitcroft } 14630a920b5bSAndy Whitcroft 1464653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 1465653d4876SAndy Whitcroft if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { 14666c72ffaaSAndy Whitcroft my $checkfile = "$root/include/linux/$1.h"; 14676c72ffaaSAndy Whitcroft if (-f $checkfile && $1 ne 'irq.h') { 1468de7d4f0eSAndy Whitcroft CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . 1469de7d4f0eSAndy Whitcroft $herecurr); 14700a920b5bSAndy Whitcroft } 14710a920b5bSAndy Whitcroft } 14720a920b5bSAndy Whitcroft 1473653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 1474653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 1475653d4876SAndy Whitcroft# in a known goot container 14769c0ca6f9SAndy Whitcroft if ($prevline =~ /\#define.*\\/ && 14779c0ca6f9SAndy Whitcroft $prevline !~/(?:do\s+{|\(\{|\{)/ && 14789c0ca6f9SAndy Whitcroft $line !~ /(?:do\s+{|\(\{|\{)/ && 14799c0ca6f9SAndy Whitcroft $line !~ /^.\s*$Declare\s/) { 1480653d4876SAndy Whitcroft # Grab the first statement, if that is the entire macro 1481653d4876SAndy Whitcroft # its ok. This may start either on the #define line 1482653d4876SAndy Whitcroft # or the one below. 1483d8aaf121SAndy Whitcroft my $ln = $linenr; 1484d8aaf121SAndy Whitcroft my $cnt = $realcnt; 1485f0a594c1SAndy Whitcroft my $off = 0; 1486653d4876SAndy Whitcroft 1487f0a594c1SAndy Whitcroft # If the macro starts on the define line start 1488f0a594c1SAndy Whitcroft # grabbing the statement after the identifier 1489f0a594c1SAndy Whitcroft $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; 1490f0a594c1SAndy Whitcroft ##print "1<$1> 2<$2>\n"; 149122f2a2efSAndy Whitcroft if (defined $2 && $2 ne '') { 1492f0a594c1SAndy Whitcroft $off = length($1); 1493d8aaf121SAndy Whitcroft $ln--; 1494d8aaf121SAndy Whitcroft $cnt++; 14958905a67cSAndy Whitcroft while ($lines[$ln - 1] =~ /^-/) { 14968905a67cSAndy Whitcroft $ln--; 14978905a67cSAndy Whitcroft $cnt++; 14988905a67cSAndy Whitcroft } 1499d8aaf121SAndy Whitcroft } 1500f0a594c1SAndy Whitcroft my @ctx = ctx_statement($ln, $cnt, $off); 1501de7d4f0eSAndy Whitcroft my $ctx_ln = $ln + $#ctx + 1; 1502de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 1503de7d4f0eSAndy Whitcroft 1504de7d4f0eSAndy Whitcroft # Pull in any empty extension lines. 1505de7d4f0eSAndy Whitcroft while ($ctx =~ /\\$/ && 1506de7d4f0eSAndy Whitcroft $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { 1507de7d4f0eSAndy Whitcroft $ctx .= $lines[$ctx_ln - 1]; 1508de7d4f0eSAndy Whitcroft $ctx_ln++; 1509de7d4f0eSAndy Whitcroft } 1510d8aaf121SAndy Whitcroft 1511d8aaf121SAndy Whitcroft if ($ctx =~ /\\$/) { 1512d8aaf121SAndy Whitcroft if ($ctx =~ /;/) { 1513de7d4f0eSAndy Whitcroft ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 1514d8aaf121SAndy Whitcroft } else { 1515de7d4f0eSAndy Whitcroft ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 1516d8aaf121SAndy Whitcroft } 15170a920b5bSAndy Whitcroft } 1518653d4876SAndy Whitcroft } 15190a920b5bSAndy Whitcroft 1520f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 1521f0a594c1SAndy Whitcroft if ($line =~ /\b(if|while|for|else)\b/) { 1522f0a594c1SAndy Whitcroft # Locate the end of the opening statement. 1523f0a594c1SAndy Whitcroft my @control = ctx_statement($linenr, $realcnt, 0); 1524f0a594c1SAndy Whitcroft my $nr = $linenr + (scalar(@control) - 1); 1525f0a594c1SAndy Whitcroft my $cnt = $realcnt - (scalar(@control) - 1); 1526f0a594c1SAndy Whitcroft 1527f0a594c1SAndy Whitcroft my $off = $realcnt - $cnt; 1528f0a594c1SAndy Whitcroft #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; 1529f0a594c1SAndy Whitcroft 1530f0a594c1SAndy Whitcroft # If this is is a braced statement group check it 1531f0a594c1SAndy Whitcroft if ($lines[$nr - 1] =~ /{\s*$/) { 1532f0a594c1SAndy Whitcroft my ($lvl, @block) = ctx_block_level($nr, $cnt); 1533f0a594c1SAndy Whitcroft 15348905a67cSAndy Whitcroft my $stmt = join("\n", @block); 15358905a67cSAndy Whitcroft # Drop the diff line leader. 15368905a67cSAndy Whitcroft $stmt =~ s/\n./\n/g; 15378905a67cSAndy Whitcroft # Drop the code outside the block. 15388905a67cSAndy Whitcroft $stmt =~ s/(^[^{]*){\s*//; 153922f2a2efSAndy Whitcroft my $before = $1; 15408905a67cSAndy Whitcroft $stmt =~ s/\s*}([^}]*$)//; 154122f2a2efSAndy Whitcroft my $after = $1; 1542f0a594c1SAndy Whitcroft 1543f0a594c1SAndy Whitcroft #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; 1544f0a594c1SAndy Whitcroft #print "stmt<$stmt>\n\n"; 1545f0a594c1SAndy Whitcroft 15468905a67cSAndy Whitcroft # Count the newlines, if there is only one 15478905a67cSAndy Whitcroft # then the block should not have {}'s. 15488905a67cSAndy Whitcroft my @lines = ($stmt =~ /\n/g); 1549*c2fdda0dSAndy Whitcroft my @statements = ($stmt =~ /;/g); 15508905a67cSAndy Whitcroft #print "lines<" . scalar(@lines) . ">\n"; 1551*c2fdda0dSAndy Whitcroft #print "statements<" . scalar(@statements) . ">\n"; 15528905a67cSAndy Whitcroft if ($lvl == 0 && scalar(@lines) == 0 && 1553*c2fdda0dSAndy Whitcroft scalar(@statements) < 2 && 155422f2a2efSAndy Whitcroft $stmt !~ /{/ && $stmt !~ /\bif\b/ && 155522f2a2efSAndy Whitcroft $before !~ /}/ && $after !~ /{/) { 1556f0a594c1SAndy Whitcroft my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; 1557f0a594c1SAndy Whitcroft shift(@block); 155822f2a2efSAndy Whitcroft WARN("braces {} are not necessary for single statement blocks\n" . $herectx); 1559f0a594c1SAndy Whitcroft } 1560f0a594c1SAndy Whitcroft } 1561f0a594c1SAndy Whitcroft } 1562f0a594c1SAndy Whitcroft 1563653d4876SAndy Whitcroft# don't include deprecated include files (uses RAW line) 15644a0df2efSAndy Whitcroft for my $inc (@dep_includes) { 1565653d4876SAndy Whitcroft if ($rawline =~ m@\#\s*include\s*\<$inc>@) { 1566de7d4f0eSAndy Whitcroft ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); 15670a920b5bSAndy Whitcroft } 15680a920b5bSAndy Whitcroft } 15690a920b5bSAndy Whitcroft 15704a0df2efSAndy Whitcroft# don't use deprecated functions 15714a0df2efSAndy Whitcroft for my $func (@dep_functions) { 157200df344fSAndy Whitcroft if ($line =~ /\b$func\b/) { 1573de7d4f0eSAndy Whitcroft ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); 15744a0df2efSAndy Whitcroft } 15754a0df2efSAndy Whitcroft } 15764a0df2efSAndy Whitcroft 15774a0df2efSAndy Whitcroft# no volatiles please 15786c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 15796c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 1580de7d4f0eSAndy Whitcroft WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 15814a0df2efSAndy Whitcroft } 15824a0df2efSAndy Whitcroft 15839c0ca6f9SAndy Whitcroft# SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated 15849c0ca6f9SAndy Whitcroft if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) { 15859c0ca6f9SAndy Whitcroft ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr); 15869c0ca6f9SAndy Whitcroft } 15879c0ca6f9SAndy Whitcroft 158800df344fSAndy Whitcroft# warn about #if 0 158900df344fSAndy Whitcroft if ($line =~ /^.#\s*if\s+0\b/) { 1590de7d4f0eSAndy Whitcroft CHK("if this code is redundant consider removing it\n" . 1591de7d4f0eSAndy Whitcroft $herecurr); 15924a0df2efSAndy Whitcroft } 15934a0df2efSAndy Whitcroft 1594f0a594c1SAndy Whitcroft# check for needless kfree() checks 1595f0a594c1SAndy Whitcroft if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { 1596f0a594c1SAndy Whitcroft my $expr = $1; 1597f0a594c1SAndy Whitcroft if ($line =~ /\bkfree\(\Q$expr\E\);/) { 1598f0a594c1SAndy Whitcroft WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev); 1599f0a594c1SAndy Whitcroft } 1600f0a594c1SAndy Whitcroft } 1601f0a594c1SAndy Whitcroft 160200df344fSAndy Whitcroft# warn about #ifdefs in C files 160300df344fSAndy Whitcroft# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 160400df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 160500df344fSAndy Whitcroft# print "$herecurr"; 160600df344fSAndy Whitcroft# $clean = 0; 160700df344fSAndy Whitcroft# } 160800df344fSAndy Whitcroft 160922f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 161022f2a2efSAndy Whitcroft if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { 161122f2a2efSAndy Whitcroft ERROR("exactly one space required after that #$1\n" . $herecurr); 161222f2a2efSAndy Whitcroft } 161322f2a2efSAndy Whitcroft 16144a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 16154a0df2efSAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { 16164a0df2efSAndy Whitcroft my $which = $1; 16174a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1618de7d4f0eSAndy Whitcroft CHK("$1 definition without comment\n" . $herecurr); 16194a0df2efSAndy Whitcroft } 16204a0df2efSAndy Whitcroft } 16214a0df2efSAndy Whitcroft# check for memory barriers without a comment. 16224a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 16234a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1624de7d4f0eSAndy Whitcroft CHK("memory barrier without comment\n" . $herecurr); 16254a0df2efSAndy Whitcroft } 16264a0df2efSAndy Whitcroft } 16274a0df2efSAndy Whitcroft# check of hardware specific defines 162822f2a2efSAndy Whitcroft if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 1629de7d4f0eSAndy Whitcroft CHK("architecture specific defines should be avoided\n" . $herecurr); 16300a920b5bSAndy Whitcroft } 1631653d4876SAndy Whitcroft 1632de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 1633de7d4f0eSAndy Whitcroft# storage class and type. 16349c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 16359c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 1636de7d4f0eSAndy Whitcroft ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 1637de7d4f0eSAndy Whitcroft } 1638de7d4f0eSAndy Whitcroft 16398905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 16408905a67cSAndy Whitcroft if ($line =~ /\b(__inline__|__inline)\b/) { 16418905a67cSAndy Whitcroft WARN("plain inline is preferred over $1\n" . $herecurr); 16428905a67cSAndy Whitcroft } 16438905a67cSAndy Whitcroft 1644de7d4f0eSAndy Whitcroft# check for new externs in .c files. 1645de7d4f0eSAndy Whitcroft if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { 1646de7d4f0eSAndy Whitcroft WARN("externs should be avoided in .c files\n" . $herecurr); 1647de7d4f0eSAndy Whitcroft } 1648de7d4f0eSAndy Whitcroft 1649de7d4f0eSAndy Whitcroft# checks for new __setup's 1650de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 1651de7d4f0eSAndy Whitcroft my $name = $1; 1652de7d4f0eSAndy Whitcroft 1653de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 1654de7d4f0eSAndy Whitcroft CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 1655de7d4f0eSAndy Whitcroft } 1656653d4876SAndy Whitcroft } 16579c0ca6f9SAndy Whitcroft 16589c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 16599c0ca6f9SAndy Whitcroft if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) { 16609c0ca6f9SAndy Whitcroft WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 16619c0ca6f9SAndy Whitcroft } 16620a920b5bSAndy Whitcroft } 16630a920b5bSAndy Whitcroft 16648905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 16658905a67cSAndy Whitcroft # things that appear to be patches. 16668905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 16678905a67cSAndy Whitcroft exit(0); 16688905a67cSAndy Whitcroft } 16698905a67cSAndy Whitcroft 16708905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 16718905a67cSAndy Whitcroft # just keep quiet. 16728905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 16738905a67cSAndy Whitcroft exit(0); 16748905a67cSAndy Whitcroft } 16758905a67cSAndy Whitcroft 16768905a67cSAndy Whitcroft if (!$is_patch) { 1677de7d4f0eSAndy Whitcroft ERROR("Does not appear to be a unified-diff format patch\n"); 16780a920b5bSAndy Whitcroft } 16790a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 1680de7d4f0eSAndy Whitcroft ERROR("Missing Signed-off-by: line(s)\n"); 16810a920b5bSAndy Whitcroft } 16820a920b5bSAndy Whitcroft 1683f0a594c1SAndy Whitcroft print report_dump(); 16848905a67cSAndy Whitcroft if ($summary) { 16856c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 16866c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 16876c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 16888905a67cSAndy Whitcroft print "\n" if ($quiet == 0); 16896c72ffaaSAndy Whitcroft } 16908905a67cSAndy Whitcroft 16910a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 1692*c2fdda0dSAndy Whitcroft print "$vname has no obvious style problems and is ready for submission.\n" 16930a920b5bSAndy Whitcroft } 16940a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 1695*c2fdda0dSAndy Whitcroft print "$vname has style problems, please review. If any of these errors\n"; 16960a920b5bSAndy Whitcroft print "are false positives report them to the maintainer, see\n"; 16970a920b5bSAndy Whitcroft print "CHECKPATCH in MAINTAINERS.\n"; 16980a920b5bSAndy Whitcroft } 16990a920b5bSAndy Whitcroft return $clean; 17000a920b5bSAndy Whitcroft} 1701