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*9c0ca6f9SAndy Whitcroftmy $V = '0.10'; 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; 210a920b5bSAndy WhitcroftGetOptions( 220a920b5bSAndy Whitcroft 'q|quiet' => \$quiet, 230a920b5bSAndy Whitcroft 'tree!' => \$tree, 240a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 250a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 26653d4876SAndy Whitcroft 'test-type!' => \$tst_type, 270a920b5bSAndy Whitcroft) or exit; 280a920b5bSAndy Whitcroft 290a920b5bSAndy Whitcroftmy $exit = 0; 300a920b5bSAndy Whitcroft 310a920b5bSAndy Whitcroftif ($#ARGV < 0) { 3200df344fSAndy Whitcroft print "usage: $P [options] patchfile\n"; 330a920b5bSAndy Whitcroft print "version: $V\n"; 340a920b5bSAndy Whitcroft print "options: -q => quiet\n"; 350a920b5bSAndy Whitcroft print " --no-tree => run without a kernel tree\n"; 360a920b5bSAndy Whitcroft exit(1); 370a920b5bSAndy Whitcroft} 380a920b5bSAndy Whitcroft 390a920b5bSAndy Whitcroftif ($tree && !top_of_kernel_tree()) { 400a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 410a920b5bSAndy Whitcroft exit(2); 420a920b5bSAndy Whitcroft} 430a920b5bSAndy Whitcroft 444a0df2efSAndy Whitcroftmy @dep_includes = (); 454a0df2efSAndy Whitcroftmy @dep_functions = (); 460a920b5bSAndy Whitcroftmy $removal = 'Documentation/feature-removal-schedule.txt'; 470a920b5bSAndy Whitcroftif ($tree && -f $removal) { 480a920b5bSAndy Whitcroft open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; 490a920b5bSAndy Whitcroft while (<REMOVE>) { 50f0a594c1SAndy Whitcroft if (/^Check:\s+(.*\S)/) { 51f0a594c1SAndy Whitcroft for my $entry (split(/[, ]+/, $1)) { 52f0a594c1SAndy Whitcroft if ($entry =~ m@include/(.*)@) { 534a0df2efSAndy Whitcroft push(@dep_includes, $1); 544a0df2efSAndy Whitcroft 55f0a594c1SAndy Whitcroft } elsif ($entry !~ m@/@) { 56f0a594c1SAndy Whitcroft push(@dep_functions, $entry); 57f0a594c1SAndy Whitcroft } 584a0df2efSAndy Whitcroft } 590a920b5bSAndy Whitcroft } 600a920b5bSAndy Whitcroft } 610a920b5bSAndy Whitcroft} 620a920b5bSAndy Whitcroft 6300df344fSAndy Whitcroftmy @rawlines = (); 640a920b5bSAndy Whitcroftwhile (<>) { 650a920b5bSAndy Whitcroft chomp; 6600df344fSAndy Whitcroft push(@rawlines, $_); 670a920b5bSAndy Whitcroft if (eof(ARGV)) { 6800df344fSAndy Whitcroft if (!process($ARGV, @rawlines)) { 690a920b5bSAndy Whitcroft $exit = 1; 700a920b5bSAndy Whitcroft } 7100df344fSAndy Whitcroft @rawlines = (); 720a920b5bSAndy Whitcroft } 730a920b5bSAndy Whitcroft} 740a920b5bSAndy Whitcroft 750a920b5bSAndy Whitcroftexit($exit); 760a920b5bSAndy Whitcroft 770a920b5bSAndy Whitcroftsub top_of_kernel_tree { 780a920b5bSAndy Whitcroft if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") && 790a920b5bSAndy Whitcroft (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") && 800a920b5bSAndy Whitcroft (-d "Documentation") && (-d "arch") && (-d "include") && 810a920b5bSAndy Whitcroft (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") && 820a920b5bSAndy Whitcroft (-d "kernel") && (-d "lib") && (-d "scripts")) { 830a920b5bSAndy Whitcroft return 1; 840a920b5bSAndy Whitcroft } 850a920b5bSAndy Whitcroft return 0; 860a920b5bSAndy Whitcroft} 870a920b5bSAndy Whitcroft 880a920b5bSAndy Whitcroftsub expand_tabs { 890a920b5bSAndy Whitcroft my ($str) = @_; 900a920b5bSAndy Whitcroft 910a920b5bSAndy Whitcroft my $res = ''; 920a920b5bSAndy Whitcroft my $n = 0; 930a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 940a920b5bSAndy Whitcroft if ($c eq "\t") { 950a920b5bSAndy Whitcroft $res .= ' '; 960a920b5bSAndy Whitcroft $n++; 970a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 980a920b5bSAndy Whitcroft $res .= ' '; 990a920b5bSAndy Whitcroft } 1000a920b5bSAndy Whitcroft next; 1010a920b5bSAndy Whitcroft } 1020a920b5bSAndy Whitcroft $res .= $c; 1030a920b5bSAndy Whitcroft $n++; 1040a920b5bSAndy Whitcroft } 1050a920b5bSAndy Whitcroft 1060a920b5bSAndy Whitcroft return $res; 1070a920b5bSAndy Whitcroft} 1080a920b5bSAndy Whitcroft 1094a0df2efSAndy Whitcroftsub line_stats { 1104a0df2efSAndy Whitcroft my ($line) = @_; 1114a0df2efSAndy Whitcroft 1124a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 1134a0df2efSAndy Whitcroft $line =~ s/^.//; 1144a0df2efSAndy Whitcroft $line = expand_tabs($line); 1154a0df2efSAndy Whitcroft 1164a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 1174a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 1184a0df2efSAndy Whitcroft 1194a0df2efSAndy Whitcroft return (length($line), length($white)); 1204a0df2efSAndy Whitcroft} 1214a0df2efSAndy Whitcroft 12200df344fSAndy Whitcroftsub sanitise_line { 12300df344fSAndy Whitcroft my ($line) = @_; 12400df344fSAndy Whitcroft 12500df344fSAndy Whitcroft my $res = ''; 12600df344fSAndy Whitcroft my $l = ''; 12700df344fSAndy Whitcroft 12800df344fSAndy Whitcroft my $quote = ''; 12900df344fSAndy Whitcroft 13000df344fSAndy Whitcroft foreach my $c (split(//, $line)) { 13100df344fSAndy Whitcroft if ($l ne "\\" && ($c eq "'" || $c eq '"')) { 13200df344fSAndy Whitcroft if ($quote eq '') { 13300df344fSAndy Whitcroft $quote = $c; 13400df344fSAndy Whitcroft $res .= $c; 13500df344fSAndy Whitcroft $l = $c; 13600df344fSAndy Whitcroft next; 13700df344fSAndy Whitcroft } elsif ($quote eq $c) { 13800df344fSAndy Whitcroft $quote = ''; 13900df344fSAndy Whitcroft } 14000df344fSAndy Whitcroft } 14100df344fSAndy Whitcroft if ($quote && $c ne "\t") { 14200df344fSAndy Whitcroft $res .= "X"; 14300df344fSAndy Whitcroft } else { 14400df344fSAndy Whitcroft $res .= $c; 14500df344fSAndy Whitcroft } 14600df344fSAndy Whitcroft 14700df344fSAndy Whitcroft $l = $c; 14800df344fSAndy Whitcroft } 14900df344fSAndy Whitcroft 15000df344fSAndy Whitcroft return $res; 15100df344fSAndy Whitcroft} 15200df344fSAndy Whitcroft 1534a0df2efSAndy Whitcroftsub ctx_block_get { 154f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 1554a0df2efSAndy Whitcroft my $line; 1564a0df2efSAndy Whitcroft my $start = $linenr - 1; 1574a0df2efSAndy Whitcroft my $blk = ''; 1584a0df2efSAndy Whitcroft my @o; 1594a0df2efSAndy Whitcroft my @c; 1604a0df2efSAndy Whitcroft my @res = (); 1614a0df2efSAndy Whitcroft 162f0a594c1SAndy Whitcroft my $level = 0; 16300df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 16400df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 16500df344fSAndy Whitcroft $remain--; 16600df344fSAndy Whitcroft 16700df344fSAndy Whitcroft $blk .= $rawlines[$line]; 168f0a594c1SAndy Whitcroft foreach my $c (split(//, $rawlines[$line])) { 169f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 170f0a594c1SAndy Whitcroft if ($off > 0) { 171f0a594c1SAndy Whitcroft $off--; 172f0a594c1SAndy Whitcroft next; 173f0a594c1SAndy Whitcroft } 1744a0df2efSAndy Whitcroft 175f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 176f0a594c1SAndy Whitcroft $level--; 177f0a594c1SAndy Whitcroft last if ($level == 0); 178f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 179f0a594c1SAndy Whitcroft $level++; 180f0a594c1SAndy Whitcroft } 181f0a594c1SAndy Whitcroft } 1824a0df2efSAndy Whitcroft 183f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 18400df344fSAndy Whitcroft push(@res, $rawlines[$line]); 1854a0df2efSAndy Whitcroft } 1864a0df2efSAndy Whitcroft 187f0a594c1SAndy Whitcroft last if ($level == 0); 1884a0df2efSAndy Whitcroft } 1894a0df2efSAndy Whitcroft 190f0a594c1SAndy Whitcroft return ($level, @res); 1914a0df2efSAndy Whitcroft} 1924a0df2efSAndy Whitcroftsub ctx_block_outer { 1934a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 1944a0df2efSAndy Whitcroft 195f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 196f0a594c1SAndy Whitcroft return @r; 1974a0df2efSAndy Whitcroft} 1984a0df2efSAndy Whitcroftsub ctx_block { 1994a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 2004a0df2efSAndy Whitcroft 201f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 202f0a594c1SAndy Whitcroft return @r; 203653d4876SAndy Whitcroft} 204653d4876SAndy Whitcroftsub ctx_statement { 205f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 206f0a594c1SAndy Whitcroft 207f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 208f0a594c1SAndy Whitcroft return @r; 209f0a594c1SAndy Whitcroft} 210f0a594c1SAndy Whitcroftsub ctx_block_level { 211653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 212653d4876SAndy Whitcroft 213f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 2144a0df2efSAndy Whitcroft} 215*9c0ca6f9SAndy Whitcroftsub ctx_statement_level { 216*9c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 217*9c0ca6f9SAndy Whitcroft 218*9c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 219*9c0ca6f9SAndy Whitcroft} 2204a0df2efSAndy Whitcroft 2214a0df2efSAndy Whitcroftsub ctx_locate_comment { 2224a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 2234a0df2efSAndy Whitcroft 2244a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 22500df344fSAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@); 2264a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 2274a0df2efSAndy Whitcroft 2284a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 2294a0df2efSAndy Whitcroft # comment. 2304a0df2efSAndy Whitcroft my $in_comment = 0; 2314a0df2efSAndy Whitcroft $current_comment = ''; 2324a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 23300df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 23400df344fSAndy Whitcroft #warn " $line\n"; 2354a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 2364a0df2efSAndy Whitcroft $in_comment = 1; 2374a0df2efSAndy Whitcroft } 2384a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 2394a0df2efSAndy Whitcroft $in_comment = 1; 2404a0df2efSAndy Whitcroft } 2414a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 2424a0df2efSAndy Whitcroft $current_comment = ''; 2434a0df2efSAndy Whitcroft } 2444a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 2454a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 2464a0df2efSAndy Whitcroft $in_comment = 0; 2474a0df2efSAndy Whitcroft } 2484a0df2efSAndy Whitcroft } 2494a0df2efSAndy Whitcroft 2504a0df2efSAndy Whitcroft chomp($current_comment); 2514a0df2efSAndy Whitcroft return($current_comment); 2524a0df2efSAndy Whitcroft} 2534a0df2efSAndy Whitcroftsub ctx_has_comment { 2544a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 2554a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 2564a0df2efSAndy Whitcroft 25700df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 2584a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 2594a0df2efSAndy Whitcroft 2604a0df2efSAndy Whitcroft return ($cmt ne ''); 2614a0df2efSAndy Whitcroft} 2624a0df2efSAndy Whitcroft 263*9c0ca6f9SAndy Whitcroftsub ctx_expr_before { 264*9c0ca6f9SAndy Whitcroft my ($line) = @_; 265*9c0ca6f9SAndy Whitcroft 266*9c0ca6f9SAndy Whitcroft ##print "CHECK<$line>\n"; 267*9c0ca6f9SAndy Whitcroft 268*9c0ca6f9SAndy Whitcroft my $pos = length($line) - 1; 269*9c0ca6f9SAndy Whitcroft my $count = 0; 270*9c0ca6f9SAndy Whitcroft my $c; 271*9c0ca6f9SAndy Whitcroft 272*9c0ca6f9SAndy Whitcroft for (; $pos >= 0; $pos--) { 273*9c0ca6f9SAndy Whitcroft $c = substr($line, $pos, 1); 274*9c0ca6f9SAndy Whitcroft ##print "CHECK: c<$c> count<$count>\n"; 275*9c0ca6f9SAndy Whitcroft if ($c eq ')') { 276*9c0ca6f9SAndy Whitcroft $count++; 277*9c0ca6f9SAndy Whitcroft } elsif ($c eq '(') { 278*9c0ca6f9SAndy Whitcroft last if (--$count == 0); 279*9c0ca6f9SAndy Whitcroft } 280*9c0ca6f9SAndy Whitcroft } 281*9c0ca6f9SAndy Whitcroft 282*9c0ca6f9SAndy Whitcroft ##print "CHECK: result<" . substr($line, 0, $pos) . ">\n"; 283*9c0ca6f9SAndy Whitcroft 284*9c0ca6f9SAndy Whitcroft return substr($line, 0, $pos); 285*9c0ca6f9SAndy Whitcroft} 286*9c0ca6f9SAndy Whitcroft 2870a920b5bSAndy Whitcroftsub cat_vet { 2880a920b5bSAndy Whitcroft my ($vet) = @_; 289*9c0ca6f9SAndy Whitcroft my ($res, $coded); 2900a920b5bSAndy Whitcroft 291*9c0ca6f9SAndy Whitcroft $res = ''; 292*9c0ca6f9SAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) { 293*9c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 294*9c0ca6f9SAndy Whitcroft $res .= $1 . $coded; 295*9c0ca6f9SAndy Whitcroft } 296*9c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 2970a920b5bSAndy Whitcroft 298*9c0ca6f9SAndy Whitcroft return $res; 2990a920b5bSAndy Whitcroft} 3000a920b5bSAndy Whitcroft 301f0a594c1SAndy Whitcroftmy @report = (); 302f0a594c1SAndy Whitcroftsub report { 303f0a594c1SAndy Whitcroft push(@report, $_[0]); 304f0a594c1SAndy Whitcroft} 305f0a594c1SAndy Whitcroftsub report_dump { 306f0a594c1SAndy Whitcroft @report; 307f0a594c1SAndy Whitcroft} 308de7d4f0eSAndy Whitcroftsub ERROR { 309f0a594c1SAndy Whitcroft report("ERROR: $_[0]\n"); 310de7d4f0eSAndy Whitcroft our $clean = 0; 311de7d4f0eSAndy Whitcroft} 312de7d4f0eSAndy Whitcroftsub WARN { 313f0a594c1SAndy Whitcroft report("WARNING: $_[0]\n"); 314de7d4f0eSAndy Whitcroft our $clean = 0; 315de7d4f0eSAndy Whitcroft} 316de7d4f0eSAndy Whitcroftsub CHK { 317f0a594c1SAndy Whitcroft report("CHECK: $_[0]\n"); 318de7d4f0eSAndy Whitcroft our $clean = 0; 319de7d4f0eSAndy Whitcroft} 320de7d4f0eSAndy Whitcroft 3210a920b5bSAndy Whitcroftsub process { 3220a920b5bSAndy Whitcroft my $filename = shift; 3230a920b5bSAndy Whitcroft my @lines = @_; 3240a920b5bSAndy Whitcroft 3250a920b5bSAndy Whitcroft my $linenr=0; 3260a920b5bSAndy Whitcroft my $prevline=""; 3270a920b5bSAndy Whitcroft my $stashline=""; 3280a920b5bSAndy Whitcroft 3294a0df2efSAndy Whitcroft my $length; 3300a920b5bSAndy Whitcroft my $indent; 3310a920b5bSAndy Whitcroft my $previndent=0; 3320a920b5bSAndy Whitcroft my $stashindent=0; 3330a920b5bSAndy Whitcroft 334de7d4f0eSAndy Whitcroft our $clean = 1; 3350a920b5bSAndy Whitcroft my $signoff = 0; 3360a920b5bSAndy Whitcroft my $is_patch = 0; 3370a920b5bSAndy Whitcroft 3380a920b5bSAndy Whitcroft # Trace the real file/line as we go. 3390a920b5bSAndy Whitcroft my $realfile = ''; 3400a920b5bSAndy Whitcroft my $realline = 0; 3410a920b5bSAndy Whitcroft my $realcnt = 0; 3420a920b5bSAndy Whitcroft my $here = ''; 3430a920b5bSAndy Whitcroft my $in_comment = 0; 3440a920b5bSAndy Whitcroft my $first_line = 0; 3450a920b5bSAndy Whitcroft 346d8aaf121SAndy Whitcroft my $Ident = qr{[A-Za-z\d_]+}; 347*9c0ca6f9SAndy Whitcroft my $Storage = qr{extern|static|asmlinkage}; 348*9c0ca6f9SAndy Whitcroft my $Sparse = qr{ 349*9c0ca6f9SAndy Whitcroft __user| 350*9c0ca6f9SAndy Whitcroft __kernel| 351*9c0ca6f9SAndy Whitcroft __force| 352*9c0ca6f9SAndy Whitcroft __iomem| 353*9c0ca6f9SAndy Whitcroft __must_check| 354*9c0ca6f9SAndy Whitcroft __init_refok| 355*9c0ca6f9SAndy Whitcroft fastcall 356*9c0ca6f9SAndy Whitcroft }x; 357*9c0ca6f9SAndy Whitcroft my $Inline = qr{inline|__always_inline|noinline}; 358d8aaf121SAndy Whitcroft my $NonptrType = qr{ 359d8aaf121SAndy Whitcroft \b 360d8aaf121SAndy Whitcroft (?:const\s+)? 361d8aaf121SAndy Whitcroft (?:unsigned\s+)? 362d8aaf121SAndy Whitcroft (?: 363d8aaf121SAndy Whitcroft void| 364d8aaf121SAndy Whitcroft char| 365d8aaf121SAndy Whitcroft short| 366d8aaf121SAndy Whitcroft int| 367d8aaf121SAndy Whitcroft long| 368d8aaf121SAndy Whitcroft unsigned| 369d8aaf121SAndy Whitcroft float| 370d8aaf121SAndy Whitcroft double| 37122f2a2efSAndy Whitcroft bool| 372d8aaf121SAndy Whitcroft long\s+int| 373d8aaf121SAndy Whitcroft long\s+long| 374d8aaf121SAndy Whitcroft long\s+long\s+int| 375de7d4f0eSAndy Whitcroft u8|u16|u32|u64| 376de7d4f0eSAndy Whitcroft s8|s16|s32|s64| 377d8aaf121SAndy Whitcroft struct\s+$Ident| 378d8aaf121SAndy Whitcroft union\s+$Ident| 379de7d4f0eSAndy Whitcroft enum\s+$Ident| 380d8aaf121SAndy Whitcroft ${Ident}_t 381d8aaf121SAndy Whitcroft ) 382d8aaf121SAndy Whitcroft (?:\s+$Sparse)* 383d8aaf121SAndy Whitcroft \b 384d8aaf121SAndy Whitcroft }x; 385d8aaf121SAndy Whitcroft my $Type = qr{ 386d8aaf121SAndy Whitcroft \b$NonptrType\b 38722f2a2efSAndy Whitcroft (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 38822f2a2efSAndy Whitcroft (?:\s+$Sparse)* 389d8aaf121SAndy Whitcroft }x; 390d8aaf121SAndy Whitcroft my $Declare = qr{(?:$Storage\s+)?$Type}; 391*9c0ca6f9SAndy Whitcroft my $Attribute = qr{ 392*9c0ca6f9SAndy Whitcroft const| 393*9c0ca6f9SAndy Whitcroft __read_mostly| 394*9c0ca6f9SAndy Whitcroft __(?:mem|cpu|dev|)(?:initdata|init) 395*9c0ca6f9SAndy Whitcroft }x; 396f0a594c1SAndy Whitcroft my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 397f0a594c1SAndy Whitcroft my $Lval = qr{$Ident(?:$Member)*}; 398653d4876SAndy Whitcroft 399*9c0ca6f9SAndy Whitcroft # Possible bare types. 400*9c0ca6f9SAndy Whitcroft my @bare = (); 401*9c0ca6f9SAndy Whitcroft my $Bare = $NonptrType; 402*9c0ca6f9SAndy Whitcroft 403de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 404de7d4f0eSAndy Whitcroft my @setup_docs = (); 405de7d4f0eSAndy Whitcroft my $setup_docs = 0; 406de7d4f0eSAndy Whitcroft foreach my $line (@lines) { 407de7d4f0eSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 408de7d4f0eSAndy Whitcroft $setup_docs = 0; 409de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 410de7d4f0eSAndy Whitcroft $setup_docs = 1; 411de7d4f0eSAndy Whitcroft } 412de7d4f0eSAndy Whitcroft next; 413de7d4f0eSAndy Whitcroft } 414de7d4f0eSAndy Whitcroft 415de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 416de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 417de7d4f0eSAndy Whitcroft } 418de7d4f0eSAndy Whitcroft } 419de7d4f0eSAndy Whitcroft 4200a920b5bSAndy Whitcroft foreach my $line (@lines) { 4210a920b5bSAndy Whitcroft $linenr++; 4220a920b5bSAndy Whitcroft 423653d4876SAndy Whitcroft my $rawline = $line; 424653d4876SAndy Whitcroft 4250a920b5bSAndy Whitcroft#extract the filename as it passes 4260a920b5bSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 4270a920b5bSAndy Whitcroft $realfile=$1; 42800df344fSAndy Whitcroft $realfile =~ s@^[^/]*/@@; 4290a920b5bSAndy Whitcroft $in_comment = 0; 4300a920b5bSAndy Whitcroft next; 4310a920b5bSAndy Whitcroft } 4320a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 4330a920b5bSAndy Whitcroft if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { 4340a920b5bSAndy Whitcroft $is_patch = 1; 4354a0df2efSAndy Whitcroft $first_line = $linenr + 1; 4360a920b5bSAndy Whitcroft $in_comment = 0; 4370a920b5bSAndy Whitcroft $realline=$1-1; 4380a920b5bSAndy Whitcroft if (defined $2) { 4390a920b5bSAndy Whitcroft $realcnt=$3+1; 4400a920b5bSAndy Whitcroft } else { 4410a920b5bSAndy Whitcroft $realcnt=1+1; 4420a920b5bSAndy Whitcroft } 4430a920b5bSAndy Whitcroft next; 4440a920b5bSAndy Whitcroft } 4450a920b5bSAndy Whitcroft 4464a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 4474a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 4484a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 4494a0df2efSAndy Whitcroft if ($line =~ /^( |\+|$)/) { 4500a920b5bSAndy Whitcroft $realline++; 451d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 4520a920b5bSAndy Whitcroft 4530a920b5bSAndy Whitcroft # track any sort of multi-line comment. Obviously if 4540a920b5bSAndy Whitcroft # the added text or context do not include the whole 4550a920b5bSAndy Whitcroft # comment we will not see it. Such is life. 4560a920b5bSAndy Whitcroft # 4570a920b5bSAndy Whitcroft # Guestimate if this is a continuing comment. If this 4580a920b5bSAndy Whitcroft # is the start of a diff block and this line starts 4590a920b5bSAndy Whitcroft # ' *' then it is very likely a comment. 4604a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 4610a920b5bSAndy Whitcroft $in_comment = 1; 4620a920b5bSAndy Whitcroft } 4630a920b5bSAndy Whitcroft if ($line =~ m@/\*@) { 4640a920b5bSAndy Whitcroft $in_comment = 1; 4650a920b5bSAndy Whitcroft } 4660a920b5bSAndy Whitcroft if ($line =~ m@\*/@) { 4670a920b5bSAndy Whitcroft $in_comment = 0; 4680a920b5bSAndy Whitcroft } 4690a920b5bSAndy Whitcroft 4704a0df2efSAndy Whitcroft # Measure the line length and indent. 4714a0df2efSAndy Whitcroft ($length, $indent) = line_stats($line); 4720a920b5bSAndy Whitcroft 4730a920b5bSAndy Whitcroft # Track the previous line. 4740a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 4750a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 476d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 477d8aaf121SAndy Whitcroft $realcnt--; 4780a920b5bSAndy Whitcroft } 4790a920b5bSAndy Whitcroft 4800a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 481389834b6SRandy Dunlap $here = "#$linenr: "; 482389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 4830a920b5bSAndy Whitcroft 48400df344fSAndy Whitcroft my $hereline = "$here\n$line\n"; 485de7d4f0eSAndy Whitcroft my $herecurr = "$here\n$line\n"; 486de7d4f0eSAndy Whitcroft my $hereprev = "$here\n$prevline\n$line\n"; 4870a920b5bSAndy Whitcroft 4880a920b5bSAndy Whitcroft#check the patch for a signoff: 489d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 4904a0df2efSAndy Whitcroft # This is a signoff, if ugly, so do not double report. 4914a0df2efSAndy Whitcroft $signoff++; 4920a920b5bSAndy Whitcroft if (!($line =~ /^\s*Signed-off-by:/)) { 493de7d4f0eSAndy Whitcroft WARN("Signed-off-by: is the preferred form\n" . 494de7d4f0eSAndy Whitcroft $herecurr); 4950a920b5bSAndy Whitcroft } 4960a920b5bSAndy Whitcroft if ($line =~ /^\s*signed-off-by:\S/i) { 497de7d4f0eSAndy Whitcroft WARN("need space after Signed-off-by:\n" . 498de7d4f0eSAndy Whitcroft $herecurr); 4990a920b5bSAndy Whitcroft } 5000a920b5bSAndy Whitcroft } 5010a920b5bSAndy Whitcroft 50200df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 50300df344fSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { 504de7d4f0eSAndy Whitcroft ERROR("patch seems to be corrupt (line wrapped?)\n" . 505de7d4f0eSAndy Whitcroft $herecurr); 506de7d4f0eSAndy Whitcroft } 507de7d4f0eSAndy Whitcroft 508de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 509de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 510de7d4f0eSAndy Whitcroft !($line =~ m/^( 511de7d4f0eSAndy Whitcroft [\x09\x0A\x0D\x20-\x7E] # ASCII 512de7d4f0eSAndy Whitcroft | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 513de7d4f0eSAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 514de7d4f0eSAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 515de7d4f0eSAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 516de7d4f0eSAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 517de7d4f0eSAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 518de7d4f0eSAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 519de7d4f0eSAndy Whitcroft )*$/x )) { 520de7d4f0eSAndy Whitcroft ERROR("Invalid UTF-8\n" . $herecurr); 52100df344fSAndy Whitcroft } 5220a920b5bSAndy Whitcroft 52300df344fSAndy Whitcroft#ignore lines being removed 52400df344fSAndy Whitcroft if ($line=~/^-/) {next;} 52500df344fSAndy Whitcroft 52600df344fSAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 52700df344fSAndy Whitcroft next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 5280a920b5bSAndy Whitcroft 5290a920b5bSAndy Whitcroft#trailing whitespace 530*9c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 531*9c0ca6f9SAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 532*9c0ca6f9SAndy Whitcroft ERROR("DOS line endings\n" . $herevet); 533*9c0ca6f9SAndy Whitcroft 534*9c0ca6f9SAndy Whitcroft } elsif ($line =~ /^\+.*\S\s+$/ || $line =~ /^\+\s+$/) { 535de7d4f0eSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 536de7d4f0eSAndy Whitcroft ERROR("trailing whitespace\n" . $herevet); 5370a920b5bSAndy Whitcroft } 5380a920b5bSAndy Whitcroft#80 column limit 53900df344fSAndy Whitcroft if ($line =~ /^\+/ && !($prevline=~/\/\*\*/) && $length > 80) { 540de7d4f0eSAndy Whitcroft WARN("line over 80 characters\n" . $herecurr); 5410a920b5bSAndy Whitcroft } 5420a920b5bSAndy Whitcroft 5430a920b5bSAndy Whitcroft# check we are in a valid source file *.[hc] if not then ignore this hunk 5440a920b5bSAndy Whitcroft next if ($realfile !~ /\.[hc]$/); 5450a920b5bSAndy Whitcroft 5460a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 5470a920b5bSAndy Whitcroft# more than 8 must use tabs. 5480a920b5bSAndy Whitcroft if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s* \s*/) { 549de7d4f0eSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n"; 550de7d4f0eSAndy Whitcroft ERROR("use tabs not spaces\n" . $herevet); 5510a920b5bSAndy Whitcroft } 5520a920b5bSAndy Whitcroft 5530a920b5bSAndy Whitcroft# Remove comments from the line before processing. 55422f2a2efSAndy Whitcroft my $comment_edge = ($line =~ s@/\*.*\*/@@g) + 55522f2a2efSAndy Whitcroft ($line =~ s@/\*.*@@) + 55622f2a2efSAndy Whitcroft ($line =~ s@^(.).*\*/@$1@); 55722f2a2efSAndy Whitcroft 55822f2a2efSAndy Whitcroft# The rest of our checks refer specifically to C style 55922f2a2efSAndy Whitcroft# only apply those _outside_ comments. Only skip 56022f2a2efSAndy Whitcroft# lines in the middle of comments. 56122f2a2efSAndy Whitcroft next if (!$comment_edge && $in_comment); 56200df344fSAndy Whitcroft 563653d4876SAndy Whitcroft# Standardise the strings and chars within the input to simplify matching. 564653d4876SAndy Whitcroft $line = sanitise_line($line); 565653d4876SAndy Whitcroft 566*9c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 567*9c0ca6f9SAndy Whitcroft if ($realcnt && 568*9c0ca6f9SAndy Whitcroft $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && 569*9c0ca6f9SAndy Whitcroft $line !~ /$Ident:\s*$/ && 570*9c0ca6f9SAndy Whitcroft $line !~ /^.\s*$Ident\s*\(/ && 571*9c0ca6f9SAndy Whitcroft ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || 572*9c0ca6f9SAndy Whitcroft $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) { 573*9c0ca6f9SAndy Whitcroft my $possible = $1; 574*9c0ca6f9SAndy Whitcroft if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && 575*9c0ca6f9SAndy Whitcroft $possible ne 'goto' && $possible ne 'return' && 576*9c0ca6f9SAndy Whitcroft $possible ne 'struct' && $possible ne 'enum' && 577*9c0ca6f9SAndy Whitcroft $possible ne 'case' && $possible ne 'else' && 578*9c0ca6f9SAndy Whitcroft $possible ne 'typedef') { 579*9c0ca6f9SAndy Whitcroft #print "POSSIBLE<$possible>\n"; 580*9c0ca6f9SAndy Whitcroft push(@bare, $possible); 581*9c0ca6f9SAndy Whitcroft my $bare = join("|", @bare); 582*9c0ca6f9SAndy Whitcroft $Bare = qr{ 583*9c0ca6f9SAndy Whitcroft \b(?:$bare)\b 584*9c0ca6f9SAndy Whitcroft (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 585*9c0ca6f9SAndy Whitcroft (?:\s+$Sparse)* 586*9c0ca6f9SAndy Whitcroft }x; 587*9c0ca6f9SAndy Whitcroft } 588*9c0ca6f9SAndy Whitcroft } 589*9c0ca6f9SAndy Whitcroft 59000df344fSAndy Whitcroft# 59100df344fSAndy Whitcroft# Checks which may be anchored in the context. 59200df344fSAndy Whitcroft# 59300df344fSAndy Whitcroft 59400df344fSAndy Whitcroft# Check for switch () and associated case and default 59500df344fSAndy Whitcroft# statements should be at the same indent. 59600df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 59700df344fSAndy Whitcroft my $err = ''; 59800df344fSAndy Whitcroft my $sep = ''; 59900df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 60000df344fSAndy Whitcroft shift(@ctx); 60100df344fSAndy Whitcroft for my $ctx (@ctx) { 60200df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 60300df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 60400df344fSAndy Whitcroft $indent != $cindent) { 60500df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 60600df344fSAndy Whitcroft $sep = ''; 60700df344fSAndy Whitcroft } else { 60800df344fSAndy Whitcroft $sep = "[...]\n"; 60900df344fSAndy Whitcroft } 61000df344fSAndy Whitcroft } 61100df344fSAndy Whitcroft if ($err ne '') { 612*9c0ca6f9SAndy Whitcroft ERROR("switch and case should be at the same indent\n$hereline$err"); 613de7d4f0eSAndy Whitcroft } 614de7d4f0eSAndy Whitcroft } 615de7d4f0eSAndy Whitcroft 616de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 617de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 618de7d4f0eSAndy Whitcroft if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { 619*9c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 620de7d4f0eSAndy Whitcroft my $ctx_ln = $linenr + $#ctx + 1; 621de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 622de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 623de7d4f0eSAndy Whitcroft 624*9c0ca6f9SAndy Whitcroft # Skip over any removed lines in the context following statement. 625de7d4f0eSAndy Whitcroft while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) { 626de7d4f0eSAndy Whitcroft $ctx_ln++; 627de7d4f0eSAndy Whitcroft $ctx_cnt--; 628de7d4f0eSAndy Whitcroft } 629de7d4f0eSAndy Whitcroft ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>"; 630de7d4f0eSAndy Whitcroft 631de7d4f0eSAndy Whitcroft if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 632f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . 633de7d4f0eSAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 63400df344fSAndy Whitcroft } 635*9c0ca6f9SAndy Whitcroft if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) { 636*9c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 637*9c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 638*9c0ca6f9SAndy Whitcroft WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" . 639*9c0ca6f9SAndy Whitcroft "$here\n$ctx\n$lines[$ctx_ln - 1]"); 640*9c0ca6f9SAndy Whitcroft } 641*9c0ca6f9SAndy Whitcroft } 64200df344fSAndy Whitcroft } 64300df344fSAndy Whitcroft 64400df344fSAndy Whitcroft#ignore lines not being added 64500df344fSAndy Whitcroft if ($line=~/^[^\+]/) {next;} 64600df344fSAndy Whitcroft 647653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 648653d4876SAndy Whitcroft if ($tst_type && $line =~ /^.$Declare$/) { 649de7d4f0eSAndy Whitcroft ERROR("TEST: is type $Declare\n" . $herecurr); 650653d4876SAndy Whitcroft next; 651653d4876SAndy Whitcroft } 652653d4876SAndy Whitcroft 653f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 654f0a594c1SAndy Whitcroft if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ && 655f0a594c1SAndy Whitcroft $line =~ /^.\s*{/) { 656f0a594c1SAndy Whitcroft ERROR("That open brace { should be on the previous line\n" . $hereprev); 657f0a594c1SAndy Whitcroft } 658f0a594c1SAndy Whitcroft 65900df344fSAndy Whitcroft# 66000df344fSAndy Whitcroft# Checks which are anchored on the added line. 66100df344fSAndy Whitcroft# 66200df344fSAndy Whitcroft 663653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 664653d4876SAndy Whitcroft if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { 665653d4876SAndy Whitcroft my $path = $1; 666653d4876SAndy Whitcroft if ($path =~ m{//}) { 667de7d4f0eSAndy Whitcroft ERROR("malformed #include filename\n" . 668de7d4f0eSAndy Whitcroft $herecurr); 669653d4876SAndy Whitcroft } 670653d4876SAndy Whitcroft # Sanitise this special form of string. 671653d4876SAndy Whitcroft $path = 'X' x length($path); 672653d4876SAndy Whitcroft $line =~ s{\<.*\>}{<$path>}; 673653d4876SAndy Whitcroft } 674653d4876SAndy Whitcroft 67500df344fSAndy Whitcroft# no C99 // comments 67600df344fSAndy Whitcroft if ($line =~ m{//}) { 677de7d4f0eSAndy Whitcroft ERROR("do not use C99 // comments\n" . $herecurr); 67800df344fSAndy Whitcroft } 67900df344fSAndy Whitcroft # Remove C99 comments. 6800a920b5bSAndy Whitcroft $line =~ s@//.*@@; 6810a920b5bSAndy Whitcroft 6820a920b5bSAndy Whitcroft#EXPORT_SYMBOL should immediately follow its function closing }. 683653d4876SAndy Whitcroft if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || 684653d4876SAndy Whitcroft ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 685653d4876SAndy Whitcroft my $name = $1; 6860a920b5bSAndy Whitcroft if (($prevline !~ /^}/) && 6870a920b5bSAndy Whitcroft ($prevline !~ /^\+}/) && 688653d4876SAndy Whitcroft ($prevline !~ /^ }/) && 68922f2a2efSAndy Whitcroft ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { 690de7d4f0eSAndy Whitcroft WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 6910a920b5bSAndy Whitcroft } 6920a920b5bSAndy Whitcroft } 6930a920b5bSAndy Whitcroft 694f0a594c1SAndy Whitcroft# check for external initialisers. 695f0a594c1SAndy Whitcroft if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) { 696f0a594c1SAndy Whitcroft ERROR("do not initialise externals to 0 or NULL\n" . 697f0a594c1SAndy Whitcroft $herecurr); 698f0a594c1SAndy Whitcroft } 6990a920b5bSAndy Whitcroft# check for static initialisers. 700f0a594c1SAndy Whitcroft if ($line =~ /\s*static\s.*=\s*(0|NULL);/) { 701de7d4f0eSAndy Whitcroft ERROR("do not initialise statics to 0 or NULL\n" . 702de7d4f0eSAndy Whitcroft $herecurr); 7030a920b5bSAndy Whitcroft } 7040a920b5bSAndy Whitcroft 705653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 706653d4876SAndy Whitcroft# make sense. 707653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 708*9c0ca6f9SAndy Whitcroft $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && 709653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 710de7d4f0eSAndy Whitcroft WARN("do not add new typedefs\n" . $herecurr); 7110a920b5bSAndy Whitcroft } 7120a920b5bSAndy Whitcroft 7130a920b5bSAndy Whitcroft# * goes on variable not on type 714d8aaf121SAndy Whitcroft if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) { 715de7d4f0eSAndy Whitcroft ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" . 716de7d4f0eSAndy Whitcroft $herecurr); 717d8aaf121SAndy Whitcroft 718d8aaf121SAndy Whitcroft } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) { 719de7d4f0eSAndy Whitcroft ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" . 720de7d4f0eSAndy Whitcroft $herecurr); 721d8aaf121SAndy Whitcroft 722*9c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) { 723de7d4f0eSAndy Whitcroft ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" . 724de7d4f0eSAndy Whitcroft $herecurr); 725d8aaf121SAndy Whitcroft 726*9c0ca6f9SAndy Whitcroft } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) { 727de7d4f0eSAndy Whitcroft ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" . 728de7d4f0eSAndy Whitcroft $herecurr); 7290a920b5bSAndy Whitcroft } 7300a920b5bSAndy Whitcroft 7310a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 7320a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 7330a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 7340a920b5bSAndy Whitcroft# print "$herecurr"; 7350a920b5bSAndy Whitcroft# $clean = 0; 7360a920b5bSAndy Whitcroft# } 7370a920b5bSAndy Whitcroft 73800df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 73900df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 74000df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 74100df344fSAndy Whitcroft# printk includes all preceeding printk's which have no newline on the end. 74200df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 743f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 74400df344fSAndy Whitcroft my $ok = 0; 74500df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 74600df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 74700df344fSAndy Whitcroft # we have a preceeding printk if it ends 74800df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 74900df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 75000df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 75100df344fSAndy Whitcroft $ok = 1; 75200df344fSAndy Whitcroft } 75300df344fSAndy Whitcroft last; 75400df344fSAndy Whitcroft } 75500df344fSAndy Whitcroft } 75600df344fSAndy Whitcroft if ($ok == 0) { 757de7d4f0eSAndy Whitcroft WARN("printk() should include KERN_ facility level\n" . $herecurr); 7580a920b5bSAndy Whitcroft } 75900df344fSAndy Whitcroft } 7600a920b5bSAndy Whitcroft 761653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 762653d4876SAndy Whitcroft# or if closed on same line 763d8aaf121SAndy Whitcroft if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).* {/) and 7640a920b5bSAndy Whitcroft !($line=~/\#define.*do\s{/) and !($line=~/}/)) { 765de7d4f0eSAndy Whitcroft ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 7660a920b5bSAndy Whitcroft } 767653d4876SAndy Whitcroft 768f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 769f0a594c1SAndy Whitcroft if ($line =~ /($Ident)\s+\(/ && 77022f2a2efSAndy Whitcroft $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ && 771f0a594c1SAndy Whitcroft $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { 77222f2a2efSAndy Whitcroft WARN("no space between function name and open parenthesis '('\n" . $herecurr); 773f0a594c1SAndy Whitcroft } 774653d4876SAndy Whitcroft# Check operator spacing. 7754a0df2efSAndy Whitcroft # Note we expand the line with the leading + as the real 7764a0df2efSAndy Whitcroft # line will be displayed with the leading + and the tabs 7774a0df2efSAndy Whitcroft # will therefore also expand that way. 7780a920b5bSAndy Whitcroft my $opline = $line; 7794a0df2efSAndy Whitcroft $opline = expand_tabs($opline); 7800a920b5bSAndy Whitcroft $opline =~ s/^./ /; 7810a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 782*9c0ca6f9SAndy Whitcroft my $ops = qr{ 783*9c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 784*9c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 785*9c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 786*9c0ca6f9SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ 787*9c0ca6f9SAndy Whitcroft }x; 788*9c0ca6f9SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 78900df344fSAndy Whitcroft my $off = 0; 7900a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 7914a0df2efSAndy Whitcroft $off += length($elements[$n]); 7924a0df2efSAndy Whitcroft 7934a0df2efSAndy Whitcroft my $a = ''; 7944a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 7954a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 7964a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 7974a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 7984a0df2efSAndy Whitcroft $a = 'E' if ($elements[$n] eq '' && $n == 0); 7994a0df2efSAndy Whitcroft 8000a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 8014a0df2efSAndy Whitcroft 8024a0df2efSAndy Whitcroft my $c = ''; 8030a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 8044a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 8054a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 8064a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 8074a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 80822f2a2efSAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); 8094a0df2efSAndy Whitcroft } else { 8104a0df2efSAndy Whitcroft $c = 'E'; 8110a920b5bSAndy Whitcroft } 8120a920b5bSAndy Whitcroft 81300df344fSAndy Whitcroft # Pick up the preceeding and succeeding characters. 814de7d4f0eSAndy Whitcroft my $ca = substr($opline, 0, $off); 81500df344fSAndy Whitcroft my $cc = ''; 816653d4876SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 817d8aaf121SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 81800df344fSAndy Whitcroft } 819de7d4f0eSAndy Whitcroft my $cb = "$ca$;$cc"; 82000df344fSAndy Whitcroft 8214a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 8224a0df2efSAndy Whitcroft 8234a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 8244a0df2efSAndy Whitcroft 8254a0df2efSAndy Whitcroft my $ptr = (" " x $off) . "^"; 826de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 8270a920b5bSAndy Whitcroft 828*9c0ca6f9SAndy Whitcroft # Classify operators into binary, unary, or 829*9c0ca6f9SAndy Whitcroft # definitions (* only) where they have more 830*9c0ca6f9SAndy Whitcroft # than one mode. 831*9c0ca6f9SAndy Whitcroft my $unary_ctx = $prevline . $ca; 832*9c0ca6f9SAndy Whitcroft $unary_ctx =~ s/^./ /; 833*9c0ca6f9SAndy Whitcroft my $is_unary = 0; 834*9c0ca6f9SAndy Whitcroft my $Unary = qr{ 835*9c0ca6f9SAndy Whitcroft (?: 836*9c0ca6f9SAndy Whitcroft ^|;|,|$ops|\(|\?|:| 837*9c0ca6f9SAndy Whitcroft \(\s*$Type\s*\)| 838*9c0ca6f9SAndy Whitcroft $Type| 839*9c0ca6f9SAndy Whitcroft return|case|else| 840*9c0ca6f9SAndy Whitcroft \{|\}| 841*9c0ca6f9SAndy Whitcroft \[| 842*9c0ca6f9SAndy Whitcroft ^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?| 843*9c0ca6f9SAndy Whitcroft ^.\#\s*else| 844*9c0ca6f9SAndy Whitcroft ^.\#\s*endif| 845*9c0ca6f9SAndy Whitcroft ^.\#\s*(?:if|ifndef|ifdef)\b.* 846*9c0ca6f9SAndy Whitcroft )\s*(?:|\\)\s*$ 847*9c0ca6f9SAndy Whitcroft }x; 848*9c0ca6f9SAndy Whitcroft my $UnaryFalse = qr{ 849*9c0ca6f9SAndy Whitcroft sizeof\s*\(\s*$Type\s*\)\s*$ 850*9c0ca6f9SAndy Whitcroft }x; 851*9c0ca6f9SAndy Whitcroft my $UnaryDefine = qr{ 852*9c0ca6f9SAndy Whitcroft (?:$Type|$Bare)\s*| 853*9c0ca6f9SAndy Whitcroft (?:$Type|$Bare).*,\s*\** 854*9c0ca6f9SAndy Whitcroft }x; 855*9c0ca6f9SAndy Whitcroft if ($op eq '-' || $op eq '&' || $op eq '*') { 856*9c0ca6f9SAndy Whitcroft # An operator is binary if the left hand 857*9c0ca6f9SAndy Whitcroft # side is a value. Pick out the known 858*9c0ca6f9SAndy Whitcroft # non-values. 859*9c0ca6f9SAndy Whitcroft if ($unary_ctx =~ /$Unary$/s && 860*9c0ca6f9SAndy Whitcroft $unary_ctx !~ /$UnaryFalse$/s) { 861*9c0ca6f9SAndy Whitcroft $is_unary = 1; 862*9c0ca6f9SAndy Whitcroft 863*9c0ca6f9SAndy Whitcroft # Special handling for ')' check if this 864*9c0ca6f9SAndy Whitcroft # brace represents a conditional, if so 865*9c0ca6f9SAndy Whitcroft # we are unary. 866*9c0ca6f9SAndy Whitcroft } elsif ($unary_ctx =~ /\)\s*$/) { 867*9c0ca6f9SAndy Whitcroft my $before = ctx_expr_before($unary_ctx); 868*9c0ca6f9SAndy Whitcroft if ($before =~ /(?:for|if|while)\s*$/) { 869*9c0ca6f9SAndy Whitcroft $is_unary = 1; 870*9c0ca6f9SAndy Whitcroft } 871*9c0ca6f9SAndy Whitcroft } 872*9c0ca6f9SAndy Whitcroft 873*9c0ca6f9SAndy Whitcroft # Check for type definition for of '*'. 874*9c0ca6f9SAndy Whitcroft if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) { 875*9c0ca6f9SAndy Whitcroft $is_unary = 2; 876*9c0ca6f9SAndy Whitcroft } 877*9c0ca6f9SAndy Whitcroft } 878*9c0ca6f9SAndy Whitcroft 879*9c0ca6f9SAndy Whitcroft #if ($op eq '-' || $op eq '&' || $op eq '*') { 880*9c0ca6f9SAndy Whitcroft # print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; 881*9c0ca6f9SAndy Whitcroft #} 8820a920b5bSAndy Whitcroft 883d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 884d8aaf121SAndy Whitcroft if ($op eq ';') { 885de7d4f0eSAndy Whitcroft if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && 886de7d4f0eSAndy Whitcroft $cc !~ /^;/) { 887de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 888d8aaf121SAndy Whitcroft } 889d8aaf121SAndy Whitcroft 890d8aaf121SAndy Whitcroft # // is a comment 891d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 8920a920b5bSAndy Whitcroft 8930a920b5bSAndy Whitcroft # -> should have no spaces 8940a920b5bSAndy Whitcroft } elsif ($op eq '->') { 8954a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 896de7d4f0eSAndy Whitcroft ERROR("no spaces around that '$op' $at\n" . $hereptr); 8970a920b5bSAndy Whitcroft } 8980a920b5bSAndy Whitcroft 8990a920b5bSAndy Whitcroft # , must have a space on the right. 9000a920b5bSAndy Whitcroft } elsif ($op eq ',') { 901d8aaf121SAndy Whitcroft if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { 902de7d4f0eSAndy Whitcroft ERROR("need space after that '$op' $at\n" . $hereptr); 9030a920b5bSAndy Whitcroft } 9040a920b5bSAndy Whitcroft 905*9c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 906*9c0ca6f9SAndy Whitcroft } elsif ($op eq '*' && $is_unary == 2) { 907*9c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 908*9c0ca6f9SAndy Whitcroft 909*9c0ca6f9SAndy Whitcroft # unary operators should have a space before and 910*9c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 911*9c0ca6f9SAndy Whitcroft # unary operator, or a cast 912*9c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 913*9c0ca6f9SAndy Whitcroft ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { 914*9c0ca6f9SAndy Whitcroft if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 915de7d4f0eSAndy Whitcroft ERROR("need space before that '$op' $at\n" . $hereptr); 9160a920b5bSAndy Whitcroft } 9174a0df2efSAndy Whitcroft if ($ctx =~ /.xW/) { 918de7d4f0eSAndy Whitcroft ERROR("no space after that '$op' $at\n" . $hereptr); 9190a920b5bSAndy Whitcroft } 9200a920b5bSAndy Whitcroft 9210a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 9220a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 923d8aaf121SAndy Whitcroft if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { 924de7d4f0eSAndy Whitcroft ERROR("need space one side of that '$op' $at\n" . $hereptr); 9250a920b5bSAndy Whitcroft } 926d8aaf121SAndy Whitcroft if ($ctx =~ /Wx./ && $cc =~ /^;/) { 927de7d4f0eSAndy Whitcroft ERROR("no space before that '$op' $at\n" . $hereptr); 928653d4876SAndy Whitcroft } 9290a920b5bSAndy Whitcroft 9300a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 931*9c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 932*9c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 933*9c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 934*9c0ca6f9SAndy Whitcroft $op eq '*' or $op eq '/') 9350a920b5bSAndy Whitcroft { 936*9c0ca6f9SAndy Whitcroft if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) { 937de7d4f0eSAndy Whitcroft ERROR("need consistent spacing around '$op' $at\n" . 938de7d4f0eSAndy Whitcroft $hereptr); 9390a920b5bSAndy Whitcroft } 9400a920b5bSAndy Whitcroft 9410a920b5bSAndy Whitcroft # All the others need spaces both sides. 9424a0df2efSAndy Whitcroft } elsif ($ctx !~ /[EW]x[WE]/) { 94322f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 94422f2a2efSAndy Whitcroft if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && 94522f2a2efSAndy Whitcroft !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { 946de7d4f0eSAndy Whitcroft ERROR("need spaces around that '$op' $at\n" . $hereptr); 9470a920b5bSAndy Whitcroft } 94822f2a2efSAndy Whitcroft } 9494a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 9500a920b5bSAndy Whitcroft } 9510a920b5bSAndy Whitcroft } 9520a920b5bSAndy Whitcroft 953f0a594c1SAndy Whitcroft# check for multiple assignments 954f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 955f0a594c1SAndy Whitcroft WARN("multiple assignments should be avoided\n" . $herecurr); 956f0a594c1SAndy Whitcroft } 957f0a594c1SAndy Whitcroft 95822f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 95922f2a2efSAndy Whitcroft## # continuation. 96022f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 96122f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 96222f2a2efSAndy Whitcroft## 96322f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 96422f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 96522f2a2efSAndy Whitcroft## my $ln = $line; 96622f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 96722f2a2efSAndy Whitcroft## } 96822f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 96922f2a2efSAndy Whitcroft## WARN("declaring multiple variables together should be avoided\n" . $herecurr); 97022f2a2efSAndy Whitcroft## } 97122f2a2efSAndy Whitcroft## } 972f0a594c1SAndy Whitcroft 9730a920b5bSAndy Whitcroft#need space before brace following if, while, etc 97422f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 97522f2a2efSAndy Whitcroft $line =~ /do{/) { 976de7d4f0eSAndy Whitcroft ERROR("need a space before the open brace '{'\n" . $herecurr); 977de7d4f0eSAndy Whitcroft } 978de7d4f0eSAndy Whitcroft 979de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 980de7d4f0eSAndy Whitcroft# on the line 981de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 982de7d4f0eSAndy Whitcroft ERROR("need a space after that close brace '}'\n" . $herecurr); 9830a920b5bSAndy Whitcroft } 9840a920b5bSAndy Whitcroft 98522f2a2efSAndy Whitcroft# check spacing on square brackets 98622f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 98722f2a2efSAndy Whitcroft ERROR("no space after that open square bracket '['\n" . $herecurr); 98822f2a2efSAndy Whitcroft } 98922f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 99022f2a2efSAndy Whitcroft ERROR("no space before that close square bracket ']'\n" . $herecurr); 99122f2a2efSAndy Whitcroft } 99222f2a2efSAndy Whitcroft 99322f2a2efSAndy Whitcroft# check spacing on paretheses 994*9c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 995*9c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 99622f2a2efSAndy Whitcroft ERROR("no space after that open parenthesis '('\n" . $herecurr); 99722f2a2efSAndy Whitcroft } 998*9c0ca6f9SAndy Whitcroft if ($line =~ /\s\)/ && $line !~ /^.\s*\)/ && 999*9c0ca6f9SAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/) { 100022f2a2efSAndy Whitcroft ERROR("no space before that close parenthesis ')'\n" . $herecurr); 100122f2a2efSAndy Whitcroft } 100222f2a2efSAndy Whitcroft 10030a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 10044a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 10050a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 1006de7d4f0eSAndy Whitcroft WARN("labels should not be indented\n" . $herecurr); 10070a920b5bSAndy Whitcroft } 10080a920b5bSAndy Whitcroft 10090a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 10104a0df2efSAndy Whitcroft if ($line=~/\b(if|while|for|switch)\(/) { 1011de7d4f0eSAndy Whitcroft ERROR("need a space before the open parenthesis '('\n" . $herecurr); 10120a920b5bSAndy Whitcroft } 10130a920b5bSAndy Whitcroft 10140a920b5bSAndy Whitcroft# Check for illegal assignment in if conditional. 1015653d4876SAndy Whitcroft if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) { 101600df344fSAndy Whitcroft #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); 1017de7d4f0eSAndy Whitcroft ERROR("do not use assignment in if condition\n" . $herecurr); 10180a920b5bSAndy Whitcroft } 10190a920b5bSAndy Whitcroft 10200a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 10210a920b5bSAndy Whitcroft # indent level to be relevant to each other. 10220a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 10230a920b5bSAndy Whitcroft $previndent == $indent) { 1024de7d4f0eSAndy Whitcroft ERROR("else should follow close brace '}'\n" . $hereprev); 10250a920b5bSAndy Whitcroft } 10260a920b5bSAndy Whitcroft 10270a920b5bSAndy Whitcroft#studly caps, commented out until figure out how to distinguish between use of existing and adding new 10280a920b5bSAndy Whitcroft# if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { 10290a920b5bSAndy Whitcroft# print "No studly caps, use _\n"; 10300a920b5bSAndy Whitcroft# print "$herecurr"; 10310a920b5bSAndy Whitcroft# $clean = 0; 10320a920b5bSAndy Whitcroft# } 10330a920b5bSAndy Whitcroft 10340a920b5bSAndy Whitcroft#no spaces allowed after \ in define 10350a920b5bSAndy Whitcroft if ($line=~/\#define.*\\\s$/) { 1036de7d4f0eSAndy Whitcroft WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); 10370a920b5bSAndy Whitcroft } 10380a920b5bSAndy Whitcroft 1039653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 1040653d4876SAndy Whitcroft if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { 10410a920b5bSAndy Whitcroft my $checkfile = "include/linux/$1.h"; 10420a920b5bSAndy Whitcroft if (-f $checkfile) { 1043de7d4f0eSAndy Whitcroft CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . 1044de7d4f0eSAndy Whitcroft $herecurr); 10450a920b5bSAndy Whitcroft } 10460a920b5bSAndy Whitcroft } 10470a920b5bSAndy Whitcroft 1048d8aaf121SAndy Whitcroft# if and else should not have general statements after it 1049d8aaf121SAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ && 1050de7d4f0eSAndy Whitcroft $1 !~ /^\s*(?:\sif|{|\\|$)/) { 1051de7d4f0eSAndy Whitcroft ERROR("trailing statements should be on next line\n" . $herecurr); 1052d8aaf121SAndy Whitcroft } 1053d8aaf121SAndy Whitcroft 1054653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 1055653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 1056653d4876SAndy Whitcroft# in a known goot container 1057*9c0ca6f9SAndy Whitcroft if ($prevline =~ /\#define.*\\/ && 1058*9c0ca6f9SAndy Whitcroft $prevline !~/(?:do\s+{|\(\{|\{)/ && 1059*9c0ca6f9SAndy Whitcroft $line !~ /(?:do\s+{|\(\{|\{)/ && 1060*9c0ca6f9SAndy Whitcroft $line !~ /^.\s*$Declare\s/) { 1061653d4876SAndy Whitcroft # Grab the first statement, if that is the entire macro 1062653d4876SAndy Whitcroft # its ok. This may start either on the #define line 1063653d4876SAndy Whitcroft # or the one below. 1064d8aaf121SAndy Whitcroft my $ln = $linenr; 1065d8aaf121SAndy Whitcroft my $cnt = $realcnt; 1066f0a594c1SAndy Whitcroft my $off = 0; 1067653d4876SAndy Whitcroft 1068f0a594c1SAndy Whitcroft # If the macro starts on the define line start 1069f0a594c1SAndy Whitcroft # grabbing the statement after the identifier 1070f0a594c1SAndy Whitcroft $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; 1071f0a594c1SAndy Whitcroft ##print "1<$1> 2<$2>\n"; 107222f2a2efSAndy Whitcroft if (defined $2 && $2 ne '') { 1073f0a594c1SAndy Whitcroft $off = length($1); 1074d8aaf121SAndy Whitcroft $ln--; 1075d8aaf121SAndy Whitcroft $cnt++; 1076d8aaf121SAndy Whitcroft } 1077f0a594c1SAndy Whitcroft my @ctx = ctx_statement($ln, $cnt, $off); 1078de7d4f0eSAndy Whitcroft my $ctx_ln = $ln + $#ctx + 1; 1079de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 1080de7d4f0eSAndy Whitcroft 1081de7d4f0eSAndy Whitcroft # Pull in any empty extension lines. 1082de7d4f0eSAndy Whitcroft while ($ctx =~ /\\$/ && 1083de7d4f0eSAndy Whitcroft $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { 1084de7d4f0eSAndy Whitcroft $ctx .= $lines[$ctx_ln - 1]; 1085de7d4f0eSAndy Whitcroft $ctx_ln++; 1086de7d4f0eSAndy Whitcroft } 1087d8aaf121SAndy Whitcroft 1088d8aaf121SAndy Whitcroft if ($ctx =~ /\\$/) { 1089d8aaf121SAndy Whitcroft if ($ctx =~ /;/) { 1090de7d4f0eSAndy Whitcroft ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 1091d8aaf121SAndy Whitcroft } else { 1092de7d4f0eSAndy Whitcroft ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 1093d8aaf121SAndy Whitcroft } 10940a920b5bSAndy Whitcroft } 1095653d4876SAndy Whitcroft } 10960a920b5bSAndy Whitcroft 1097f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 1098f0a594c1SAndy Whitcroft if ($line =~ /\b(if|while|for|else)\b/) { 1099f0a594c1SAndy Whitcroft # Locate the end of the opening statement. 1100f0a594c1SAndy Whitcroft my @control = ctx_statement($linenr, $realcnt, 0); 1101f0a594c1SAndy Whitcroft my $nr = $linenr + (scalar(@control) - 1); 1102f0a594c1SAndy Whitcroft my $cnt = $realcnt - (scalar(@control) - 1); 1103f0a594c1SAndy Whitcroft 1104f0a594c1SAndy Whitcroft my $off = $realcnt - $cnt; 1105f0a594c1SAndy Whitcroft #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; 1106f0a594c1SAndy Whitcroft 1107f0a594c1SAndy Whitcroft # If this is is a braced statement group check it 1108f0a594c1SAndy Whitcroft if ($lines[$nr - 1] =~ /{\s*$/) { 1109f0a594c1SAndy Whitcroft my ($lvl, @block) = ctx_block_level($nr, $cnt); 1110f0a594c1SAndy Whitcroft 1111f0a594c1SAndy Whitcroft my $stmt = join(' ', @block); 111222f2a2efSAndy Whitcroft $stmt =~ s/(^[^{]*){//; 111322f2a2efSAndy Whitcroft my $before = $1; 111422f2a2efSAndy Whitcroft $stmt =~ s/}([^}]*$)//; 111522f2a2efSAndy Whitcroft my $after = $1; 1116f0a594c1SAndy Whitcroft 1117f0a594c1SAndy Whitcroft #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; 1118f0a594c1SAndy Whitcroft #print "stmt<$stmt>\n\n"; 1119f0a594c1SAndy Whitcroft 1120f0a594c1SAndy Whitcroft # Count the ;'s if there is fewer than two 1121f0a594c1SAndy Whitcroft # then there can only be one statement, 1122f0a594c1SAndy Whitcroft # if there is a brace inside we cannot 1123f0a594c1SAndy Whitcroft # trivially detect if its one statement. 1124f0a594c1SAndy Whitcroft # Also nested if's often require braces to 1125f0a594c1SAndy Whitcroft # disambiguate the else binding so shhh there. 1126f0a594c1SAndy Whitcroft my @semi = ($stmt =~ /;/g); 112722f2a2efSAndy Whitcroft push(@semi, "/**/") if ($stmt =~ m@/\*@); 1128f0a594c1SAndy Whitcroft ##print "semi<" . scalar(@semi) . ">\n"; 1129f0a594c1SAndy Whitcroft if ($lvl == 0 && scalar(@semi) < 2 && 113022f2a2efSAndy Whitcroft $stmt !~ /{/ && $stmt !~ /\bif\b/ && 113122f2a2efSAndy Whitcroft $before !~ /}/ && $after !~ /{/) { 1132f0a594c1SAndy Whitcroft my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; 1133f0a594c1SAndy Whitcroft shift(@block); 113422f2a2efSAndy Whitcroft WARN("braces {} are not necessary for single statement blocks\n" . $herectx); 1135f0a594c1SAndy Whitcroft } 1136f0a594c1SAndy Whitcroft } 1137f0a594c1SAndy Whitcroft } 1138f0a594c1SAndy Whitcroft 1139653d4876SAndy Whitcroft# don't include deprecated include files (uses RAW line) 11404a0df2efSAndy Whitcroft for my $inc (@dep_includes) { 1141653d4876SAndy Whitcroft if ($rawline =~ m@\#\s*include\s*\<$inc>@) { 1142de7d4f0eSAndy Whitcroft ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); 11430a920b5bSAndy Whitcroft } 11440a920b5bSAndy Whitcroft } 11450a920b5bSAndy Whitcroft 11464a0df2efSAndy Whitcroft# don't use deprecated functions 11474a0df2efSAndy Whitcroft for my $func (@dep_functions) { 114800df344fSAndy Whitcroft if ($line =~ /\b$func\b/) { 1149de7d4f0eSAndy Whitcroft ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); 11504a0df2efSAndy Whitcroft } 11514a0df2efSAndy Whitcroft } 11524a0df2efSAndy Whitcroft 11534a0df2efSAndy Whitcroft# no volatiles please 115400df344fSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { 1155de7d4f0eSAndy Whitcroft WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 11564a0df2efSAndy Whitcroft } 11574a0df2efSAndy Whitcroft 1158*9c0ca6f9SAndy Whitcroft# SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated 1159*9c0ca6f9SAndy Whitcroft if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) { 1160*9c0ca6f9SAndy Whitcroft ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr); 1161*9c0ca6f9SAndy Whitcroft } 1162*9c0ca6f9SAndy Whitcroft 116300df344fSAndy Whitcroft# warn about #if 0 116400df344fSAndy Whitcroft if ($line =~ /^.#\s*if\s+0\b/) { 1165de7d4f0eSAndy Whitcroft CHK("if this code is redundant consider removing it\n" . 1166de7d4f0eSAndy Whitcroft $herecurr); 11674a0df2efSAndy Whitcroft } 11684a0df2efSAndy Whitcroft 1169f0a594c1SAndy Whitcroft# check for needless kfree() checks 1170f0a594c1SAndy Whitcroft if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { 1171f0a594c1SAndy Whitcroft my $expr = $1; 1172f0a594c1SAndy Whitcroft if ($line =~ /\bkfree\(\Q$expr\E\);/) { 1173f0a594c1SAndy Whitcroft WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev); 1174f0a594c1SAndy Whitcroft } 1175f0a594c1SAndy Whitcroft } 1176f0a594c1SAndy Whitcroft 117700df344fSAndy Whitcroft# warn about #ifdefs in C files 117800df344fSAndy Whitcroft# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 117900df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 118000df344fSAndy Whitcroft# print "$herecurr"; 118100df344fSAndy Whitcroft# $clean = 0; 118200df344fSAndy Whitcroft# } 118300df344fSAndy Whitcroft 118422f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 118522f2a2efSAndy Whitcroft if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { 118622f2a2efSAndy Whitcroft ERROR("exactly one space required after that #$1\n" . $herecurr); 118722f2a2efSAndy Whitcroft } 118822f2a2efSAndy Whitcroft 11894a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 11904a0df2efSAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { 11914a0df2efSAndy Whitcroft my $which = $1; 11924a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1193de7d4f0eSAndy Whitcroft CHK("$1 definition without comment\n" . $herecurr); 11944a0df2efSAndy Whitcroft } 11954a0df2efSAndy Whitcroft } 11964a0df2efSAndy Whitcroft# check for memory barriers without a comment. 11974a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 11984a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 1199de7d4f0eSAndy Whitcroft CHK("memory barrier without comment\n" . $herecurr); 12004a0df2efSAndy Whitcroft } 12014a0df2efSAndy Whitcroft } 12024a0df2efSAndy Whitcroft# check of hardware specific defines 120322f2a2efSAndy Whitcroft if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 1204de7d4f0eSAndy Whitcroft CHK("architecture specific defines should be avoided\n" . $herecurr); 12050a920b5bSAndy Whitcroft } 1206653d4876SAndy Whitcroft 1207de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 1208de7d4f0eSAndy Whitcroft# storage class and type. 1209*9c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 1210*9c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 1211de7d4f0eSAndy Whitcroft ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 1212de7d4f0eSAndy Whitcroft } 1213de7d4f0eSAndy Whitcroft 1214de7d4f0eSAndy Whitcroft# check for new externs in .c files. 1215de7d4f0eSAndy Whitcroft if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { 1216de7d4f0eSAndy Whitcroft WARN("externs should be avoided in .c files\n" . $herecurr); 1217de7d4f0eSAndy Whitcroft } 1218de7d4f0eSAndy Whitcroft 1219de7d4f0eSAndy Whitcroft# checks for new __setup's 1220de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 1221de7d4f0eSAndy Whitcroft my $name = $1; 1222de7d4f0eSAndy Whitcroft 1223de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 1224de7d4f0eSAndy Whitcroft CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 1225de7d4f0eSAndy Whitcroft } 1226653d4876SAndy Whitcroft } 1227*9c0ca6f9SAndy Whitcroft 1228*9c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 1229*9c0ca6f9SAndy Whitcroft if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) { 1230*9c0ca6f9SAndy Whitcroft WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 1231*9c0ca6f9SAndy Whitcroft } 12320a920b5bSAndy Whitcroft } 12330a920b5bSAndy Whitcroft 12340a920b5bSAndy Whitcroft if ($chk_patch && !$is_patch) { 1235de7d4f0eSAndy Whitcroft ERROR("Does not appear to be a unified-diff format patch\n"); 12360a920b5bSAndy Whitcroft } 12370a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 1238de7d4f0eSAndy Whitcroft ERROR("Missing Signed-off-by: line(s)\n"); 12390a920b5bSAndy Whitcroft } 12400a920b5bSAndy Whitcroft 1241f0a594c1SAndy Whitcroft if ($clean == 0 && ($chk_patch || $is_patch)) { 1242f0a594c1SAndy Whitcroft print report_dump(); 1243f0a594c1SAndy Whitcroft } 12440a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 12450a920b5bSAndy Whitcroft print "Your patch has no obvious style problems and is ready for submission.\n" 12460a920b5bSAndy Whitcroft } 12470a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 12480a920b5bSAndy Whitcroft print "Your patch has style problems, please review. If any of these errors\n"; 12490a920b5bSAndy Whitcroft print "are false positives report them to the maintainer, see\n"; 12500a920b5bSAndy Whitcroft print "CHECKPATCH in MAINTAINERS.\n"; 12510a920b5bSAndy Whitcroft } 12520a920b5bSAndy Whitcroft return $clean; 12530a920b5bSAndy Whitcroft} 1254