1*0a920b5bSAndy Whitcroft#!/usr/bin/perl -w 2*0a920b5bSAndy Whitcroft# (c) 2001, Dave Jones. <[email protected]> (the file handling bit) 3*0a920b5bSAndy Whitcroft# (c) 2005, Joel Scohpp <[email protected]> (the ugly bit) 4*0a920b5bSAndy Whitcroft# (c) 2007, Andy Whitcroft <[email protected]> (new conditions, test suite, etc) 5*0a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2 6*0a920b5bSAndy Whitcroft 7*0a920b5bSAndy Whitcroftuse strict; 8*0a920b5bSAndy Whitcroft 9*0a920b5bSAndy Whitcroftmy $P = $0; 10*0a920b5bSAndy Whitcroft 11*0a920b5bSAndy Whitcroftmy $V = '0.01'; 12*0a920b5bSAndy Whitcroft 13*0a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 14*0a920b5bSAndy Whitcroft 15*0a920b5bSAndy Whitcroftmy $quiet = 0; 16*0a920b5bSAndy Whitcroftmy $tree = 1; 17*0a920b5bSAndy Whitcroftmy $chk_signoff = 1; 18*0a920b5bSAndy Whitcroftmy $chk_patch = 1; 19*0a920b5bSAndy WhitcroftGetOptions( 20*0a920b5bSAndy Whitcroft 'q|quiet' => \$quiet, 21*0a920b5bSAndy Whitcroft 'tree!' => \$tree, 22*0a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 23*0a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 24*0a920b5bSAndy Whitcroft) or exit; 25*0a920b5bSAndy Whitcroft 26*0a920b5bSAndy Whitcroftmy $exit = 0; 27*0a920b5bSAndy Whitcroft 28*0a920b5bSAndy Whitcroftif ($#ARGV < 0) { 29*0a920b5bSAndy Whitcroft print "usage: patchstylecheckemail.pl [options] patchfile\n"; 30*0a920b5bSAndy Whitcroft print "version: $V\n"; 31*0a920b5bSAndy Whitcroft print "options: -q => quiet\n"; 32*0a920b5bSAndy Whitcroft print " --no-tree => run without a kernel tree\n"; 33*0a920b5bSAndy Whitcroft exit(1); 34*0a920b5bSAndy Whitcroft} 35*0a920b5bSAndy Whitcroft 36*0a920b5bSAndy Whitcroftif ($tree && !top_of_kernel_tree()) { 37*0a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 38*0a920b5bSAndy Whitcroft exit(2); 39*0a920b5bSAndy Whitcroft} 40*0a920b5bSAndy Whitcroft 41*0a920b5bSAndy Whitcroftmy @deprecated = (); 42*0a920b5bSAndy Whitcroftmy $removal = 'Documentation/feature-removal-schedule.txt'; 43*0a920b5bSAndy Whitcroftif ($tree && -f $removal) { 44*0a920b5bSAndy Whitcroft open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; 45*0a920b5bSAndy Whitcroft while (<REMOVE>) { 46*0a920b5bSAndy Whitcroft if (/^Files:\s+(.*\S)/) { 47*0a920b5bSAndy Whitcroft for my $file (split(/[, ]+/, $1)) { 48*0a920b5bSAndy Whitcroft if ($file =~ m@include/(.*)@) { 49*0a920b5bSAndy Whitcroft push(@deprecated, $1); 50*0a920b5bSAndy Whitcroft } 51*0a920b5bSAndy Whitcroft } 52*0a920b5bSAndy Whitcroft } 53*0a920b5bSAndy Whitcroft } 54*0a920b5bSAndy Whitcroft} 55*0a920b5bSAndy Whitcroft 56*0a920b5bSAndy Whitcroftmy @lines = (); 57*0a920b5bSAndy Whitcroftwhile (<>) { 58*0a920b5bSAndy Whitcroft chomp; 59*0a920b5bSAndy Whitcroft push(@lines, $_); 60*0a920b5bSAndy Whitcroft if (eof(ARGV)) { 61*0a920b5bSAndy Whitcroft if (!process($ARGV, @lines)) { 62*0a920b5bSAndy Whitcroft $exit = 1; 63*0a920b5bSAndy Whitcroft } 64*0a920b5bSAndy Whitcroft @lines = (); 65*0a920b5bSAndy Whitcroft } 66*0a920b5bSAndy Whitcroft} 67*0a920b5bSAndy Whitcroft 68*0a920b5bSAndy Whitcroftexit($exit); 69*0a920b5bSAndy Whitcroft 70*0a920b5bSAndy Whitcroftsub top_of_kernel_tree { 71*0a920b5bSAndy Whitcroft if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") && 72*0a920b5bSAndy Whitcroft (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") && 73*0a920b5bSAndy Whitcroft (-d "Documentation") && (-d "arch") && (-d "include") && 74*0a920b5bSAndy Whitcroft (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") && 75*0a920b5bSAndy Whitcroft (-d "kernel") && (-d "lib") && (-d "scripts")) { 76*0a920b5bSAndy Whitcroft return 1; 77*0a920b5bSAndy Whitcroft } 78*0a920b5bSAndy Whitcroft return 0; 79*0a920b5bSAndy Whitcroft} 80*0a920b5bSAndy Whitcroft 81*0a920b5bSAndy Whitcroftsub expand_tabs { 82*0a920b5bSAndy Whitcroft my ($str) = @_; 83*0a920b5bSAndy Whitcroft 84*0a920b5bSAndy Whitcroft my $res = ''; 85*0a920b5bSAndy Whitcroft my $n = 0; 86*0a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 87*0a920b5bSAndy Whitcroft if ($c eq "\t") { 88*0a920b5bSAndy Whitcroft $res .= ' '; 89*0a920b5bSAndy Whitcroft $n++; 90*0a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 91*0a920b5bSAndy Whitcroft $res .= ' '; 92*0a920b5bSAndy Whitcroft } 93*0a920b5bSAndy Whitcroft next; 94*0a920b5bSAndy Whitcroft } 95*0a920b5bSAndy Whitcroft $res .= $c; 96*0a920b5bSAndy Whitcroft $n++; 97*0a920b5bSAndy Whitcroft } 98*0a920b5bSAndy Whitcroft 99*0a920b5bSAndy Whitcroft return $res; 100*0a920b5bSAndy Whitcroft} 101*0a920b5bSAndy Whitcroft 102*0a920b5bSAndy Whitcroftsub cat_vet { 103*0a920b5bSAndy Whitcroft my ($vet) = @_; 104*0a920b5bSAndy Whitcroft 105*0a920b5bSAndy Whitcroft $vet =~ s/\t/^I/; 106*0a920b5bSAndy Whitcroft $vet =~ s/$/\$/; 107*0a920b5bSAndy Whitcroft 108*0a920b5bSAndy Whitcroft return $vet; 109*0a920b5bSAndy Whitcroft} 110*0a920b5bSAndy Whitcroft 111*0a920b5bSAndy Whitcroftsub process { 112*0a920b5bSAndy Whitcroft my $filename = shift; 113*0a920b5bSAndy Whitcroft my @lines = @_; 114*0a920b5bSAndy Whitcroft 115*0a920b5bSAndy Whitcroft my $linenr=0; 116*0a920b5bSAndy Whitcroft my $prevline=""; 117*0a920b5bSAndy Whitcroft my $stashline=""; 118*0a920b5bSAndy Whitcroft 119*0a920b5bSAndy Whitcroft my $lineforcounting=''; 120*0a920b5bSAndy Whitcroft my $indent; 121*0a920b5bSAndy Whitcroft my $previndent=0; 122*0a920b5bSAndy Whitcroft my $stashindent=0; 123*0a920b5bSAndy Whitcroft 124*0a920b5bSAndy Whitcroft my $clean = 1; 125*0a920b5bSAndy Whitcroft my $signoff = 0; 126*0a920b5bSAndy Whitcroft my $is_patch = 0; 127*0a920b5bSAndy Whitcroft 128*0a920b5bSAndy Whitcroft # Trace the real file/line as we go. 129*0a920b5bSAndy Whitcroft my $realfile = ''; 130*0a920b5bSAndy Whitcroft my $realline = 0; 131*0a920b5bSAndy Whitcroft my $realcnt = 0; 132*0a920b5bSAndy Whitcroft my $here = ''; 133*0a920b5bSAndy Whitcroft my $in_comment = 0; 134*0a920b5bSAndy Whitcroft my $first_line = 0; 135*0a920b5bSAndy Whitcroft 136*0a920b5bSAndy Whitcroft foreach my $line (@lines) { 137*0a920b5bSAndy Whitcroft $linenr++; 138*0a920b5bSAndy Whitcroft 139*0a920b5bSAndy Whitcroft#extract the filename as it passes 140*0a920b5bSAndy Whitcroft if ($line=~/^\+\+\+\s+(\S+)/) { 141*0a920b5bSAndy Whitcroft $realfile=$1; 142*0a920b5bSAndy Whitcroft $in_comment = 0; 143*0a920b5bSAndy Whitcroft next; 144*0a920b5bSAndy Whitcroft } 145*0a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 146*0a920b5bSAndy Whitcroft if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { 147*0a920b5bSAndy Whitcroft $is_patch = 1; 148*0a920b5bSAndy Whitcroft $first_line = 1; 149*0a920b5bSAndy Whitcroft $in_comment = 0; 150*0a920b5bSAndy Whitcroft $realline=$1-1; 151*0a920b5bSAndy Whitcroft if (defined $2) { 152*0a920b5bSAndy Whitcroft $realcnt=$3+1; 153*0a920b5bSAndy Whitcroft } else { 154*0a920b5bSAndy Whitcroft $realcnt=1+1; 155*0a920b5bSAndy Whitcroft } 156*0a920b5bSAndy Whitcroft next; 157*0a920b5bSAndy Whitcroft } 158*0a920b5bSAndy Whitcroft 159*0a920b5bSAndy Whitcroft#track the line number as we move through the hunk 160*0a920b5bSAndy Whitcroft if ($line=~/^[ \+]/) { 161*0a920b5bSAndy Whitcroft $realline++; 162*0a920b5bSAndy Whitcroft $realcnt-- if ($realcnt != 0); 163*0a920b5bSAndy Whitcroft 164*0a920b5bSAndy Whitcroft # track any sort of multi-line comment. Obviously if 165*0a920b5bSAndy Whitcroft # the added text or context do not include the whole 166*0a920b5bSAndy Whitcroft # comment we will not see it. Such is life. 167*0a920b5bSAndy Whitcroft # 168*0a920b5bSAndy Whitcroft # Guestimate if this is a continuing comment. If this 169*0a920b5bSAndy Whitcroft # is the start of a diff block and this line starts 170*0a920b5bSAndy Whitcroft # ' *' then it is very likely a comment. 171*0a920b5bSAndy Whitcroft if ($first_line and $line =~ m@^.\s*\*@) { 172*0a920b5bSAndy Whitcroft $in_comment = 1; 173*0a920b5bSAndy Whitcroft } 174*0a920b5bSAndy Whitcroft if ($line =~ m@/\*@) { 175*0a920b5bSAndy Whitcroft $in_comment = 1; 176*0a920b5bSAndy Whitcroft } 177*0a920b5bSAndy Whitcroft if ($line =~ m@\*/@) { 178*0a920b5bSAndy Whitcroft $in_comment = 0; 179*0a920b5bSAndy Whitcroft } 180*0a920b5bSAndy Whitcroft 181*0a920b5bSAndy Whitcroft $lineforcounting = $line; 182*0a920b5bSAndy Whitcroft $lineforcounting =~ s/^\+//; 183*0a920b5bSAndy Whitcroft $lineforcounting = expand_tabs($lineforcounting); 184*0a920b5bSAndy Whitcroft 185*0a920b5bSAndy Whitcroft my ($white) = ($lineforcounting =~ /^(\s*)/); 186*0a920b5bSAndy Whitcroft $indent = length($white); 187*0a920b5bSAndy Whitcroft 188*0a920b5bSAndy Whitcroft # Track the previous line. 189*0a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 190*0a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 191*0a920b5bSAndy Whitcroft $first_line = 0; 192*0a920b5bSAndy Whitcroft } 193*0a920b5bSAndy Whitcroft 194*0a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 195*0a920b5bSAndy Whitcroft $here = "PATCH: $ARGV:$linenr:"; 196*0a920b5bSAndy Whitcroft $here .= "\nFILE: $realfile:$realline:" if ($realcnt != 0); 197*0a920b5bSAndy Whitcroft 198*0a920b5bSAndy Whitcroft my $herecurr = "$here\n$line\n\n"; 199*0a920b5bSAndy Whitcroft my $hereprev = "$here\n$prevline\n$line\n\n"; 200*0a920b5bSAndy Whitcroft 201*0a920b5bSAndy Whitcroft#check the patch for a signoff: 202*0a920b5bSAndy Whitcroft if ($line =~ /^\s*Signed-off-by:\s/) { 203*0a920b5bSAndy Whitcroft $signoff++; 204*0a920b5bSAndy Whitcroft 205*0a920b5bSAndy Whitcroft } elsif ($line =~ /^\s*signed-off-by:/i) { 206*0a920b5bSAndy Whitcroft if (!($line =~ /^\s*Signed-off-by:/)) { 207*0a920b5bSAndy Whitcroft print "use Signed-off-by:\n"; 208*0a920b5bSAndy Whitcroft print "$herecurr"; 209*0a920b5bSAndy Whitcroft $clean = 0; 210*0a920b5bSAndy Whitcroft } 211*0a920b5bSAndy Whitcroft if ($line =~ /^\s*signed-off-by:\S/i) { 212*0a920b5bSAndy Whitcroft print "need space after Signed-off-by:\n"; 213*0a920b5bSAndy Whitcroft print "$herecurr"; 214*0a920b5bSAndy Whitcroft $clean = 0; 215*0a920b5bSAndy Whitcroft } 216*0a920b5bSAndy Whitcroft } 217*0a920b5bSAndy Whitcroft 218*0a920b5bSAndy Whitcroft#ignore lines not being added 219*0a920b5bSAndy Whitcroft if ($line=~/^[^\+]/) {next;} 220*0a920b5bSAndy Whitcroft 221*0a920b5bSAndy Whitcroft# check we are in a valid source file *.[hcsS] if not then ignore this hunk 222*0a920b5bSAndy Whitcroft next if ($realfile !~ /\.[hcsS]$/); 223*0a920b5bSAndy Whitcroft 224*0a920b5bSAndy Whitcroft#trailing whitespace 225*0a920b5bSAndy Whitcroft if ($line=~/\S\s+$/) { 226*0a920b5bSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n\n"; 227*0a920b5bSAndy Whitcroft print "trailing whitespace\n"; 228*0a920b5bSAndy Whitcroft print "$herevet"; 229*0a920b5bSAndy Whitcroft $clean = 0; 230*0a920b5bSAndy Whitcroft } 231*0a920b5bSAndy Whitcroft#80 column limit 232*0a920b5bSAndy Whitcroft if (!($prevline=~/\/\*\*/) && length($lineforcounting) > 80) { 233*0a920b5bSAndy Whitcroft print "line over 80 characters\n"; 234*0a920b5bSAndy Whitcroft print "$herecurr"; 235*0a920b5bSAndy Whitcroft $clean = 0; 236*0a920b5bSAndy Whitcroft } 237*0a920b5bSAndy Whitcroft 238*0a920b5bSAndy Whitcroft# check we are in a valid source file *.[hc] if not then ignore this hunk 239*0a920b5bSAndy Whitcroft next if ($realfile !~ /\.[hc]$/); 240*0a920b5bSAndy Whitcroft 241*0a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 242*0a920b5bSAndy Whitcroft# more than 8 must use tabs. 243*0a920b5bSAndy Whitcroft if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s* \s*/) { 244*0a920b5bSAndy Whitcroft my $herevet = "$here\n" . cat_vet($line) . "\n\n"; 245*0a920b5bSAndy Whitcroft print "use tabs not spaces\n"; 246*0a920b5bSAndy Whitcroft print "$herevet"; 247*0a920b5bSAndy Whitcroft $clean = 0; 248*0a920b5bSAndy Whitcroft } 249*0a920b5bSAndy Whitcroft 250*0a920b5bSAndy Whitcroft # 251*0a920b5bSAndy Whitcroft # The rest of our checks refer specifically to C style 252*0a920b5bSAndy Whitcroft # only apply those _outside_ comments. 253*0a920b5bSAndy Whitcroft # 254*0a920b5bSAndy Whitcroft next if ($in_comment); 255*0a920b5bSAndy Whitcroft 256*0a920b5bSAndy Whitcroft# no C99 // comments 257*0a920b5bSAndy Whitcroft if ($line =~ m@//@ and !($line =~ m@\".*//.*\"@)) { 258*0a920b5bSAndy Whitcroft print "do not use C99 // comments\n"; 259*0a920b5bSAndy Whitcroft print "$herecurr"; 260*0a920b5bSAndy Whitcroft $clean = 0; 261*0a920b5bSAndy Whitcroft } 262*0a920b5bSAndy Whitcroft 263*0a920b5bSAndy Whitcroft # Remove comments from the line before processing. 264*0a920b5bSAndy Whitcroft $line =~ s@/\*.*\*/@@g; 265*0a920b5bSAndy Whitcroft $line =~ s@/\*.*@@; 266*0a920b5bSAndy Whitcroft $line =~ s@.*\*/@@; 267*0a920b5bSAndy Whitcroft $line =~ s@//.*@@; 268*0a920b5bSAndy Whitcroft 269*0a920b5bSAndy Whitcroft#EXPORT_SYMBOL should immediately follow its function closing }. 270*0a920b5bSAndy Whitcroft if (($line =~ /EXPORT_SYMBOL.*\(.*\)/) || 271*0a920b5bSAndy Whitcroft ($line =~ /EXPORT_UNUSED_SYMBOL.*\(.*\)/)) { 272*0a920b5bSAndy Whitcroft if (($prevline !~ /^}/) && 273*0a920b5bSAndy Whitcroft ($prevline !~ /^\+}/) && 274*0a920b5bSAndy Whitcroft ($prevline !~ /^ }/)) { 275*0a920b5bSAndy Whitcroft print "EXPORT_SYMBOL(func); should immediately follow its function\n"; 276*0a920b5bSAndy Whitcroft print "$herecurr"; 277*0a920b5bSAndy Whitcroft $clean = 0; 278*0a920b5bSAndy Whitcroft } 279*0a920b5bSAndy Whitcroft } 280*0a920b5bSAndy Whitcroft 281*0a920b5bSAndy Whitcroft # check for static initialisers. 282*0a920b5bSAndy Whitcroft if ($line=~/\s*static\s.*=\s+(0|NULL);/) { 283*0a920b5bSAndy Whitcroft print "do not initialise statics to 0 or NULL\n"; 284*0a920b5bSAndy Whitcroft print "$herecurr"; 285*0a920b5bSAndy Whitcroft $clean = 0; 286*0a920b5bSAndy Whitcroft } 287*0a920b5bSAndy Whitcroft 288*0a920b5bSAndy Whitcroft # check for new typedefs. 289*0a920b5bSAndy Whitcroft if ($line=~/\s*typedef\s/) { 290*0a920b5bSAndy Whitcroft print "do not add new typedefs\n"; 291*0a920b5bSAndy Whitcroft print "$herecurr"; 292*0a920b5bSAndy Whitcroft $clean = 0; 293*0a920b5bSAndy Whitcroft } 294*0a920b5bSAndy Whitcroft 295*0a920b5bSAndy Whitcroft# * goes on variable not on type 296*0a920b5bSAndy Whitcroft if ($line=~/[A-Za-z\d_]+\* [A-Za-z\d_]+/) { 297*0a920b5bSAndy Whitcroft print "\"foo* bar\" should be \"foo *bar\"\n"; 298*0a920b5bSAndy Whitcroft print "$herecurr"; 299*0a920b5bSAndy Whitcroft $clean = 0; 300*0a920b5bSAndy Whitcroft } 301*0a920b5bSAndy Whitcroft 302*0a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 303*0a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 304*0a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 305*0a920b5bSAndy Whitcroft# print "$herecurr"; 306*0a920b5bSAndy Whitcroft# $clean = 0; 307*0a920b5bSAndy Whitcroft# } 308*0a920b5bSAndy Whitcroft 309*0a920b5bSAndy Whitcroft# printk should use KERN_* levels 310*0a920b5bSAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)/) { 311*0a920b5bSAndy Whitcroft print "printk() should include KERN_ facility level\n"; 312*0a920b5bSAndy Whitcroft print "$herecurr"; 313*0a920b5bSAndy Whitcroft $clean = 0; 314*0a920b5bSAndy Whitcroft } 315*0a920b5bSAndy Whitcroft 316*0a920b5bSAndy Whitcroft#function brace can't be on same line, except for #defines of do while, or if closed on same line 317*0a920b5bSAndy Whitcroft if (($line=~/[A-Za-z\d_]+\**\s+\**[A-Za-z\d_]+\(.*\).* {/) and 318*0a920b5bSAndy Whitcroft !($line=~/\#define.*do\s{/) and !($line=~/}/)) { 319*0a920b5bSAndy Whitcroft print "braces following function declarations go on the next line\n"; 320*0a920b5bSAndy Whitcroft print "$herecurr"; 321*0a920b5bSAndy Whitcroft $clean = 0; 322*0a920b5bSAndy Whitcroft } 323*0a920b5bSAndy Whitcroft my $opline = $line; 324*0a920b5bSAndy Whitcroft $opline =~ s/^.//; 325*0a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 326*0a920b5bSAndy Whitcroft # Check operator spacing. 327*0a920b5bSAndy Whitcroft my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline); 328*0a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 329*0a920b5bSAndy Whitcroft # $wN says we have white-space before or after 330*0a920b5bSAndy Whitcroft # $sN says we have a separator before or after 331*0a920b5bSAndy Whitcroft # $oN says we have another operator before or after 332*0a920b5bSAndy Whitcroft my $w1 = $elements[$n] =~ /\s$/; 333*0a920b5bSAndy Whitcroft my $s1 = $elements[$n] =~ /(\[|\(|\s)$/; 334*0a920b5bSAndy Whitcroft my $o1 = $elements[$n] eq ''; 335*0a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 336*0a920b5bSAndy Whitcroft my $w2 = 1; 337*0a920b5bSAndy Whitcroft my $s2 = 1; 338*0a920b5bSAndy Whitcroft my $o2 = 0; 339*0a920b5bSAndy Whitcroft # If we have something after the operator handle it. 340*0a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 341*0a920b5bSAndy Whitcroft $w2 = $elements[$n + 2] =~ /^\s/; 342*0a920b5bSAndy Whitcroft $s2 = $elements[$n + 2] =~ /^(\s|\)|\]|;)/; 343*0a920b5bSAndy Whitcroft $o2 = $elements[$n + 2] eq ''; 344*0a920b5bSAndy Whitcroft } 345*0a920b5bSAndy Whitcroft 346*0a920b5bSAndy Whitcroft # Generate the context. 347*0a920b5bSAndy Whitcroft my $at = "here: "; 348*0a920b5bSAndy Whitcroft for (my $m = $n; $m >= 0; $m--) { 349*0a920b5bSAndy Whitcroft if ($elements[$m] ne '') { 350*0a920b5bSAndy Whitcroft $at .= $elements[$m]; 351*0a920b5bSAndy Whitcroft last; 352*0a920b5bSAndy Whitcroft } 353*0a920b5bSAndy Whitcroft } 354*0a920b5bSAndy Whitcroft $at .= $op; 355*0a920b5bSAndy Whitcroft for (my $m = $n + 2; defined $elements[$m]; $m++) { 356*0a920b5bSAndy Whitcroft if ($elements[$m] ne '') { 357*0a920b5bSAndy Whitcroft $at .= $elements[$m]; 358*0a920b5bSAndy Whitcroft last; 359*0a920b5bSAndy Whitcroft } 360*0a920b5bSAndy Whitcroft } 361*0a920b5bSAndy Whitcroft 362*0a920b5bSAndy Whitcroft ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n"; 363*0a920b5bSAndy Whitcroft # Skip things apparently in quotes. 364*0a920b5bSAndy Whitcroft next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); 365*0a920b5bSAndy Whitcroft 366*0a920b5bSAndy Whitcroft # We need ; as an operator. // is a comment. 367*0a920b5bSAndy Whitcroft if ($op eq ';' or $op eq '//') { 368*0a920b5bSAndy Whitcroft 369*0a920b5bSAndy Whitcroft # -> should have no spaces 370*0a920b5bSAndy Whitcroft } elsif ($op eq '->') { 371*0a920b5bSAndy Whitcroft if ($s1 or $s2) { 372*0a920b5bSAndy Whitcroft print "no spaces around that '$op' $at\n"; 373*0a920b5bSAndy Whitcroft print "$herecurr"; 374*0a920b5bSAndy Whitcroft $clean = 0; 375*0a920b5bSAndy Whitcroft } 376*0a920b5bSAndy Whitcroft 377*0a920b5bSAndy Whitcroft # , must have a space on the right. 378*0a920b5bSAndy Whitcroft } elsif ($op eq ',') { 379*0a920b5bSAndy Whitcroft if (!$s2) { 380*0a920b5bSAndy Whitcroft print "need space after that '$op' $at\n"; 381*0a920b5bSAndy Whitcroft print "$herecurr"; 382*0a920b5bSAndy Whitcroft $clean = 0; 383*0a920b5bSAndy Whitcroft } 384*0a920b5bSAndy Whitcroft 385*0a920b5bSAndy Whitcroft # unary ! and unary ~ are allowed no space on the right 386*0a920b5bSAndy Whitcroft } elsif ($op eq '!' or $op eq '~') { 387*0a920b5bSAndy Whitcroft if (!$s1 && !$o1) { 388*0a920b5bSAndy Whitcroft print "need space before that '$op' $at\n"; 389*0a920b5bSAndy Whitcroft print "$herecurr"; 390*0a920b5bSAndy Whitcroft $clean = 0; 391*0a920b5bSAndy Whitcroft } 392*0a920b5bSAndy Whitcroft if ($s2) { 393*0a920b5bSAndy Whitcroft print "no space after that '$op' $at\n"; 394*0a920b5bSAndy Whitcroft print "$herecurr"; 395*0a920b5bSAndy Whitcroft $clean = 0; 396*0a920b5bSAndy Whitcroft } 397*0a920b5bSAndy Whitcroft 398*0a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 399*0a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 400*0a920b5bSAndy Whitcroft if (($s1 && $s2) || ((!$s1 && !$o1) && (!$s2 && !$o2))) { 401*0a920b5bSAndy Whitcroft print "need space one side of that '$op' $at\n"; 402*0a920b5bSAndy Whitcroft print "$herecurr"; 403*0a920b5bSAndy Whitcroft $clean = 0; 404*0a920b5bSAndy Whitcroft } 405*0a920b5bSAndy Whitcroft 406*0a920b5bSAndy Whitcroft # & is both unary and binary 407*0a920b5bSAndy Whitcroft # unary: 408*0a920b5bSAndy Whitcroft # a &b 409*0a920b5bSAndy Whitcroft # binary (consistent spacing): 410*0a920b5bSAndy Whitcroft # a&b OK 411*0a920b5bSAndy Whitcroft # a & b OK 412*0a920b5bSAndy Whitcroft # 413*0a920b5bSAndy Whitcroft # boiling down to: if there is a space on the right then there 414*0a920b5bSAndy Whitcroft # should be one on the left. 415*0a920b5bSAndy Whitcroft # 416*0a920b5bSAndy Whitcroft # - is the same 417*0a920b5bSAndy Whitcroft # 418*0a920b5bSAndy Whitcroft # * is the same only adding: 419*0a920b5bSAndy Whitcroft # type: 420*0a920b5bSAndy Whitcroft # (foo *) 421*0a920b5bSAndy Whitcroft # (foo **) 422*0a920b5bSAndy Whitcroft # 423*0a920b5bSAndy Whitcroft } elsif ($op eq '&' or $op eq '-' or $op eq '*') { 424*0a920b5bSAndy Whitcroft if ($w2 and !$w1) { 425*0a920b5bSAndy Whitcroft print "need space before that '$op' $at\n"; 426*0a920b5bSAndy Whitcroft print "$herecurr"; 427*0a920b5bSAndy Whitcroft $clean = 0; 428*0a920b5bSAndy Whitcroft } 429*0a920b5bSAndy Whitcroft 430*0a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 431*0a920b5bSAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or 432*0a920b5bSAndy Whitcroft $op eq '^' or $op eq '|') 433*0a920b5bSAndy Whitcroft { 434*0a920b5bSAndy Whitcroft if ($s1 != $s2) { 435*0a920b5bSAndy Whitcroft print "need consistent spacing around '$op' $at\n"; 436*0a920b5bSAndy Whitcroft print "$herecurr"; 437*0a920b5bSAndy Whitcroft $clean = 0; 438*0a920b5bSAndy Whitcroft } 439*0a920b5bSAndy Whitcroft 440*0a920b5bSAndy Whitcroft # All the others need spaces both sides. 441*0a920b5bSAndy Whitcroft } elsif (!$s1 or !$s2) { 442*0a920b5bSAndy Whitcroft print "need spaces around that '$op' $at\n"; 443*0a920b5bSAndy Whitcroft print "$herecurr"; 444*0a920b5bSAndy Whitcroft $clean = 0; 445*0a920b5bSAndy Whitcroft } 446*0a920b5bSAndy Whitcroft } 447*0a920b5bSAndy Whitcroft } 448*0a920b5bSAndy Whitcroft 449*0a920b5bSAndy Whitcroft#need space before brace following if, while, etc 450*0a920b5bSAndy Whitcroft if ($line=~/\(.*\){/) { 451*0a920b5bSAndy Whitcroft print "need a space before the brace\n"; 452*0a920b5bSAndy Whitcroft print "$herecurr"; 453*0a920b5bSAndy Whitcroft $clean = 0; 454*0a920b5bSAndy Whitcroft } 455*0a920b5bSAndy Whitcroft 456*0a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 457*0a920b5bSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:/ and 458*0a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 459*0a920b5bSAndy Whitcroft print "labels should not be indented\n"; 460*0a920b5bSAndy Whitcroft print "$herecurr"; 461*0a920b5bSAndy Whitcroft $clean = 0; 462*0a920b5bSAndy Whitcroft } 463*0a920b5bSAndy Whitcroft 464*0a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 465*0a920b5bSAndy Whitcroft if ($line=~/(if|while|for|switch)\(/) { 466*0a920b5bSAndy Whitcroft print "need a space before the open parenthesis\n"; 467*0a920b5bSAndy Whitcroft print "$herecurr"; 468*0a920b5bSAndy Whitcroft $clean = 0; 469*0a920b5bSAndy Whitcroft } 470*0a920b5bSAndy Whitcroft 471*0a920b5bSAndy Whitcroft# Check for illegal assignment in if conditional. 472*0a920b5bSAndy Whitcroft if ($line=~/(if|while)\s*\(.*[^<>!=]=[^=].*\)/) { 473*0a920b5bSAndy Whitcroft print "do not use assignment in if condition\n"; 474*0a920b5bSAndy Whitcroft print "$herecurr"; 475*0a920b5bSAndy Whitcroft $clean = 0; 476*0a920b5bSAndy Whitcroft } 477*0a920b5bSAndy Whitcroft 478*0a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 479*0a920b5bSAndy Whitcroft # indent level to be relevant to each other. 480*0a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 481*0a920b5bSAndy Whitcroft $previndent == $indent) { 482*0a920b5bSAndy Whitcroft print "else should follow close brace\n"; 483*0a920b5bSAndy Whitcroft print "$hereprev"; 484*0a920b5bSAndy Whitcroft $clean = 0; 485*0a920b5bSAndy Whitcroft } 486*0a920b5bSAndy Whitcroft 487*0a920b5bSAndy Whitcroft # Check for switch () {<nl>case, these must be at the 488*0a920b5bSAndy Whitcroft # same indent. We will only catch the first one, as our 489*0a920b5bSAndy Whitcroft # context is very small but people tend to be consistent 490*0a920b5bSAndy Whitcroft # so we will catch them out more often than not. 491*0a920b5bSAndy Whitcroft if ($prevline=~/\s*switch\s*\(.*\)/ and $line=~/\s*case\s+/ 492*0a920b5bSAndy Whitcroft and $previndent != $indent) { 493*0a920b5bSAndy Whitcroft print "switch and case should be at the same indent\n"; 494*0a920b5bSAndy Whitcroft print "$hereprev"; 495*0a920b5bSAndy Whitcroft $clean = 0; 496*0a920b5bSAndy Whitcroft } 497*0a920b5bSAndy Whitcroft 498*0a920b5bSAndy Whitcroft#studly caps, commented out until figure out how to distinguish between use of existing and adding new 499*0a920b5bSAndy Whitcroft# if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { 500*0a920b5bSAndy Whitcroft# print "No studly caps, use _\n"; 501*0a920b5bSAndy Whitcroft# print "$herecurr"; 502*0a920b5bSAndy Whitcroft# $clean = 0; 503*0a920b5bSAndy Whitcroft# } 504*0a920b5bSAndy Whitcroft 505*0a920b5bSAndy Whitcroft#no spaces allowed after \ in define 506*0a920b5bSAndy Whitcroft if ($line=~/\#define.*\\\s$/) { 507*0a920b5bSAndy Whitcroft print("Whitepspace after \\ makes next lines useless\n"); 508*0a920b5bSAndy Whitcroft print "$herecurr"; 509*0a920b5bSAndy Whitcroft $clean = 0; 510*0a920b5bSAndy Whitcroft } 511*0a920b5bSAndy Whitcroft 512*0a920b5bSAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available. 513*0a920b5bSAndy Whitcroft if ($tree && $line =~ qr|\s*\#\s*include\s*\<asm\/(.*)\.h\>|) { 514*0a920b5bSAndy Whitcroft my $checkfile = "include/linux/$1.h"; 515*0a920b5bSAndy Whitcroft if (-f $checkfile) { 516*0a920b5bSAndy Whitcroft print "Use #include <linux/$1.h> instead of <asm/$1.h>\n"; 517*0a920b5bSAndy Whitcroft print $herecurr; 518*0a920b5bSAndy Whitcroft $clean = 0; 519*0a920b5bSAndy Whitcroft } 520*0a920b5bSAndy Whitcroft } 521*0a920b5bSAndy Whitcroft 522*0a920b5bSAndy Whitcroft#if/while/etc brace do not go on next line, unless #defining a do while loop, or if that brace on the next line is for something else 523*0a920b5bSAndy Whitcroft if ($prevline=~/(if|while|for|switch)\s*\(/) { 524*0a920b5bSAndy Whitcroft my @opened = $prevline=~/\(/g; 525*0a920b5bSAndy Whitcroft my @closed = $prevline=~/\)/g; 526*0a920b5bSAndy Whitcroft my $nr_line = $linenr; 527*0a920b5bSAndy Whitcroft my $remaining = $realcnt; 528*0a920b5bSAndy Whitcroft my $next_line = $line; 529*0a920b5bSAndy Whitcroft my $extra_lines = 0; 530*0a920b5bSAndy Whitcroft my $display_segment = $prevline; 531*0a920b5bSAndy Whitcroft 532*0a920b5bSAndy Whitcroft while ($remaining > 0 && scalar @opened > scalar @closed) { 533*0a920b5bSAndy Whitcroft $prevline .= $next_line; 534*0a920b5bSAndy Whitcroft $display_segment .= "\n" . $next_line; 535*0a920b5bSAndy Whitcroft $next_line = $lines[$nr_line]; 536*0a920b5bSAndy Whitcroft $nr_line++; 537*0a920b5bSAndy Whitcroft $remaining--; 538*0a920b5bSAndy Whitcroft 539*0a920b5bSAndy Whitcroft @opened = $prevline=~/\(/g; 540*0a920b5bSAndy Whitcroft @closed = $prevline=~/\)/g; 541*0a920b5bSAndy Whitcroft } 542*0a920b5bSAndy Whitcroft 543*0a920b5bSAndy Whitcroft if (($prevline=~/(if|while|for|switch)\s*\(.*\)\s*$/) and ($next_line=~/{/) and 544*0a920b5bSAndy Whitcroft !($next_line=~/(if|while|for)/) and !($next_line=~/\#define.*do.*while/)) { 545*0a920b5bSAndy Whitcroft print "That { should be on the previous line\n"; 546*0a920b5bSAndy Whitcroft print "$display_segment\n$next_line\n\n"; 547*0a920b5bSAndy Whitcroft $clean = 0; 548*0a920b5bSAndy Whitcroft } 549*0a920b5bSAndy Whitcroft } 550*0a920b5bSAndy Whitcroft 551*0a920b5bSAndy Whitcroft#multiline macros should be enclosed in a do while loop 552*0a920b5bSAndy Whitcroft if (($prevline=~/\#define.*\\/) and !($prevline=~/do\s+{/) and 553*0a920b5bSAndy Whitcroft !($prevline=~/\(\{/) and ($line=~/;\s*\\/) and 554*0a920b5bSAndy Whitcroft !($line=~/do.*{/) and !($line=~/\(\{/)) { 555*0a920b5bSAndy Whitcroft print "Macros with multiple statements should be enclosed in a do - while loop\n"; 556*0a920b5bSAndy Whitcroft print "$hereprev"; 557*0a920b5bSAndy Whitcroft $clean = 0; 558*0a920b5bSAndy Whitcroft } 559*0a920b5bSAndy Whitcroft 560*0a920b5bSAndy Whitcroft# don't include deprecated include files 561*0a920b5bSAndy Whitcroft for my $inc (@deprecated) { 562*0a920b5bSAndy Whitcroft if ($line =~ m@\#\s*include\s*\<$inc>@) { 563*0a920b5bSAndy Whitcroft print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n"; 564*0a920b5bSAndy Whitcroft print "$herecurr"; 565*0a920b5bSAndy Whitcroft $clean = 0; 566*0a920b5bSAndy Whitcroft } 567*0a920b5bSAndy Whitcroft } 568*0a920b5bSAndy Whitcroft 569*0a920b5bSAndy Whitcroft# don't use kernel_thread() 570*0a920b5bSAndy Whitcroft if ($line =~ /\bkernel_thread\b/) { 571*0a920b5bSAndy Whitcroft print "Don't use kernel_thread(), use kthread(): see Documentation/feature-removal-schedule.txt\n"; 572*0a920b5bSAndy Whitcroft print "$herecurr"; 573*0a920b5bSAndy Whitcroft $clean = 0; 574*0a920b5bSAndy Whitcroft } 575*0a920b5bSAndy Whitcroft } 576*0a920b5bSAndy Whitcroft 577*0a920b5bSAndy Whitcroft if ($chk_patch && !$is_patch) { 578*0a920b5bSAndy Whitcroft $clean = 0; 579*0a920b5bSAndy Whitcroft print "Does not appear to be a unified-diff format patch\n"; 580*0a920b5bSAndy Whitcroft } 581*0a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 582*0a920b5bSAndy Whitcroft $clean = 0; 583*0a920b5bSAndy Whitcroft print "Missing Signed-off-by: line(s)\n"; 584*0a920b5bSAndy Whitcroft } 585*0a920b5bSAndy Whitcroft 586*0a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 587*0a920b5bSAndy Whitcroft print "Your patch has no obvious style problems and is ready for submission.\n" 588*0a920b5bSAndy Whitcroft } 589*0a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 590*0a920b5bSAndy Whitcroft print "Your patch has style problems, please review. If any of these errors\n"; 591*0a920b5bSAndy Whitcroft print "are false positives report them to the maintainer, see\n"; 592*0a920b5bSAndy Whitcroft print "CHECKPATCH in MAINTAINERS.\n"; 593*0a920b5bSAndy Whitcroft } 594*0a920b5bSAndy Whitcroft return $clean; 595*0a920b5bSAndy Whitcroft} 596