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*8905a67cSAndy Whitcroftmy $V = '0.12'; 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; 22*8905a67cSAndy Whitcroftmy $terse = 0; 236c72ffaaSAndy Whitcroftmy $file = 0; 246c72ffaaSAndy Whitcroftmy $check = 0; 25*8905a67cSAndy Whitcroftmy $summary = 1; 26*8905a67cSAndy Whitcroftmy $mailback = 0; 276c72ffaaSAndy Whitcroftmy $root; 280a920b5bSAndy WhitcroftGetOptions( 296c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 300a920b5bSAndy Whitcroft 'tree!' => \$tree, 310a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 320a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 33653d4876SAndy Whitcroft 'test-type!' => \$tst_type, 346c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 35*8905a67cSAndy Whitcroft 'terse!' => \$terse, 366c72ffaaSAndy Whitcroft 'file!' => \$file, 376c72ffaaSAndy Whitcroft 'subjective!' => \$check, 386c72ffaaSAndy Whitcroft 'strict!' => \$check, 396c72ffaaSAndy Whitcroft 'root=s' => \$root, 40*8905a67cSAndy Whitcroft 'summary!' => \$summary, 41*8905a67cSAndy Whitcroft 'mailback!' => \$mailback, 420a920b5bSAndy Whitcroft) or exit; 430a920b5bSAndy Whitcroft 440a920b5bSAndy Whitcroftmy $exit = 0; 450a920b5bSAndy Whitcroft 460a920b5bSAndy Whitcroftif ($#ARGV < 0) { 4700df344fSAndy Whitcroft print "usage: $P [options] patchfile\n"; 480a920b5bSAndy Whitcroft print "version: $V\n"; 490a920b5bSAndy Whitcroft print "options: -q => quiet\n"; 500a920b5bSAndy Whitcroft print " --no-tree => run without a kernel tree\n"; 51*8905a67cSAndy Whitcroft print " --terse => one line per report\n"; 526c72ffaaSAndy Whitcroft print " --emacs => emacs compile window format\n"; 536c72ffaaSAndy Whitcroft print " --file => check a source file\n"; 546c72ffaaSAndy Whitcroft print " --strict => enable more subjective tests\n"; 556c72ffaaSAndy Whitcroft print " --root => path to the kernel tree root\n"; 560a920b5bSAndy Whitcroft exit(1); 570a920b5bSAndy Whitcroft} 580a920b5bSAndy Whitcroft 59*8905a67cSAndy Whitcroftif ($terse) { 60*8905a67cSAndy Whitcroft $emacs = 1; 61*8905a67cSAndy Whitcroft $quiet++; 62*8905a67cSAndy Whitcroft} 63*8905a67cSAndy Whitcroft 646c72ffaaSAndy Whitcroftif ($tree) { 656c72ffaaSAndy Whitcroft if (defined $root) { 666c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 676c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 686c72ffaaSAndy Whitcroft } 696c72ffaaSAndy Whitcroft } else { 706c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 716c72ffaaSAndy Whitcroft $root = '.'; 726c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 736c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 746c72ffaaSAndy Whitcroft $root = $1; 756c72ffaaSAndy Whitcroft } 766c72ffaaSAndy Whitcroft } 776c72ffaaSAndy Whitcroft 786c72ffaaSAndy Whitcroft if (!defined $root) { 790a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 800a920b5bSAndy Whitcroft exit(2); 810a920b5bSAndy Whitcroft } 826c72ffaaSAndy Whitcroft} 836c72ffaaSAndy Whitcroft 846c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 856c72ffaaSAndy Whitcroft 866c72ffaaSAndy Whitcroftour $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; 876c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 886c72ffaaSAndy Whitcroftour $Sparse = qr{ 896c72ffaaSAndy Whitcroft __user| 906c72ffaaSAndy Whitcroft __kernel| 916c72ffaaSAndy Whitcroft __force| 926c72ffaaSAndy Whitcroft __iomem| 936c72ffaaSAndy Whitcroft __must_check| 946c72ffaaSAndy Whitcroft __init_refok| 956c72ffaaSAndy Whitcroft __kprobes| 966c72ffaaSAndy Whitcroft fastcall 976c72ffaaSAndy Whitcroft }x; 986c72ffaaSAndy Whitcroftour $Attribute = qr{ 996c72ffaaSAndy Whitcroft const| 1006c72ffaaSAndy Whitcroft __read_mostly| 1016c72ffaaSAndy Whitcroft __kprobes| 1026c72ffaaSAndy Whitcroft __(?:mem|cpu|dev|)(?:initdata|init) 1036c72ffaaSAndy Whitcroft }x; 1046c72ffaaSAndy Whitcroftour $Inline = qr{inline|__always_inline|noinline}; 1056c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 1066c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 1076c72ffaaSAndy Whitcroft 1086c72ffaaSAndy Whitcroftour $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; 1096c72ffaaSAndy Whitcroftour $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; 1106c72ffaaSAndy Whitcroftour $Operators = qr{ 1116c72ffaaSAndy Whitcroft <=|>=|==|!=| 1126c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 1136c72ffaaSAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ 1146c72ffaaSAndy Whitcroft }x; 1156c72ffaaSAndy Whitcroft 116*8905a67cSAndy Whitcroftour $NonptrType; 117*8905a67cSAndy Whitcroftour $Type; 118*8905a67cSAndy Whitcroftour $Declare; 119*8905a67cSAndy Whitcroft 120*8905a67cSAndy Whitcroftour @typeList = ( 121*8905a67cSAndy Whitcroft qr{void}, 122*8905a67cSAndy Whitcroft qr{char}, 123*8905a67cSAndy Whitcroft qr{short}, 124*8905a67cSAndy Whitcroft qr{int}, 125*8905a67cSAndy Whitcroft qr{long}, 126*8905a67cSAndy Whitcroft qr{unsigned}, 127*8905a67cSAndy Whitcroft qr{float}, 128*8905a67cSAndy Whitcroft qr{double}, 129*8905a67cSAndy Whitcroft qr{bool}, 130*8905a67cSAndy Whitcroft qr{long\s+int}, 131*8905a67cSAndy Whitcroft qr{long\s+long}, 132*8905a67cSAndy Whitcroft qr{long\s+long\s+int}, 133*8905a67cSAndy Whitcroft qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)}, 134*8905a67cSAndy Whitcroft qr{struct\s+$Ident}, 135*8905a67cSAndy Whitcroft qr{union\s+$Ident}, 136*8905a67cSAndy Whitcroft qr{enum\s+$Ident}, 137*8905a67cSAndy Whitcroft qr{${Ident}_t}, 138*8905a67cSAndy Whitcroft qr{${Ident}_handler}, 139*8905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 140*8905a67cSAndy Whitcroft); 141*8905a67cSAndy Whitcroft 142*8905a67cSAndy Whitcroftsub build_types { 143*8905a67cSAndy Whitcroft my $all = "(?: \n" . join("|\n ", @typeList) . "\n)"; 144*8905a67cSAndy Whitcroft $NonptrType = qr{ 145*8905a67cSAndy Whitcroft \b 146*8905a67cSAndy Whitcroft (?:const\s+)? 147*8905a67cSAndy Whitcroft (?:unsigned\s+)? 148*8905a67cSAndy Whitcroft $all 149*8905a67cSAndy Whitcroft (?:\s+$Sparse|\s+const)* 150*8905a67cSAndy Whitcroft \b 151*8905a67cSAndy Whitcroft }x; 152*8905a67cSAndy Whitcroft $Type = qr{ 153*8905a67cSAndy Whitcroft \b$NonptrType\b 154*8905a67cSAndy Whitcroft (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 155*8905a67cSAndy Whitcroft (?:\s+$Sparse|\s+$Attribute)* 156*8905a67cSAndy Whitcroft }x; 157*8905a67cSAndy Whitcroft $Declare = qr{(?:$Storage\s+)?$Type}; 158*8905a67cSAndy Whitcroft} 159*8905a67cSAndy Whitcroftbuild_types(); 1606c72ffaaSAndy Whitcroft 1616c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 1620a920b5bSAndy Whitcroft 1634a0df2efSAndy Whitcroftmy @dep_includes = (); 1644a0df2efSAndy Whitcroftmy @dep_functions = (); 1656c72ffaaSAndy Whitcroftmy $removal = "Documentation/feature-removal-schedule.txt"; 1666c72ffaaSAndy Whitcroftif ($tree && -f "$root/$removal") { 1676c72ffaaSAndy Whitcroft open(REMOVE, "<$root/$removal") || 1686c72ffaaSAndy Whitcroft die "$P: $removal: open failed - $!\n"; 1690a920b5bSAndy Whitcroft while (<REMOVE>) { 170f0a594c1SAndy Whitcroft if (/^Check:\s+(.*\S)/) { 171f0a594c1SAndy Whitcroft for my $entry (split(/[, ]+/, $1)) { 172f0a594c1SAndy Whitcroft if ($entry =~ m@include/(.*)@) { 1734a0df2efSAndy Whitcroft push(@dep_includes, $1); 1744a0df2efSAndy Whitcroft 175f0a594c1SAndy Whitcroft } elsif ($entry !~ m@/@) { 176f0a594c1SAndy Whitcroft push(@dep_functions, $entry); 177f0a594c1SAndy Whitcroft } 1784a0df2efSAndy Whitcroft } 1790a920b5bSAndy Whitcroft } 1800a920b5bSAndy Whitcroft } 1810a920b5bSAndy Whitcroft} 1820a920b5bSAndy Whitcroft 18300df344fSAndy Whitcroftmy @rawlines = (); 1846c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 1856c72ffaaSAndy Whitcroft if ($file) { 1866c72ffaaSAndy Whitcroft open(FILE, "diff -u /dev/null $filename|") || 1876c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 1886c72ffaaSAndy Whitcroft } else { 1896c72ffaaSAndy Whitcroft open(FILE, "<$filename") || 1906c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 1916c72ffaaSAndy Whitcroft } 1926c72ffaaSAndy Whitcroft while (<FILE>) { 1930a920b5bSAndy Whitcroft chomp; 19400df344fSAndy Whitcroft push(@rawlines, $_); 1956c72ffaaSAndy Whitcroft } 1966c72ffaaSAndy Whitcroft close(FILE); 1976c72ffaaSAndy Whitcroft if (!process($filename, @rawlines)) { 1980a920b5bSAndy Whitcroft $exit = 1; 1990a920b5bSAndy Whitcroft } 20000df344fSAndy Whitcroft @rawlines = (); 2010a920b5bSAndy Whitcroft} 2020a920b5bSAndy Whitcroft 2030a920b5bSAndy Whitcroftexit($exit); 2040a920b5bSAndy Whitcroft 2050a920b5bSAndy Whitcroftsub top_of_kernel_tree { 2066c72ffaaSAndy Whitcroft my ($root) = @_; 2076c72ffaaSAndy Whitcroft 2086c72ffaaSAndy Whitcroft my @tree_check = ( 2096c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 2106c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 2116c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 2126c72ffaaSAndy Whitcroft ); 2136c72ffaaSAndy Whitcroft 2146c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 2156c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 2160a920b5bSAndy Whitcroft return 0; 2170a920b5bSAndy Whitcroft } 2186c72ffaaSAndy Whitcroft } 2196c72ffaaSAndy Whitcroft return 1; 2206c72ffaaSAndy Whitcroft} 2210a920b5bSAndy Whitcroft 2220a920b5bSAndy Whitcroftsub expand_tabs { 2230a920b5bSAndy Whitcroft my ($str) = @_; 2240a920b5bSAndy Whitcroft 2250a920b5bSAndy Whitcroft my $res = ''; 2260a920b5bSAndy Whitcroft my $n = 0; 2270a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 2280a920b5bSAndy Whitcroft if ($c eq "\t") { 2290a920b5bSAndy Whitcroft $res .= ' '; 2300a920b5bSAndy Whitcroft $n++; 2310a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 2320a920b5bSAndy Whitcroft $res .= ' '; 2330a920b5bSAndy Whitcroft } 2340a920b5bSAndy Whitcroft next; 2350a920b5bSAndy Whitcroft } 2360a920b5bSAndy Whitcroft $res .= $c; 2370a920b5bSAndy Whitcroft $n++; 2380a920b5bSAndy Whitcroft } 2390a920b5bSAndy Whitcroft 2400a920b5bSAndy Whitcroft return $res; 2410a920b5bSAndy Whitcroft} 2426c72ffaaSAndy Whitcroftsub copy_spacing { 2436c72ffaaSAndy Whitcroft my ($str) = @_; 2446c72ffaaSAndy Whitcroft 2456c72ffaaSAndy Whitcroft my $res = ''; 2466c72ffaaSAndy Whitcroft for my $c (split(//, $str)) { 2476c72ffaaSAndy Whitcroft if ($c eq "\t") { 2486c72ffaaSAndy Whitcroft $res .= $c; 2496c72ffaaSAndy Whitcroft } else { 2506c72ffaaSAndy Whitcroft $res .= ' '; 2516c72ffaaSAndy Whitcroft } 2526c72ffaaSAndy Whitcroft } 2536c72ffaaSAndy Whitcroft 2546c72ffaaSAndy Whitcroft return $res; 2556c72ffaaSAndy Whitcroft} 2560a920b5bSAndy Whitcroft 2574a0df2efSAndy Whitcroftsub line_stats { 2584a0df2efSAndy Whitcroft my ($line) = @_; 2594a0df2efSAndy Whitcroft 2604a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 2614a0df2efSAndy Whitcroft $line =~ s/^.//; 2624a0df2efSAndy Whitcroft $line = expand_tabs($line); 2634a0df2efSAndy Whitcroft 2644a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 2654a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 2664a0df2efSAndy Whitcroft 2674a0df2efSAndy Whitcroft return (length($line), length($white)); 2684a0df2efSAndy Whitcroft} 2694a0df2efSAndy Whitcroft 27000df344fSAndy Whitcroftsub sanitise_line { 27100df344fSAndy Whitcroft my ($line) = @_; 27200df344fSAndy Whitcroft 27300df344fSAndy Whitcroft my $res = ''; 27400df344fSAndy Whitcroft my $l = ''; 27500df344fSAndy Whitcroft 27600df344fSAndy Whitcroft my $quote = ''; 27700df344fSAndy Whitcroft 27800df344fSAndy Whitcroft foreach my $c (split(//, $line)) { 27900df344fSAndy Whitcroft if ($l ne "\\" && ($c eq "'" || $c eq '"')) { 28000df344fSAndy Whitcroft if ($quote eq '') { 28100df344fSAndy Whitcroft $quote = $c; 28200df344fSAndy Whitcroft $res .= $c; 28300df344fSAndy Whitcroft $l = $c; 28400df344fSAndy Whitcroft next; 28500df344fSAndy Whitcroft } elsif ($quote eq $c) { 28600df344fSAndy Whitcroft $quote = ''; 28700df344fSAndy Whitcroft } 28800df344fSAndy Whitcroft } 28900df344fSAndy Whitcroft if ($quote && $c ne "\t") { 29000df344fSAndy Whitcroft $res .= "X"; 29100df344fSAndy Whitcroft } else { 29200df344fSAndy Whitcroft $res .= $c; 29300df344fSAndy Whitcroft } 29400df344fSAndy Whitcroft 29500df344fSAndy Whitcroft $l = $c; 29600df344fSAndy Whitcroft } 29700df344fSAndy Whitcroft 29800df344fSAndy Whitcroft return $res; 29900df344fSAndy Whitcroft} 30000df344fSAndy Whitcroft 301*8905a67cSAndy Whitcroftsub ctx_statement_block { 302*8905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 303*8905a67cSAndy Whitcroft my $line = $linenr - 1; 304*8905a67cSAndy Whitcroft my $blk = ''; 305*8905a67cSAndy Whitcroft my $soff = $off; 306*8905a67cSAndy Whitcroft my $coff = $off - 1; 307*8905a67cSAndy Whitcroft 308*8905a67cSAndy Whitcroft my $type = ''; 309*8905a67cSAndy Whitcroft my $level = 0; 310*8905a67cSAndy Whitcroft my $c; 311*8905a67cSAndy Whitcroft my $len = 0; 312*8905a67cSAndy Whitcroft while (1) { 313*8905a67cSAndy Whitcroft #warn "CSB: blk<$blk>\n"; 314*8905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 315*8905a67cSAndy Whitcroft # context. 316*8905a67cSAndy Whitcroft if ($off >= $len) { 317*8905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 318*8905a67cSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 319*8905a67cSAndy Whitcroft $remain--; 320*8905a67cSAndy Whitcroft $blk .= sanitise_line($rawlines[$line]) . "\n"; 321*8905a67cSAndy Whitcroft $len = length($blk); 322*8905a67cSAndy Whitcroft $line++; 323*8905a67cSAndy Whitcroft last; 324*8905a67cSAndy Whitcroft } 325*8905a67cSAndy Whitcroft # Bail if there is no further context. 326*8905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 327*8905a67cSAndy Whitcroft if ($off == $len) { 328*8905a67cSAndy Whitcroft last; 329*8905a67cSAndy Whitcroft } 330*8905a67cSAndy Whitcroft } 331*8905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 332*8905a67cSAndy Whitcroft 333*8905a67cSAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level>\n"; 334*8905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 335*8905a67cSAndy Whitcroft # outermost level. 336*8905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 337*8905a67cSAndy Whitcroft last; 338*8905a67cSAndy Whitcroft } 339*8905a67cSAndy Whitcroft 340*8905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 341*8905a67cSAndy Whitcroft $level++; 342*8905a67cSAndy Whitcroft $type = '('; 343*8905a67cSAndy Whitcroft } 344*8905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 345*8905a67cSAndy Whitcroft $level--; 346*8905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 347*8905a67cSAndy Whitcroft 348*8905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 349*8905a67cSAndy Whitcroft $coff = $off; 350*8905a67cSAndy Whitcroft } 351*8905a67cSAndy Whitcroft } 352*8905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 353*8905a67cSAndy Whitcroft $level++; 354*8905a67cSAndy Whitcroft $type = '{'; 355*8905a67cSAndy Whitcroft } 356*8905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 357*8905a67cSAndy Whitcroft $level--; 358*8905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 359*8905a67cSAndy Whitcroft 360*8905a67cSAndy Whitcroft if ($level == 0) { 361*8905a67cSAndy Whitcroft last; 362*8905a67cSAndy Whitcroft } 363*8905a67cSAndy Whitcroft } 364*8905a67cSAndy Whitcroft $off++; 365*8905a67cSAndy Whitcroft } 366*8905a67cSAndy Whitcroft 367*8905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 368*8905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 369*8905a67cSAndy Whitcroft 370*8905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 371*8905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 372*8905a67cSAndy Whitcroft 373*8905a67cSAndy Whitcroft return ($statement, $condition); 374*8905a67cSAndy Whitcroft} 375*8905a67cSAndy Whitcroft 3764a0df2efSAndy Whitcroftsub ctx_block_get { 377f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 3784a0df2efSAndy Whitcroft my $line; 3794a0df2efSAndy Whitcroft my $start = $linenr - 1; 3804a0df2efSAndy Whitcroft my $blk = ''; 3814a0df2efSAndy Whitcroft my @o; 3824a0df2efSAndy Whitcroft my @c; 3834a0df2efSAndy Whitcroft my @res = (); 3844a0df2efSAndy Whitcroft 385f0a594c1SAndy Whitcroft my $level = 0; 38600df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 38700df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 38800df344fSAndy Whitcroft $remain--; 38900df344fSAndy Whitcroft 39000df344fSAndy Whitcroft $blk .= $rawlines[$line]; 391f0a594c1SAndy Whitcroft foreach my $c (split(//, $rawlines[$line])) { 392f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 393f0a594c1SAndy Whitcroft if ($off > 0) { 394f0a594c1SAndy Whitcroft $off--; 395f0a594c1SAndy Whitcroft next; 396f0a594c1SAndy Whitcroft } 3974a0df2efSAndy Whitcroft 398f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 399f0a594c1SAndy Whitcroft $level--; 400f0a594c1SAndy Whitcroft last if ($level == 0); 401f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 402f0a594c1SAndy Whitcroft $level++; 403f0a594c1SAndy Whitcroft } 404f0a594c1SAndy Whitcroft } 4054a0df2efSAndy Whitcroft 406f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 40700df344fSAndy Whitcroft push(@res, $rawlines[$line]); 4084a0df2efSAndy Whitcroft } 4094a0df2efSAndy Whitcroft 410f0a594c1SAndy Whitcroft last if ($level == 0); 4114a0df2efSAndy Whitcroft } 4124a0df2efSAndy Whitcroft 413f0a594c1SAndy Whitcroft return ($level, @res); 4144a0df2efSAndy Whitcroft} 4154a0df2efSAndy Whitcroftsub ctx_block_outer { 4164a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 4174a0df2efSAndy Whitcroft 418f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 419f0a594c1SAndy Whitcroft return @r; 4204a0df2efSAndy Whitcroft} 4214a0df2efSAndy Whitcroftsub ctx_block { 4224a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 4234a0df2efSAndy Whitcroft 424f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 425f0a594c1SAndy Whitcroft return @r; 426653d4876SAndy Whitcroft} 427653d4876SAndy Whitcroftsub ctx_statement { 428f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 429f0a594c1SAndy Whitcroft 430f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 431f0a594c1SAndy Whitcroft return @r; 432f0a594c1SAndy Whitcroft} 433f0a594c1SAndy Whitcroftsub ctx_block_level { 434653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 435653d4876SAndy Whitcroft 436f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 4374a0df2efSAndy Whitcroft} 4389c0ca6f9SAndy Whitcroftsub ctx_statement_level { 4399c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 4409c0ca6f9SAndy Whitcroft 4419c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 4429c0ca6f9SAndy Whitcroft} 4434a0df2efSAndy Whitcroft 4444a0df2efSAndy Whitcroftsub ctx_locate_comment { 4454a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 4464a0df2efSAndy Whitcroft 4474a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 44800df344fSAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@); 4494a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 4504a0df2efSAndy Whitcroft 4514a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 4524a0df2efSAndy Whitcroft # comment. 4534a0df2efSAndy Whitcroft my $in_comment = 0; 4544a0df2efSAndy Whitcroft $current_comment = ''; 4554a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 45600df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 45700df344fSAndy Whitcroft #warn " $line\n"; 4584a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 4594a0df2efSAndy Whitcroft $in_comment = 1; 4604a0df2efSAndy Whitcroft } 4614a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 4624a0df2efSAndy Whitcroft $in_comment = 1; 4634a0df2efSAndy Whitcroft } 4644a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 4654a0df2efSAndy Whitcroft $current_comment = ''; 4664a0df2efSAndy Whitcroft } 4674a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 4684a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 4694a0df2efSAndy Whitcroft $in_comment = 0; 4704a0df2efSAndy Whitcroft } 4714a0df2efSAndy Whitcroft } 4724a0df2efSAndy Whitcroft 4734a0df2efSAndy Whitcroft chomp($current_comment); 4744a0df2efSAndy Whitcroft return($current_comment); 4754a0df2efSAndy Whitcroft} 4764a0df2efSAndy Whitcroftsub ctx_has_comment { 4774a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 4784a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 4794a0df2efSAndy Whitcroft 48000df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 4814a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 4824a0df2efSAndy Whitcroft 4834a0df2efSAndy Whitcroft return ($cmt ne ''); 4844a0df2efSAndy Whitcroft} 4854a0df2efSAndy Whitcroft 4860a920b5bSAndy Whitcroftsub cat_vet { 4870a920b5bSAndy Whitcroft my ($vet) = @_; 4889c0ca6f9SAndy Whitcroft my ($res, $coded); 4890a920b5bSAndy Whitcroft 4909c0ca6f9SAndy Whitcroft $res = ''; 4916c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 4926c72ffaaSAndy Whitcroft $res .= $1; 4936c72ffaaSAndy Whitcroft if ($2 ne '') { 4949c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 4956c72ffaaSAndy Whitcroft $res .= $coded; 4966c72ffaaSAndy Whitcroft } 4979c0ca6f9SAndy Whitcroft } 4989c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 4990a920b5bSAndy Whitcroft 5009c0ca6f9SAndy Whitcroft return $res; 5010a920b5bSAndy Whitcroft} 5020a920b5bSAndy Whitcroft 5036c72ffaaSAndy Whitcroftsub annotate_values { 5046c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 5056c72ffaaSAndy Whitcroft 5066c72ffaaSAndy Whitcroft my $res; 5076c72ffaaSAndy Whitcroft my $cur = $stream; 5086c72ffaaSAndy Whitcroft 5096c72ffaaSAndy Whitcroft my $debug = 0; 5106c72ffaaSAndy Whitcroft 5116c72ffaaSAndy Whitcroft print "$stream\n" if ($debug); 5126c72ffaaSAndy Whitcroft 5136c72ffaaSAndy Whitcroft ##my $type = 'N'; 5146c72ffaaSAndy Whitcroft my $pos = 0; 5156c72ffaaSAndy Whitcroft my $preprocessor = 0; 5166c72ffaaSAndy Whitcroft my $paren = 0; 5176c72ffaaSAndy Whitcroft my @paren_type; 5186c72ffaaSAndy Whitcroft 5196c72ffaaSAndy Whitcroft while (length($cur)) { 5206c72ffaaSAndy Whitcroft print " <$type> " if ($debug); 5216c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 5226c72ffaaSAndy Whitcroft print "WS($1)\n" if ($debug); 5236c72ffaaSAndy Whitcroft if ($1 =~ /\n/ && $preprocessor) { 5246c72ffaaSAndy Whitcroft $preprocessor = 0; 5256c72ffaaSAndy Whitcroft $type = 'N'; 5266c72ffaaSAndy Whitcroft } 5276c72ffaaSAndy Whitcroft 528*8905a67cSAndy Whitcroft } elsif ($cur =~ /^($Type)/) { 5296c72ffaaSAndy Whitcroft print "DECLARE($1)\n" if ($debug); 5306c72ffaaSAndy Whitcroft $type = 'T'; 5316c72ffaaSAndy Whitcroft 5326c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { 5336c72ffaaSAndy Whitcroft print "DEFINE($1)\n" if ($debug); 5346c72ffaaSAndy Whitcroft $preprocessor = 1; 5356c72ffaaSAndy Whitcroft $paren_type[$paren] = 'N'; 5366c72ffaaSAndy Whitcroft 5376c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) { 5386c72ffaaSAndy Whitcroft print "PRE($1)\n" if ($debug); 5396c72ffaaSAndy Whitcroft $preprocessor = 1; 5406c72ffaaSAndy Whitcroft $type = 'N'; 5416c72ffaaSAndy Whitcroft 5426c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 5436c72ffaaSAndy Whitcroft print "PRECONT($1)\n" if ($debug); 5446c72ffaaSAndy Whitcroft 5456c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 5466c72ffaaSAndy Whitcroft print "SIZEOF($1)\n" if ($debug); 5476c72ffaaSAndy Whitcroft if (defined $2) { 5486c72ffaaSAndy Whitcroft $paren_type[$paren] = 'V'; 5496c72ffaaSAndy Whitcroft } 5506c72ffaaSAndy Whitcroft $type = 'N'; 5516c72ffaaSAndy Whitcroft 552*8905a67cSAndy Whitcroft } elsif ($cur =~ /^(if|while|typeof|for)\b/o) { 5536c72ffaaSAndy Whitcroft print "COND($1)\n" if ($debug); 5546c72ffaaSAndy Whitcroft $paren_type[$paren] = 'N'; 5556c72ffaaSAndy Whitcroft $type = 'N'; 5566c72ffaaSAndy Whitcroft 5576c72ffaaSAndy Whitcroft } elsif ($cur =~/^(return|case|else)/o) { 5586c72ffaaSAndy Whitcroft print "KEYWORD($1)\n" if ($debug); 5596c72ffaaSAndy Whitcroft $type = 'N'; 5606c72ffaaSAndy Whitcroft 5616c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 5626c72ffaaSAndy Whitcroft print "PAREN('$1')\n" if ($debug); 5636c72ffaaSAndy Whitcroft $paren++; 5646c72ffaaSAndy Whitcroft $type = 'N'; 5656c72ffaaSAndy Whitcroft 5666c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 5676c72ffaaSAndy Whitcroft $paren-- if ($paren > 0); 5686c72ffaaSAndy Whitcroft if (defined $paren_type[$paren]) { 5696c72ffaaSAndy Whitcroft $type = $paren_type[$paren]; 5706c72ffaaSAndy Whitcroft undef $paren_type[$paren]; 5716c72ffaaSAndy Whitcroft print "PAREN('$1') -> $type\n" if ($debug); 5726c72ffaaSAndy Whitcroft } else { 5736c72ffaaSAndy Whitcroft print "PAREN('$1')\n" if ($debug); 5746c72ffaaSAndy Whitcroft } 5756c72ffaaSAndy Whitcroft 5766c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident)\(/o) { 5776c72ffaaSAndy Whitcroft print "FUNC($1)\n" if ($debug); 5786c72ffaaSAndy Whitcroft $paren_type[$paren] = 'V'; 5796c72ffaaSAndy Whitcroft 5806c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 5816c72ffaaSAndy Whitcroft print "IDENT($1)\n" if ($debug); 5826c72ffaaSAndy Whitcroft $type = 'V'; 5836c72ffaaSAndy Whitcroft 5846c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 5856c72ffaaSAndy Whitcroft print "ASSIGN($1)\n" if ($debug); 5866c72ffaaSAndy Whitcroft $type = 'N'; 5876c72ffaaSAndy Whitcroft 5886c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { 5896c72ffaaSAndy Whitcroft print "END($1)\n" if ($debug); 5906c72ffaaSAndy Whitcroft $type = 'N'; 5916c72ffaaSAndy Whitcroft 5926c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 5936c72ffaaSAndy Whitcroft print "OP($1)\n" if ($debug); 5946c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 5956c72ffaaSAndy Whitcroft $type = 'N'; 5966c72ffaaSAndy Whitcroft } 5976c72ffaaSAndy Whitcroft 5986c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 5996c72ffaaSAndy Whitcroft print "C($1)\n" if ($debug); 6006c72ffaaSAndy Whitcroft } 6016c72ffaaSAndy Whitcroft if (defined $1) { 6026c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 6036c72ffaaSAndy Whitcroft $res .= $type x length($1); 6046c72ffaaSAndy Whitcroft } 6056c72ffaaSAndy Whitcroft } 6066c72ffaaSAndy Whitcroft 6076c72ffaaSAndy Whitcroft return $res; 6086c72ffaaSAndy Whitcroft} 6096c72ffaaSAndy Whitcroft 610*8905a67cSAndy Whitcroftsub possible { 611*8905a67cSAndy Whitcroft my ($possible) = @_; 612*8905a67cSAndy Whitcroft 613*8905a67cSAndy Whitcroft #print "CHECK<$possible>\n"; 614*8905a67cSAndy Whitcroft if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && 615*8905a67cSAndy Whitcroft $possible ne 'goto' && $possible ne 'return' && 616*8905a67cSAndy Whitcroft $possible ne 'struct' && $possible ne 'enum' && 617*8905a67cSAndy Whitcroft $possible ne 'case' && $possible ne 'else' && 618*8905a67cSAndy Whitcroft $possible ne 'typedef') { 619*8905a67cSAndy Whitcroft #print "POSSIBLE<$possible>\n"; 620*8905a67cSAndy Whitcroft push(@typeList, $possible); 621*8905a67cSAndy Whitcroft build_types(); 622*8905a67cSAndy Whitcroft } 623*8905a67cSAndy Whitcroft} 624*8905a67cSAndy Whitcroft 6256c72ffaaSAndy Whitcroftmy $prefix = ''; 6266c72ffaaSAndy Whitcroft 627f0a594c1SAndy Whitcroftmy @report = (); 628f0a594c1SAndy Whitcroftsub report { 629*8905a67cSAndy Whitcroft my $line = $prefix . $_[0]; 630*8905a67cSAndy Whitcroft 631*8905a67cSAndy Whitcroft $line = (split('\n', $line))[0] . "\n" if ($terse); 632*8905a67cSAndy Whitcroft 633*8905a67cSAndy Whitcroft push(@report, $line); 634f0a594c1SAndy Whitcroft} 635f0a594c1SAndy Whitcroftsub report_dump { 636f0a594c1SAndy Whitcroft @report; 637f0a594c1SAndy Whitcroft} 638de7d4f0eSAndy Whitcroftsub ERROR { 639f0a594c1SAndy Whitcroft report("ERROR: $_[0]\n"); 640de7d4f0eSAndy Whitcroft our $clean = 0; 6416c72ffaaSAndy Whitcroft our $cnt_error++; 642de7d4f0eSAndy Whitcroft} 643de7d4f0eSAndy Whitcroftsub WARN { 644f0a594c1SAndy Whitcroft report("WARNING: $_[0]\n"); 645de7d4f0eSAndy Whitcroft our $clean = 0; 6466c72ffaaSAndy Whitcroft our $cnt_warn++; 647de7d4f0eSAndy Whitcroft} 648de7d4f0eSAndy Whitcroftsub CHK { 6496c72ffaaSAndy Whitcroft if ($check) { 650f0a594c1SAndy Whitcroft report("CHECK: $_[0]\n"); 651de7d4f0eSAndy Whitcroft our $clean = 0; 6526c72ffaaSAndy Whitcroft our $cnt_chk++; 6536c72ffaaSAndy Whitcroft } 654de7d4f0eSAndy Whitcroft} 655de7d4f0eSAndy Whitcroft 6560a920b5bSAndy Whitcroftsub process { 6570a920b5bSAndy Whitcroft my $filename = shift; 6580a920b5bSAndy Whitcroft my @lines = @_; 6590a920b5bSAndy Whitcroft 6600a920b5bSAndy Whitcroft my $linenr=0; 6610a920b5bSAndy Whitcroft my $prevline=""; 6620a920b5bSAndy Whitcroft my $stashline=""; 6630a920b5bSAndy Whitcroft 6644a0df2efSAndy Whitcroft my $length; 6650a920b5bSAndy Whitcroft my $indent; 6660a920b5bSAndy Whitcroft my $previndent=0; 6670a920b5bSAndy Whitcroft my $stashindent=0; 6680a920b5bSAndy Whitcroft 669de7d4f0eSAndy Whitcroft our $clean = 1; 6700a920b5bSAndy Whitcroft my $signoff = 0; 6710a920b5bSAndy Whitcroft my $is_patch = 0; 6720a920b5bSAndy Whitcroft 6736c72ffaaSAndy Whitcroft our $cnt_lines = 0; 6746c72ffaaSAndy Whitcroft our $cnt_error = 0; 6756c72ffaaSAndy Whitcroft our $cnt_warn = 0; 6766c72ffaaSAndy Whitcroft our $cnt_chk = 0; 6776c72ffaaSAndy Whitcroft 6780a920b5bSAndy Whitcroft # Trace the real file/line as we go. 6790a920b5bSAndy Whitcroft my $realfile = ''; 6800a920b5bSAndy Whitcroft my $realline = 0; 6810a920b5bSAndy Whitcroft my $realcnt = 0; 6820a920b5bSAndy Whitcroft my $here = ''; 6830a920b5bSAndy Whitcroft my $in_comment = 0; 6840a920b5bSAndy Whitcroft my $first_line = 0; 6850a920b5bSAndy Whitcroft 6866c72ffaaSAndy Whitcroft my $prev_values = 'N'; 687653d4876SAndy Whitcroft 688de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 689de7d4f0eSAndy Whitcroft my @setup_docs = (); 690de7d4f0eSAndy Whitcroft my $setup_docs = 0; 691de7d4f0eSAndy Whitcroft foreach my $line (@lines) { 692de7d4f0eSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 693de7d4f0eSAndy Whitcroft $setup_docs = 0; 694de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 695de7d4f0eSAndy Whitcroft $setup_docs = 1; 696de7d4f0eSAndy Whitcroft } 697de7d4f0eSAndy Whitcroft next; 698de7d4f0eSAndy Whitcroft } 699de7d4f0eSAndy Whitcroft 700de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 701de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 702de7d4f0eSAndy Whitcroft } 703de7d4f0eSAndy Whitcroft } 704de7d4f0eSAndy Whitcroft 7056c72ffaaSAndy Whitcroft $prefix = ''; 7066c72ffaaSAndy Whitcroft 7070a920b5bSAndy Whitcroft foreach my $line (@lines) { 7080a920b5bSAndy Whitcroft $linenr++; 7090a920b5bSAndy Whitcroft 710653d4876SAndy Whitcroft my $rawline = $line; 711653d4876SAndy Whitcroft 7126c72ffaaSAndy Whitcroft 7130a920b5bSAndy Whitcroft#extract the filename as it passes 7140a920b5bSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 7150a920b5bSAndy Whitcroft $realfile=$1; 71600df344fSAndy Whitcroft $realfile =~ s@^[^/]*/@@; 7170a920b5bSAndy Whitcroft $in_comment = 0; 7180a920b5bSAndy Whitcroft next; 7190a920b5bSAndy Whitcroft } 7200a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 7216c72ffaaSAndy Whitcroft if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 7220a920b5bSAndy Whitcroft $is_patch = 1; 7234a0df2efSAndy Whitcroft $first_line = $linenr + 1; 7240a920b5bSAndy Whitcroft $in_comment = 0; 7250a920b5bSAndy Whitcroft $realline=$1-1; 7260a920b5bSAndy Whitcroft if (defined $2) { 7270a920b5bSAndy Whitcroft $realcnt=$3+1; 7280a920b5bSAndy Whitcroft } else { 7290a920b5bSAndy Whitcroft $realcnt=1+1; 7300a920b5bSAndy Whitcroft } 7316c72ffaaSAndy Whitcroft $prev_values = 'N'; 7320a920b5bSAndy Whitcroft next; 7330a920b5bSAndy Whitcroft } 7340a920b5bSAndy Whitcroft 7354a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 7364a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 7374a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 7384a0df2efSAndy Whitcroft if ($line =~ /^( |\+|$)/) { 7390a920b5bSAndy Whitcroft $realline++; 740d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 7410a920b5bSAndy Whitcroft 742*8905a67cSAndy Whitcroft # Guestimate if this is a continuing comment. Run 743*8905a67cSAndy Whitcroft # the context looking for a comment "edge". If this 744*8905a67cSAndy Whitcroft # edge is a close comment then we must be in a comment 745*8905a67cSAndy Whitcroft # at context start. 746*8905a67cSAndy Whitcroft if ($linenr == $first_line) { 747*8905a67cSAndy Whitcroft my $edge; 748*8905a67cSAndy Whitcroft for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) { 749*8905a67cSAndy Whitcroft ($edge) = ($lines[$ln - 1] =~ m@(/\*|\*/)@); 750*8905a67cSAndy Whitcroft last if (defined $edge); 751*8905a67cSAndy Whitcroft } 752*8905a67cSAndy Whitcroft if (defined $edge && $edge eq '*/') { 753*8905a67cSAndy Whitcroft $in_comment = 1; 754*8905a67cSAndy Whitcroft } 755*8905a67cSAndy Whitcroft } 756*8905a67cSAndy Whitcroft 7570a920b5bSAndy Whitcroft # Guestimate if this is a continuing comment. If this 7580a920b5bSAndy Whitcroft # is the start of a diff block and this line starts 7590a920b5bSAndy Whitcroft # ' *' then it is very likely a comment. 7604a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 7610a920b5bSAndy Whitcroft $in_comment = 1; 7620a920b5bSAndy Whitcroft } 763*8905a67cSAndy Whitcroft 764*8905a67cSAndy Whitcroft # Find the last comment edge on _this_ line. 765*8905a67cSAndy Whitcroft while (($line =~ m@(/\*|\*/)@g)) { 766*8905a67cSAndy Whitcroft if ($1 eq '/*') { 7670a920b5bSAndy Whitcroft $in_comment = 1; 768*8905a67cSAndy Whitcroft } else { 7690a920b5bSAndy Whitcroft $in_comment = 0; 7700a920b5bSAndy Whitcroft } 771*8905a67cSAndy Whitcroft } 7720a920b5bSAndy Whitcroft 7734a0df2efSAndy Whitcroft # Measure the line length and indent. 7744a0df2efSAndy Whitcroft ($length, $indent) = line_stats($line); 7750a920b5bSAndy Whitcroft 7760a920b5bSAndy Whitcroft # Track the previous line. 7770a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 7780a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 7796c72ffaaSAndy Whitcroft 780d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 781d8aaf121SAndy Whitcroft $realcnt--; 7820a920b5bSAndy Whitcroft } 7830a920b5bSAndy Whitcroft 7840a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 7856c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 7866c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 787389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 7880a920b5bSAndy Whitcroft 78900df344fSAndy Whitcroft my $hereline = "$here\n$line\n"; 790de7d4f0eSAndy Whitcroft my $herecurr = "$here\n$line\n"; 791de7d4f0eSAndy Whitcroft my $hereprev = "$here\n$prevline\n$line\n"; 7920a920b5bSAndy Whitcroft 7936c72ffaaSAndy Whitcroft $prefix = "$filename:$realline: " if ($emacs && $file); 7946c72ffaaSAndy Whitcroft $prefix = "$filename:$linenr: " if ($emacs && !$file); 7956c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 7966c72ffaaSAndy Whitcroft 7970a920b5bSAndy Whitcroft#check the patch for a signoff: 798d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 7994a0df2efSAndy Whitcroft # This is a signoff, if ugly, so do not double report. 8004a0df2efSAndy Whitcroft $signoff++; 8010a920b5bSAndy Whitcroft if (!($line =~ /^\s*Signed-off-by:/)) { 802de7d4f0eSAndy Whitcroft WARN("Signed-off-by: is the preferred form\n" . 803de7d4f0eSAndy Whitcroft $herecurr); 8040a920b5bSAndy Whitcroft } 8050a920b5bSAndy Whitcroft if ($line =~ /^\s*signed-off-by:\S/i) { 806de7d4f0eSAndy Whitcroft WARN("need space after Signed-off-by:\n" . 807de7d4f0eSAndy Whitcroft $herecurr); 8080a920b5bSAndy Whitcroft } 8090a920b5bSAndy Whitcroft } 8100a920b5bSAndy Whitcroft 81100df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 812*8905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 813de7d4f0eSAndy Whitcroft ERROR("patch seems to be corrupt (line wrapped?)\n" . 8146c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 815de7d4f0eSAndy Whitcroft } 816de7d4f0eSAndy Whitcroft 817de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 818de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 819de7d4f0eSAndy Whitcroft !($line =~ m/^( 820de7d4f0eSAndy Whitcroft [\x09\x0A\x0D\x20-\x7E] # ASCII 821de7d4f0eSAndy Whitcroft | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 822de7d4f0eSAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 823de7d4f0eSAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 824de7d4f0eSAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 825de7d4f0eSAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 826de7d4f0eSAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 827de7d4f0eSAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 828de7d4f0eSAndy Whitcroft )*$/x )) { 829de7d4f0eSAndy Whitcroft ERROR("Invalid UTF-8\n" . $herecurr); 83000df344fSAndy Whitcroft } 8310a920b5bSAndy Whitcroft 83200df344fSAndy Whitcroft#ignore lines being removed 83300df344fSAndy Whitcroft if ($line=~/^-/) {next;} 83400df344fSAndy Whitcroft 83500df344fSAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 83600df344fSAndy Whitcroft next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 8370a920b5bSAndy Whitcroft 8380a920b5bSAndy Whitcroft#trailing whitespace 8399c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 8409c0ca6f9SAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 8419c0ca6f9SAndy Whitcroft ERROR("DOS line endings\n" . $herevet); 8429c0ca6f9SAndy Whitcroft 8439c0ca6f9SAndy Whitcroft } elsif ($line =~ /^\+.*\S\s+$/ || $line =~ /^\+\s+$/) { 844de7d4f0eSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 845de7d4f0eSAndy Whitcroft ERROR("trailing whitespace\n" . $herevet); 8460a920b5bSAndy Whitcroft } 8470a920b5bSAndy Whitcroft#80 column limit 84800df344fSAndy Whitcroft if ($line =~ /^\+/ && !($prevline=~/\/\*\*/) && $length > 80) { 849de7d4f0eSAndy Whitcroft WARN("line over 80 characters\n" . $herecurr); 8500a920b5bSAndy Whitcroft } 8510a920b5bSAndy Whitcroft 852*8905a67cSAndy Whitcroft# check for adding lines without a newline. 853*8905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 854*8905a67cSAndy Whitcroft WARN("adding a line without newline at end of file\n" . $herecurr); 855*8905a67cSAndy Whitcroft } 856*8905a67cSAndy Whitcroft 8570a920b5bSAndy Whitcroft# check we are in a valid source file *.[hc] if not then ignore this hunk 8580a920b5bSAndy Whitcroft next if ($realfile !~ /\.[hc]$/); 8590a920b5bSAndy Whitcroft 8600a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 8610a920b5bSAndy Whitcroft# more than 8 must use tabs. 8620a920b5bSAndy Whitcroft if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s* \s*/) { 863de7d4f0eSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 864de7d4f0eSAndy Whitcroft ERROR("use tabs not spaces\n" . $herevet); 8650a920b5bSAndy Whitcroft } 8660a920b5bSAndy Whitcroft 8670a920b5bSAndy Whitcroft# Remove comments from the line before processing. 86822f2a2efSAndy Whitcroft my $comment_edge = ($line =~ s@/\*.*\*/@@g) + 86922f2a2efSAndy Whitcroft ($line =~ s@/\*.*@@) + 87022f2a2efSAndy Whitcroft ($line =~ s@^(.).*\*/@$1@); 87122f2a2efSAndy Whitcroft 87222f2a2efSAndy Whitcroft# The rest of our checks refer specifically to C style 87322f2a2efSAndy Whitcroft# only apply those _outside_ comments. Only skip 87422f2a2efSAndy Whitcroft# lines in the middle of comments. 87522f2a2efSAndy Whitcroft next if (!$comment_edge && $in_comment); 87600df344fSAndy Whitcroft 877653d4876SAndy Whitcroft# Standardise the strings and chars within the input to simplify matching. 878653d4876SAndy Whitcroft $line = sanitise_line($line); 879653d4876SAndy Whitcroft 8809c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 8819c0ca6f9SAndy Whitcroft if ($realcnt && 8829c0ca6f9SAndy Whitcroft $line !~ /$Ident:\s*$/ && 883*8905a67cSAndy Whitcroft ($line =~ /^.\s*$Ident\s*\(\*+\s*$Ident\)\s*\(/ || 884*8905a67cSAndy Whitcroft $line !~ /^.\s*$Ident\s*\(/)) { 8856c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 886*8905a67cSAndy Whitcroft if ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { 887*8905a67cSAndy Whitcroft possible($1); 888*8905a67cSAndy Whitcroft 8896c72ffaaSAndy Whitcroft # declarations always start with types 890*8905a67cSAndy Whitcroft } elsif ($prev_values eq 'N' && $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) { 891*8905a67cSAndy Whitcroft possible($1); 892*8905a67cSAndy Whitcroft 8936c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 894*8905a67cSAndy Whitcroft } elsif ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) { 895*8905a67cSAndy Whitcroft possible($1); 8969c0ca6f9SAndy Whitcroft } 897*8905a67cSAndy Whitcroft 898*8905a67cSAndy Whitcroft # Check for any sort of function declaration. 899*8905a67cSAndy Whitcroft # int foo(something bar, other baz); 900*8905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 901*8905a67cSAndy Whitcroft if ($prev_values eq 'N' && $line =~ /^(.(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { 902*8905a67cSAndy Whitcroft my ($name_len) = length($1); 903*8905a67cSAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len); 904*8905a67cSAndy Whitcroft my $ctx = join("\n", @ctx); 905*8905a67cSAndy Whitcroft 906*8905a67cSAndy Whitcroft $ctx =~ s/\n.//; 907*8905a67cSAndy Whitcroft substr($ctx, 0, $name_len + 1) = ''; 908*8905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 909*8905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 910*8905a67cSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { 911*8905a67cSAndy Whitcroft 912*8905a67cSAndy Whitcroft possible($1); 913*8905a67cSAndy Whitcroft } 914*8905a67cSAndy Whitcroft } 915*8905a67cSAndy Whitcroft } 916*8905a67cSAndy Whitcroft 9179c0ca6f9SAndy Whitcroft } 9189c0ca6f9SAndy Whitcroft 91900df344fSAndy Whitcroft# 92000df344fSAndy Whitcroft# Checks which may be anchored in the context. 92100df344fSAndy Whitcroft# 92200df344fSAndy Whitcroft 92300df344fSAndy Whitcroft# Check for switch () and associated case and default 92400df344fSAndy Whitcroft# statements should be at the same indent. 92500df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 92600df344fSAndy Whitcroft my $err = ''; 92700df344fSAndy Whitcroft my $sep = ''; 92800df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 92900df344fSAndy Whitcroft shift(@ctx); 93000df344fSAndy Whitcroft for my $ctx (@ctx) { 93100df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 93200df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 93300df344fSAndy Whitcroft $indent != $cindent) { 93400df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 93500df344fSAndy Whitcroft $sep = ''; 93600df344fSAndy Whitcroft } else { 93700df344fSAndy Whitcroft $sep = "[...]\n"; 93800df344fSAndy Whitcroft } 93900df344fSAndy Whitcroft } 94000df344fSAndy Whitcroft if ($err ne '') { 9419c0ca6f9SAndy Whitcroft ERROR("switch and case should be at the same indent\n$hereline$err"); 942de7d4f0eSAndy Whitcroft } 943de7d4f0eSAndy Whitcroft } 944de7d4f0eSAndy Whitcroft 945de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 946de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 947de7d4f0eSAndy Whitcroft if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { 9489c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 949de7d4f0eSAndy Whitcroft my $ctx_ln = $linenr + $#ctx + 1; 950de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 951de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 952de7d4f0eSAndy Whitcroft 9539c0ca6f9SAndy Whitcroft # Skip over any removed lines in the context following statement. 954de7d4f0eSAndy Whitcroft while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) { 955de7d4f0eSAndy Whitcroft $ctx_ln++; 956de7d4f0eSAndy Whitcroft $ctx_cnt--; 957de7d4f0eSAndy Whitcroft } 958de7d4f0eSAndy Whitcroft ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>"; 959de7d4f0eSAndy Whitcroft 960de7d4f0eSAndy Whitcroft if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 961f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . 962de7d4f0eSAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 96300df344fSAndy Whitcroft } 9649c0ca6f9SAndy Whitcroft if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) { 9659c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 9669c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 9679c0ca6f9SAndy Whitcroft WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" . 9689c0ca6f9SAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 9699c0ca6f9SAndy Whitcroft } 9709c0ca6f9SAndy Whitcroft } 97100df344fSAndy Whitcroft } 97200df344fSAndy Whitcroft 9736c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 9746c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 9756c72ffaaSAndy Whitcroft my $curr_values = annotate_values($opline . "\n", $prev_values); 9766c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 9776c72ffaaSAndy Whitcroft #warn "--> $opline\n"; 9786c72ffaaSAndy Whitcroft #warn "--> $curr_values ($prev_values)\n"; 9796c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 9806c72ffaaSAndy Whitcroft 98100df344fSAndy Whitcroft#ignore lines not being added 98200df344fSAndy Whitcroft if ($line=~/^[^\+]/) {next;} 98300df344fSAndy Whitcroft 984653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 985653d4876SAndy Whitcroft if ($tst_type && $line =~ /^.$Declare$/) { 986de7d4f0eSAndy Whitcroft ERROR("TEST: is type $Declare\n" . $herecurr); 987653d4876SAndy Whitcroft next; 988653d4876SAndy Whitcroft } 989653d4876SAndy Whitcroft 990f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 991f0a594c1SAndy Whitcroft if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 992f0a594c1SAndy Whitcroft $line =~ /^.\s*{/) { 993f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . $hereprev); 994f0a594c1SAndy Whitcroft } 995f0a594c1SAndy Whitcroft 99600df344fSAndy Whitcroft# 99700df344fSAndy Whitcroft# Checks which are anchored on the added line. 99800df344fSAndy Whitcroft# 99900df344fSAndy Whitcroft 1000653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 1001653d4876SAndy Whitcroft if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { 1002653d4876SAndy Whitcroft my $path = $1; 1003653d4876SAndy Whitcroft if ($path =~ m{//}) { 1004de7d4f0eSAndy Whitcroft ERROR("malformed #include filename\n" . 1005de7d4f0eSAndy Whitcroft $herecurr); 1006653d4876SAndy Whitcroft } 1007653d4876SAndy Whitcroft # Sanitise this special form of string. 1008653d4876SAndy Whitcroft $path = 'X' x length($path); 1009653d4876SAndy Whitcroft $line =~ s{\<.*\>}{<$path>}; 1010653d4876SAndy Whitcroft } 1011653d4876SAndy Whitcroft 101200df344fSAndy Whitcroft# no C99 // comments 101300df344fSAndy Whitcroft if ($line =~ m{//}) { 1014de7d4f0eSAndy Whitcroft ERROR("do not use C99 // comments\n" . $herecurr); 101500df344fSAndy Whitcroft } 101600df344fSAndy Whitcroft # Remove C99 comments. 10170a920b5bSAndy Whitcroft $line =~ s@//.*@@; 10186c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 10190a920b5bSAndy Whitcroft 10200a920b5bSAndy Whitcroft#EXPORT_SYMBOL should immediately follow its function closing }. 1021653d4876SAndy Whitcroft if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 1022653d4876SAndy Whitcroft ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1023653d4876SAndy Whitcroft my $name = $1; 10240a920b5bSAndy Whitcroft if (($prevline !~ /^}/) && 10250a920b5bSAndy Whitcroft ($prevline !~ /^\+}/) && 1026653d4876SAndy Whitcroft ($prevline !~ /^ }/) && 102722f2a2efSAndy Whitcroft ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { 1028de7d4f0eSAndy Whitcroft WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 10290a920b5bSAndy Whitcroft } 10300a920b5bSAndy Whitcroft } 10310a920b5bSAndy Whitcroft 1032f0a594c1SAndy Whitcroft# check for external initialisers. 1033f0a594c1SAndy Whitcroft if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) { 1034f0a594c1SAndy Whitcroft ERROR("do not initialise externals to 0 or NULL\n" . 1035f0a594c1SAndy Whitcroft $herecurr); 1036f0a594c1SAndy Whitcroft } 10370a920b5bSAndy Whitcroft# check for static initialisers. 1038f0a594c1SAndy Whitcroft if ($line =~ /\s*static\s.*=\s*(0|NULL);/) { 1039de7d4f0eSAndy Whitcroft ERROR("do not initialise statics to 0 or NULL\n" . 1040de7d4f0eSAndy Whitcroft $herecurr); 10410a920b5bSAndy Whitcroft } 10420a920b5bSAndy Whitcroft 1043653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 1044653d4876SAndy Whitcroft# make sense. 1045653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 10469c0ca6f9SAndy Whitcroft $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && 1047653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 1048de7d4f0eSAndy Whitcroft WARN("do not add new typedefs\n" . $herecurr); 10490a920b5bSAndy Whitcroft } 10500a920b5bSAndy Whitcroft 10510a920b5bSAndy Whitcroft# * goes on variable not on type 1052d8aaf121SAndy Whitcroft if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) { 1053de7d4f0eSAndy Whitcroft ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" . 1054de7d4f0eSAndy Whitcroft $herecurr); 1055d8aaf121SAndy Whitcroft 1056d8aaf121SAndy Whitcroft } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) { 1057de7d4f0eSAndy Whitcroft ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" . 1058de7d4f0eSAndy Whitcroft $herecurr); 1059d8aaf121SAndy Whitcroft 10609c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) { 1061de7d4f0eSAndy Whitcroft ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" . 1062de7d4f0eSAndy Whitcroft $herecurr); 1063d8aaf121SAndy Whitcroft 10649c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) { 1065de7d4f0eSAndy Whitcroft ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" . 1066de7d4f0eSAndy Whitcroft $herecurr); 10670a920b5bSAndy Whitcroft } 10680a920b5bSAndy Whitcroft 10690a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 10700a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 10710a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 10720a920b5bSAndy Whitcroft# print "$herecurr"; 10730a920b5bSAndy Whitcroft# $clean = 0; 10740a920b5bSAndy Whitcroft# } 10750a920b5bSAndy Whitcroft 1076*8905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 1077*8905a67cSAndy Whitcroft WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged" . $herecurr); 1078*8905a67cSAndy Whitcroft } 1079*8905a67cSAndy Whitcroft 108000df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 108100df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 108200df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 108300df344fSAndy Whitcroft# printk includes all preceeding printk's which have no newline on the end. 108400df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 1085f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 108600df344fSAndy Whitcroft my $ok = 0; 108700df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 108800df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 108900df344fSAndy Whitcroft # we have a preceeding printk if it ends 109000df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 109100df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 109200df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 109300df344fSAndy Whitcroft $ok = 1; 109400df344fSAndy Whitcroft } 109500df344fSAndy Whitcroft last; 109600df344fSAndy Whitcroft } 109700df344fSAndy Whitcroft } 109800df344fSAndy Whitcroft if ($ok == 0) { 1099de7d4f0eSAndy Whitcroft WARN("printk() should include KERN_ facility level\n" . $herecurr); 11000a920b5bSAndy Whitcroft } 110100df344fSAndy Whitcroft } 11020a920b5bSAndy Whitcroft 1103653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 1104653d4876SAndy Whitcroft# or if closed on same line 1105d8aaf121SAndy Whitcroft if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).* {/) and 11060a920b5bSAndy Whitcroft !($line=~/\#define.*do\s{/) and !($line=~/}/)) { 1107de7d4f0eSAndy Whitcroft ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 11080a920b5bSAndy Whitcroft } 1109653d4876SAndy Whitcroft 1110*8905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 1111*8905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 1112*8905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 1113*8905a67cSAndy Whitcroft ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); 1114*8905a67cSAndy Whitcroft } 1115*8905a67cSAndy Whitcroft 1116f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 11176c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 11186c72ffaaSAndy Whitcroft if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ && 1119f0a594c1SAndy Whitcroft $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { 112022f2a2efSAndy Whitcroft WARN("no space between function name and open parenthesis '('\n" . $herecurr); 1121f0a594c1SAndy Whitcroft } 11226c72ffaaSAndy Whitcroft } 1123653d4876SAndy Whitcroft# Check operator spacing. 11240a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 11259c0ca6f9SAndy Whitcroft my $ops = qr{ 11269c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 11279c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 11289c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 11299c0ca6f9SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ 11309c0ca6f9SAndy Whitcroft }x; 11319c0ca6f9SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 113200df344fSAndy Whitcroft my $off = 0; 11336c72ffaaSAndy Whitcroft 11346c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 11356c72ffaaSAndy Whitcroft 11360a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 11374a0df2efSAndy Whitcroft $off += length($elements[$n]); 11384a0df2efSAndy Whitcroft 11394a0df2efSAndy Whitcroft my $a = ''; 11404a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 11414a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 11424a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 11434a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 11444a0df2efSAndy Whitcroft $a = 'E' if ($elements[$n] eq '' && $n == 0); 11454a0df2efSAndy Whitcroft 11460a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 11474a0df2efSAndy Whitcroft 11484a0df2efSAndy Whitcroft my $c = ''; 11490a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 11504a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 11514a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 11524a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 11534a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 115422f2a2efSAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); 11554a0df2efSAndy Whitcroft } else { 11564a0df2efSAndy Whitcroft $c = 'E'; 11570a920b5bSAndy Whitcroft } 11580a920b5bSAndy Whitcroft 115900df344fSAndy Whitcroft # Pick up the preceeding and succeeding characters. 1160de7d4f0eSAndy Whitcroft my $ca = substr($opline, 0, $off); 116100df344fSAndy Whitcroft my $cc = ''; 1162653d4876SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 1163d8aaf121SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 116400df344fSAndy Whitcroft } 1165de7d4f0eSAndy Whitcroft my $cb = "$ca$;$cc"; 116600df344fSAndy Whitcroft 11674a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 11684a0df2efSAndy Whitcroft 11694a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 11704a0df2efSAndy Whitcroft 11716c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 1172de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 11730a920b5bSAndy Whitcroft 11749c0ca6f9SAndy Whitcroft # Classify operators into binary, unary, or 11759c0ca6f9SAndy Whitcroft # definitions (* only) where they have more 11769c0ca6f9SAndy Whitcroft # than one mode. 11776c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 11786c72ffaaSAndy Whitcroft my $op_left = substr($curr_values, $off, 1); 11796c72ffaaSAndy Whitcroft my $is_unary; 11806c72ffaaSAndy Whitcroft if ($op_type eq 'T') { 11819c0ca6f9SAndy Whitcroft $is_unary = 2; 11826c72ffaaSAndy Whitcroft } elsif ($op_left eq 'V') { 11836c72ffaaSAndy Whitcroft $is_unary = 0; 11846c72ffaaSAndy Whitcroft } else { 11856c72ffaaSAndy Whitcroft $is_unary = 1; 11869c0ca6f9SAndy Whitcroft } 11879c0ca6f9SAndy Whitcroft #if ($op eq '-' || $op eq '&' || $op eq '*') { 11886c72ffaaSAndy Whitcroft # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; 11899c0ca6f9SAndy Whitcroft #} 11900a920b5bSAndy Whitcroft 1191d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 1192d8aaf121SAndy Whitcroft if ($op eq ';') { 1193de7d4f0eSAndy Whitcroft if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && 1194de7d4f0eSAndy Whitcroft $cc !~ /^;/) { 1195de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 1196d8aaf121SAndy Whitcroft } 1197d8aaf121SAndy Whitcroft 1198d8aaf121SAndy Whitcroft # // is a comment 1199d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 12000a920b5bSAndy Whitcroft 12010a920b5bSAndy Whitcroft # -> should have no spaces 12020a920b5bSAndy Whitcroft } elsif ($op eq '->') { 12034a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 1204de7d4f0eSAndy Whitcroft ERROR("no spaces around that '$op' $at\n" . $hereptr); 12050a920b5bSAndy Whitcroft } 12060a920b5bSAndy Whitcroft 12070a920b5bSAndy Whitcroft # , must have a space on the right. 12080a920b5bSAndy Whitcroft } elsif ($op eq ',') { 1209d8aaf121SAndy Whitcroft if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { 1210de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 12110a920b5bSAndy Whitcroft } 12120a920b5bSAndy Whitcroft 12139c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 12149c0ca6f9SAndy Whitcroft } elsif ($op eq '*' && $is_unary == 2) { 12159c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 12169c0ca6f9SAndy Whitcroft 12179c0ca6f9SAndy Whitcroft # unary operators should have a space before and 12189c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 12199c0ca6f9SAndy Whitcroft # unary operator, or a cast 12209c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 12219c0ca6f9SAndy Whitcroft ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { 12229c0ca6f9SAndy Whitcroft if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 1223de7d4f0eSAndy Whitcroft ERROR("need space before that '$op' $at\n" . $hereptr); 12240a920b5bSAndy Whitcroft } 12254a0df2efSAndy Whitcroft if ($ctx =~ /.xW/) { 1226de7d4f0eSAndy Whitcroft ERROR("no space after that '$op' $at\n" . $hereptr); 12270a920b5bSAndy Whitcroft } 12280a920b5bSAndy Whitcroft 12290a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 12300a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 1231d8aaf121SAndy Whitcroft if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { 1232de7d4f0eSAndy Whitcroft ERROR("need space one side of that '$op' $at\n" . $hereptr); 12330a920b5bSAndy Whitcroft } 1234d8aaf121SAndy Whitcroft if ($ctx =~ /Wx./ && $cc =~ /^;/) { 1235de7d4f0eSAndy Whitcroft ERROR("no space before that '$op' $at\n" . $hereptr); 1236653d4876SAndy Whitcroft } 12370a920b5bSAndy Whitcroft 12380a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 12399c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 12409c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 12419c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 12429c0ca6f9SAndy Whitcroft $op eq '*' or $op eq '/') 12430a920b5bSAndy Whitcroft { 12449c0ca6f9SAndy Whitcroft if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) { 1245de7d4f0eSAndy Whitcroft ERROR("need consistent spacing around '$op' $at\n" . 1246de7d4f0eSAndy Whitcroft $hereptr); 12470a920b5bSAndy Whitcroft } 12480a920b5bSAndy Whitcroft 12490a920b5bSAndy Whitcroft # All the others need spaces both sides. 12504a0df2efSAndy Whitcroft } elsif ($ctx !~ /[EW]x[WE]/) { 125122f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 125222f2a2efSAndy Whitcroft if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && 125322f2a2efSAndy Whitcroft !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { 1254de7d4f0eSAndy Whitcroft ERROR("need spaces around that '$op' $at\n" . $hereptr); 12550a920b5bSAndy Whitcroft } 125622f2a2efSAndy Whitcroft } 12574a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 12580a920b5bSAndy Whitcroft } 12590a920b5bSAndy Whitcroft } 12600a920b5bSAndy Whitcroft 1261f0a594c1SAndy Whitcroft# check for multiple assignments 1262f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 12636c72ffaaSAndy Whitcroft CHK("multiple assignments should be avoided\n" . $herecurr); 1264f0a594c1SAndy Whitcroft } 1265f0a594c1SAndy Whitcroft 126622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 126722f2a2efSAndy Whitcroft## # continuation. 126822f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 126922f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 127022f2a2efSAndy Whitcroft## 127122f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 127222f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 127322f2a2efSAndy Whitcroft## my $ln = $line; 127422f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 127522f2a2efSAndy Whitcroft## } 127622f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 127722f2a2efSAndy Whitcroft## WARN("declaring multiple variables together should be avoided\n" . $herecurr); 127822f2a2efSAndy Whitcroft## } 127922f2a2efSAndy Whitcroft## } 1280f0a594c1SAndy Whitcroft 12810a920b5bSAndy Whitcroft#need space before brace following if, while, etc 128222f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 128322f2a2efSAndy Whitcroft $line =~ /do{/) { 1284de7d4f0eSAndy Whitcroft ERROR("need a space before the open brace '{'\n" . $herecurr); 1285de7d4f0eSAndy Whitcroft } 1286de7d4f0eSAndy Whitcroft 1287de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 1288de7d4f0eSAndy Whitcroft# on the line 1289de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 1290de7d4f0eSAndy Whitcroft ERROR("need a space after that close brace '}'\n" . $herecurr); 12910a920b5bSAndy Whitcroft } 12920a920b5bSAndy Whitcroft 129322f2a2efSAndy Whitcroft# check spacing on square brackets 129422f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 129522f2a2efSAndy Whitcroft ERROR("no space after that open square bracket '['\n" . $herecurr); 129622f2a2efSAndy Whitcroft } 129722f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 129822f2a2efSAndy Whitcroft ERROR("no space before that close square bracket ']'\n" . $herecurr); 129922f2a2efSAndy Whitcroft } 130022f2a2efSAndy Whitcroft 130122f2a2efSAndy Whitcroft# check spacing on paretheses 13029c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 13039c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 130422f2a2efSAndy Whitcroft ERROR("no space after that open parenthesis '('\n" . $herecurr); 130522f2a2efSAndy Whitcroft } 13069c0ca6f9SAndy Whitcroft if ($line =~ /\s\)/ && $line !~ /^.\s*\)/ && 13079c0ca6f9SAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/) { 130822f2a2efSAndy Whitcroft ERROR("no space before that close parenthesis ')'\n" . $herecurr); 130922f2a2efSAndy Whitcroft } 131022f2a2efSAndy Whitcroft 13110a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 13124a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 13130a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 1314de7d4f0eSAndy Whitcroft WARN("labels should not be indented\n" . $herecurr); 13150a920b5bSAndy Whitcroft } 13160a920b5bSAndy Whitcroft 13170a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 13184a0df2efSAndy Whitcroft if ($line=~/\b(if|while|for|switch)\(/) { 1319de7d4f0eSAndy Whitcroft ERROR("need a space before the open parenthesis '('\n" . $herecurr); 13200a920b5bSAndy Whitcroft } 13210a920b5bSAndy Whitcroft 13220a920b5bSAndy Whitcroft# Check for illegal assignment in if conditional. 1323*8905a67cSAndy Whitcroft if ($line =~ /\bif\s*\(/) { 1324*8905a67cSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 1325*8905a67cSAndy Whitcroft 1326*8905a67cSAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) { 1327*8905a67cSAndy Whitcroft ERROR("do not use assignment in if condition ($c)\n" . $herecurr); 1328*8905a67cSAndy Whitcroft } 1329*8905a67cSAndy Whitcroft 1330*8905a67cSAndy Whitcroft # Find out what is on the end of the line after the 1331*8905a67cSAndy Whitcroft # conditional. 1332*8905a67cSAndy Whitcroft substr($s, 0, length($c)) = ''; 1333*8905a67cSAndy Whitcroft $s =~ s/\n.*//g; 1334*8905a67cSAndy Whitcroft 1335*8905a67cSAndy Whitcroft if (length($c) && $s !~ /^\s*({|;|\/\*.*\*\/)?\s*\\*\s*$/) { 1336*8905a67cSAndy Whitcroft ERROR("trailing statements should be on next line\n" . $herecurr); 1337*8905a67cSAndy Whitcroft } 1338*8905a67cSAndy Whitcroft } 1339*8905a67cSAndy Whitcroft 1340*8905a67cSAndy Whitcroft# if and else should not have general statements after it 1341*8905a67cSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ && 1342*8905a67cSAndy Whitcroft $1 !~ /^\s*(?:\sif|{|\\|$)/) { 1343*8905a67cSAndy Whitcroft ERROR("trailing statements should be on next line\n" . $herecurr); 13440a920b5bSAndy Whitcroft } 13450a920b5bSAndy Whitcroft 13460a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 13470a920b5bSAndy Whitcroft # indent level to be relevant to each other. 13480a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 13490a920b5bSAndy Whitcroft $previndent == $indent) { 1350de7d4f0eSAndy Whitcroft ERROR("else should follow close brace '}'\n" . $hereprev); 13510a920b5bSAndy Whitcroft } 13520a920b5bSAndy Whitcroft 13530a920b5bSAndy Whitcroft#studly caps, commented out until figure out how to distinguish between use of existing and adding new 13540a920b5bSAndy Whitcroft# if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { 13550a920b5bSAndy Whitcroft# print "No studly caps, use _\n"; 13560a920b5bSAndy Whitcroft# print "$herecurr"; 13570a920b5bSAndy Whitcroft# $clean = 0; 13580a920b5bSAndy Whitcroft# } 13590a920b5bSAndy Whitcroft 13600a920b5bSAndy Whitcroft#no spaces allowed after \ in define 13610a920b5bSAndy Whitcroft if ($line=~/\#define.*\\\s$/) { 1362de7d4f0eSAndy Whitcroft WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); 13630a920b5bSAndy Whitcroft } 13640a920b5bSAndy Whitcroft 1365653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 1366653d4876SAndy Whitcroft if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { 13676c72ffaaSAndy Whitcroft my $checkfile = "$root/include/linux/$1.h"; 13686c72ffaaSAndy Whitcroft if (-f $checkfile && $1 ne 'irq.h') { 1369de7d4f0eSAndy Whitcroft CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . 1370de7d4f0eSAndy Whitcroft $herecurr); 13710a920b5bSAndy Whitcroft } 13720a920b5bSAndy Whitcroft } 13730a920b5bSAndy Whitcroft 1374653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 1375653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 1376653d4876SAndy Whitcroft# in a known goot container 13779c0ca6f9SAndy Whitcroft if ($prevline =~ /\#define.*\\/ && 13789c0ca6f9SAndy Whitcroft $prevline !~/(?:do\s+{|\(\{|\{)/ && 13799c0ca6f9SAndy Whitcroft $line !~ /(?:do\s+{|\(\{|\{)/ && 13809c0ca6f9SAndy Whitcroft $line !~ /^.\s*$Declare\s/) { 1381653d4876SAndy Whitcroft # Grab the first statement, if that is the entire macro 1382653d4876SAndy Whitcroft # its ok. This may start either on the #define line 1383653d4876SAndy Whitcroft # or the one below. 1384d8aaf121SAndy Whitcroft my $ln = $linenr; 1385d8aaf121SAndy Whitcroft my $cnt = $realcnt; 1386f0a594c1SAndy Whitcroft my $off = 0; 1387653d4876SAndy Whitcroft 1388f0a594c1SAndy Whitcroft # If the macro starts on the define line start 1389f0a594c1SAndy Whitcroft # grabbing the statement after the identifier 1390f0a594c1SAndy Whitcroft $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; 1391f0a594c1SAndy Whitcroft ##print "1<$1> 2<$2>\n"; 139222f2a2efSAndy Whitcroft if (defined $2 && $2 ne '') { 1393f0a594c1SAndy Whitcroft $off = length($1); 1394d8aaf121SAndy Whitcroft $ln--; 1395d8aaf121SAndy Whitcroft $cnt++; 1396*8905a67cSAndy Whitcroft while ($lines[$ln - 1] =~ /^-/) { 1397*8905a67cSAndy Whitcroft $ln--; 1398*8905a67cSAndy Whitcroft $cnt++; 1399*8905a67cSAndy Whitcroft } 1400d8aaf121SAndy Whitcroft } 1401f0a594c1SAndy Whitcroft my @ctx = ctx_statement($ln, $cnt, $off); 1402de7d4f0eSAndy Whitcroft my $ctx_ln = $ln + $#ctx + 1; 1403de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 1404de7d4f0eSAndy Whitcroft 1405de7d4f0eSAndy Whitcroft # Pull in any empty extension lines. 1406de7d4f0eSAndy Whitcroft while ($ctx =~ /\\$/ && 1407de7d4f0eSAndy Whitcroft $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { 1408de7d4f0eSAndy Whitcroft $ctx .= $lines[$ctx_ln - 1]; 1409de7d4f0eSAndy Whitcroft $ctx_ln++; 1410de7d4f0eSAndy Whitcroft } 1411d8aaf121SAndy Whitcroft 1412d8aaf121SAndy Whitcroft if ($ctx =~ /\\$/) { 1413d8aaf121SAndy Whitcroft if ($ctx =~ /;/) { 1414de7d4f0eSAndy Whitcroft ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 1415d8aaf121SAndy Whitcroft } else { 1416de7d4f0eSAndy Whitcroft ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 1417d8aaf121SAndy Whitcroft } 14180a920b5bSAndy Whitcroft } 1419653d4876SAndy Whitcroft } 14200a920b5bSAndy Whitcroft 1421f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 1422f0a594c1SAndy Whitcroft if ($line =~ /\b(if|while|for|else)\b/) { 1423f0a594c1SAndy Whitcroft # Locate the end of the opening statement. 1424f0a594c1SAndy Whitcroft my @control = ctx_statement($linenr, $realcnt, 0); 1425f0a594c1SAndy Whitcroft my $nr = $linenr + (scalar(@control) - 1); 1426f0a594c1SAndy Whitcroft my $cnt = $realcnt - (scalar(@control) - 1); 1427f0a594c1SAndy Whitcroft 1428f0a594c1SAndy Whitcroft my $off = $realcnt - $cnt; 1429f0a594c1SAndy Whitcroft #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; 1430f0a594c1SAndy Whitcroft 1431f0a594c1SAndy Whitcroft # If this is is a braced statement group check it 1432f0a594c1SAndy Whitcroft if ($lines[$nr - 1] =~ /{\s*$/) { 1433f0a594c1SAndy Whitcroft my ($lvl, @block) = ctx_block_level($nr, $cnt); 1434f0a594c1SAndy Whitcroft 1435*8905a67cSAndy Whitcroft my $stmt = join("\n", @block); 1436*8905a67cSAndy Whitcroft # Drop the diff line leader. 1437*8905a67cSAndy Whitcroft $stmt =~ s/\n./\n/g; 1438*8905a67cSAndy Whitcroft # Drop the code outside the block. 1439*8905a67cSAndy Whitcroft $stmt =~ s/(^[^{]*){\s*//; 144022f2a2efSAndy Whitcroft my $before = $1; 1441*8905a67cSAndy Whitcroft $stmt =~ s/\s*}([^}]*$)//; 144222f2a2efSAndy Whitcroft my $after = $1; 1443f0a594c1SAndy Whitcroft 1444f0a594c1SAndy Whitcroft #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; 1445f0a594c1SAndy Whitcroft #print "stmt<$stmt>\n\n"; 1446f0a594c1SAndy Whitcroft 1447*8905a67cSAndy Whitcroft # Count the newlines, if there is only one 1448*8905a67cSAndy Whitcroft # then the block should not have {}'s. 1449*8905a67cSAndy Whitcroft my @lines = ($stmt =~ /\n/g); 1450*8905a67cSAndy Whitcroft #print "lines<" . scalar(@lines) . ">\n"; 1451*8905a67cSAndy Whitcroft if ($lvl == 0 && scalar(@lines) == 0 && 145222f2a2efSAndy Whitcroft $stmt !~ /{/ && $stmt !~ /\bif\b/ && 145322f2a2efSAndy Whitcroft $before !~ /}/ && $after !~ /{/) { 1454f0a594c1SAndy Whitcroft my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; 1455f0a594c1SAndy Whitcroft shift(@block); 145622f2a2efSAndy Whitcroft WARN("braces {} are not necessary for single statement blocks\n" . $herectx); 1457f0a594c1SAndy Whitcroft } 1458f0a594c1SAndy Whitcroft } 1459f0a594c1SAndy Whitcroft } 1460f0a594c1SAndy Whitcroft 1461653d4876SAndy Whitcroft# don't include deprecated include files (uses RAW line) 14624a0df2efSAndy Whitcroft for my $inc (@dep_includes) { 1463653d4876SAndy Whitcroft if ($rawline =~ m@\#\s*include\s*\<$inc>@) { 1464de7d4f0eSAndy Whitcroft ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); 14650a920b5bSAndy Whitcroft } 14660a920b5bSAndy Whitcroft } 14670a920b5bSAndy Whitcroft 14684a0df2efSAndy Whitcroft# don't use deprecated functions 14694a0df2efSAndy Whitcroft for my $func (@dep_functions) { 147000df344fSAndy Whitcroft if ($line =~ /\b$func\b/) { 1471de7d4f0eSAndy Whitcroft ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); 14724a0df2efSAndy Whitcroft } 14734a0df2efSAndy Whitcroft } 14744a0df2efSAndy Whitcroft 14754a0df2efSAndy Whitcroft# no volatiles please 14766c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 14776c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 1478de7d4f0eSAndy Whitcroft WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 14794a0df2efSAndy Whitcroft } 14804a0df2efSAndy Whitcroft 14819c0ca6f9SAndy Whitcroft# SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated 14829c0ca6f9SAndy Whitcroft if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) { 14839c0ca6f9SAndy Whitcroft ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr); 14849c0ca6f9SAndy Whitcroft } 14859c0ca6f9SAndy Whitcroft 148600df344fSAndy Whitcroft# warn about #if 0 148700df344fSAndy Whitcroft if ($line =~ /^.#\s*if\s+0\b/) { 1488de7d4f0eSAndy Whitcroft CHK("if this code is redundant consider removing it\n" . 1489de7d4f0eSAndy Whitcroft $herecurr); 14904a0df2efSAndy Whitcroft } 14914a0df2efSAndy Whitcroft 1492f0a594c1SAndy Whitcroft# check for needless kfree() checks 1493f0a594c1SAndy Whitcroft if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { 1494f0a594c1SAndy Whitcroft my $expr = $1; 1495f0a594c1SAndy Whitcroft if ($line =~ /\bkfree\(\Q$expr\E\);/) { 1496f0a594c1SAndy Whitcroft WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev); 1497f0a594c1SAndy Whitcroft } 1498f0a594c1SAndy Whitcroft } 1499f0a594c1SAndy Whitcroft 150000df344fSAndy Whitcroft# warn about #ifdefs in C files 150100df344fSAndy Whitcroft# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 150200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 150300df344fSAndy Whitcroft# print "$herecurr"; 150400df344fSAndy Whitcroft# $clean = 0; 150500df344fSAndy Whitcroft# } 150600df344fSAndy Whitcroft 150722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 150822f2a2efSAndy Whitcroft if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { 150922f2a2efSAndy Whitcroft ERROR("exactly one space required after that #$1\n" . $herecurr); 151022f2a2efSAndy Whitcroft } 151122f2a2efSAndy Whitcroft 15124a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 15134a0df2efSAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { 15144a0df2efSAndy Whitcroft my $which = $1; 15154a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1516de7d4f0eSAndy Whitcroft CHK("$1 definition without comment\n" . $herecurr); 15174a0df2efSAndy Whitcroft } 15184a0df2efSAndy Whitcroft } 15194a0df2efSAndy Whitcroft# check for memory barriers without a comment. 15204a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 15214a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1522de7d4f0eSAndy Whitcroft CHK("memory barrier without comment\n" . $herecurr); 15234a0df2efSAndy Whitcroft } 15244a0df2efSAndy Whitcroft } 15254a0df2efSAndy Whitcroft# check of hardware specific defines 152622f2a2efSAndy Whitcroft if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 1527de7d4f0eSAndy Whitcroft CHK("architecture specific defines should be avoided\n" . $herecurr); 15280a920b5bSAndy Whitcroft } 1529653d4876SAndy Whitcroft 1530de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 1531de7d4f0eSAndy Whitcroft# storage class and type. 15329c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 15339c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 1534de7d4f0eSAndy Whitcroft ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 1535de7d4f0eSAndy Whitcroft } 1536de7d4f0eSAndy Whitcroft 1537*8905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 1538*8905a67cSAndy Whitcroft if ($line =~ /\b(__inline__|__inline)\b/) { 1539*8905a67cSAndy Whitcroft WARN("plain inline is preferred over $1\n" . $herecurr); 1540*8905a67cSAndy Whitcroft } 1541*8905a67cSAndy Whitcroft 1542de7d4f0eSAndy Whitcroft# check for new externs in .c files. 1543de7d4f0eSAndy Whitcroft if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { 1544de7d4f0eSAndy Whitcroft WARN("externs should be avoided in .c files\n" . $herecurr); 1545de7d4f0eSAndy Whitcroft } 1546de7d4f0eSAndy Whitcroft 1547de7d4f0eSAndy Whitcroft# checks for new __setup's 1548de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 1549de7d4f0eSAndy Whitcroft my $name = $1; 1550de7d4f0eSAndy Whitcroft 1551de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 1552de7d4f0eSAndy Whitcroft CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 1553de7d4f0eSAndy Whitcroft } 1554653d4876SAndy Whitcroft } 15559c0ca6f9SAndy Whitcroft 15569c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 15579c0ca6f9SAndy Whitcroft if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) { 15589c0ca6f9SAndy Whitcroft WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 15599c0ca6f9SAndy Whitcroft } 15600a920b5bSAndy Whitcroft } 15610a920b5bSAndy Whitcroft 1562*8905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 1563*8905a67cSAndy Whitcroft # things that appear to be patches. 1564*8905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 1565*8905a67cSAndy Whitcroft exit(0); 1566*8905a67cSAndy Whitcroft } 1567*8905a67cSAndy Whitcroft 1568*8905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 1569*8905a67cSAndy Whitcroft # just keep quiet. 1570*8905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 1571*8905a67cSAndy Whitcroft exit(0); 1572*8905a67cSAndy Whitcroft } 1573*8905a67cSAndy Whitcroft 1574*8905a67cSAndy Whitcroft if (!$is_patch) { 1575de7d4f0eSAndy Whitcroft ERROR("Does not appear to be a unified-diff format patch\n"); 15760a920b5bSAndy Whitcroft } 15770a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 1578de7d4f0eSAndy Whitcroft ERROR("Missing Signed-off-by: line(s)\n"); 15790a920b5bSAndy Whitcroft } 15800a920b5bSAndy Whitcroft 1581f0a594c1SAndy Whitcroft print report_dump(); 1582*8905a67cSAndy Whitcroft if ($summary) { 15836c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 15846c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 15856c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 1586*8905a67cSAndy Whitcroft print "\n" if ($quiet == 0); 15876c72ffaaSAndy Whitcroft } 1588*8905a67cSAndy Whitcroft 15890a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 15900a920b5bSAndy Whitcroft print "Your patch has no obvious style problems and is ready for submission.\n" 15910a920b5bSAndy Whitcroft } 15920a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 15930a920b5bSAndy Whitcroft print "Your patch has style problems, please review. If any of these errors\n"; 15940a920b5bSAndy Whitcroft print "are false positives report them to the maintainer, see\n"; 15950a920b5bSAndy Whitcroft print "CHECKPATCH in MAINTAINERS.\n"; 15960a920b5bSAndy Whitcroft } 15970a920b5bSAndy Whitcroft return $clean; 15980a920b5bSAndy Whitcroft} 1599