semaphore: Remove mutex emulation
[pandora-kernel.git] / scripts / checkpatch.pl
index 2039acd..e3c7fc0 100755 (executable)
@@ -2,7 +2,7 @@
 # (c) 2001, Dave Jones. (the file handling bit)
 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
-# (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
+# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
 # Licensed under the terms of the GNU GPL License version 2
 
 use strict;
@@ -10,7 +10,7 @@ use strict;
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.30';
+my $V = '0.31';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -103,6 +103,8 @@ for my $key (keys %debug) {
        die "$@" if ($@);
 }
 
+my $rpt_cleaners = 0;
+
 if ($terse) {
        $emacs = 1;
        $quiet++;
@@ -150,6 +152,20 @@ our $Sparse        = qr{
 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
 our $Attribute = qr{
                        const|
+                       __percpu|
+                       __nocast|
+                       __safe|
+                       __bitwise__|
+                       __packed__|
+                       __packed2__|
+                       __naked|
+                       __maybe_unused|
+                       __always_unused|
+                       __noreturn|
+                       __used|
+                       __cold|
+                       __noclone|
+                       __deprecated|
                        __read_mostly|
                        __kprobes|
                        __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
@@ -675,15 +691,15 @@ sub ctx_block_get {
                $blk .= $rawlines[$line];
 
                # Handle nested #if/#else.
-               if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
+               if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
                        push(@stack, $level);
-               } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
+               } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
                        $level = $stack[$#stack - 1];
-               } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
+               } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
                        $level = pop(@stack);
                }
 
-               foreach my $c (split(//, $rawlines[$line])) {
+               foreach my $c (split(//, $lines[$line])) {
                        ##print "C<$c>L<$level><$open$close>O<$off>\n";
                        if ($off > 0) {
                                $off--;
@@ -843,7 +859,12 @@ sub annotate_values {
                                $av_preprocessor = 0;
                        }
 
-               } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\()/) {
+               } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) {
+                       print "CAST($1)\n" if ($dbg_values > 1);
+                       push(@av_paren_type, $type);
+                       $type = 'C';
+
+               } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
                        print "DECLARE($1)\n" if ($dbg_values > 1);
                        $type = 'T';
 
@@ -1308,7 +1329,11 @@ sub process {
                $here = "#$realline: " if ($file);
 
                # extract the filename as it passes
-               if ($line=~/^\+\+\+\s+(\S+)/) {
+               if ($line =~ /^diff --git.*?(\S+)$/) {
+                       $realfile = $1;
+                       $realfile =~ s@^([^/]*)/@@;
+
+               } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
                        $realfile = $1;
                        $realfile =~ s@^([^/]*)/@@;
 
@@ -1332,6 +1357,14 @@ sub process {
 
                $cnt_lines++ if ($realcnt != 0);
 
+# Check for incorrect file permissions
+               if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
+                       my $permhere = $here . "FILE: $realfile\n";
+                       if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) {
+                               ERROR("do not set execute permissions for source files\n" . $permhere);
+                       }
+               }
+
 #check the patch for a signoff:
                if ($line =~ /^\s*signed-off-by:/i) {
                        # This is a signoff, if ugly, so do not double report.
@@ -1389,21 +1422,38 @@ sub process {
                } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
                        ERROR("trailing whitespace\n" . $herevet);
+                       $rpt_cleaners = 1;
                }
 
 # check for Kconfig help text having a real description
+# Only applies when adding the entry originally, after that we do not have
+# sufficient context to determine whether it is indeed long enough.
                if ($realfile =~ /Kconfig/ &&
-                   $line =~ /\+?\s*(---)?help(---)?$/) {
+                   $line =~ /\+\s*(?:---)?help(?:---)?$/) {
                        my $length = 0;
-                       for (my $l = $linenr; defined($lines[$l]); $l++) {
-                               my $f = $lines[$l];
+                       my $cnt = $realcnt;
+                       my $ln = $linenr + 1;
+                       my $f;
+                       my $is_end = 0;
+                       while ($cnt > 0 && defined $lines[$ln - 1]) {
+                               $f = $lines[$ln - 1];
+                               $cnt-- if ($lines[$ln - 1] !~ /^-/);
+                               $is_end = $lines[$ln - 1] =~ /^\+/;
+                               $ln++;
+
+                               next if ($f =~ /^-/);
+                               $f =~ s/^.//;
                                $f =~ s/#.*//;
                                $f =~ s/^\s+//;
                                next if ($f =~ /^$/);
-                               last if ($f =~ /^\s*config\s/);
+                               if ($f =~ /^\s*config\s/) {
+                                       $is_end = 1;
+                                       last;
+                               }
                                $length++;
                        }
-                       WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4);
+                       WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4);
+                       #print "is_end<$is_end> length<$length>\n";
                }
 
 # check we are in a valid source file if not then ignore this hunk
@@ -1450,6 +1500,7 @@ sub process {
                    $rawline =~ /^\+\s*        \s*/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
                        ERROR("code indent should use tabs where possible\n" . $herevet);
+                       $rpt_cleaners = 1;
                }
 
 # check for space before tabs.
@@ -1459,10 +1510,13 @@ sub process {
                }
 
 # check for spaces at the beginning of a line.
-               if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/)  {
+# Exceptions:
+#  1) within comments
+#  2) indented preprocessor commands
+#  3) hanging labels
+               if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/)  {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
-                       WARN("please, no space for starting a line, \
-                               excluding comments\n" . $herevet);
+                       WARN("please, no spaces at the start of a line\n" . $herevet);
                }
 
 # check we are in a valid C source file if not then ignore this hunk
@@ -1598,7 +1652,7 @@ sub process {
 
                        if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
                                ERROR("that open brace { should be on the previous line\n" .
-                                       "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
+                                       "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
                        }
                        if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
                            $ctx =~ /\)\s*\;\s*$/ &&
@@ -1607,7 +1661,7 @@ sub process {
                                my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
                                if ($nindent > $indent) {
                                        WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
-                                               "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
+                                               "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
                                }
                        }
                }
@@ -1768,8 +1822,17 @@ sub process {
                    !defined $suppress_export{$realline_next} &&
                    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
                     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+                       # Handle definitions which produce identifiers with
+                       # a prefix:
+                       #   XXX(foo);
+                       #   EXPORT_SYMBOL(something_foo);
                        my $name = $1;
-                       if ($stat !~ /(?:
+                       if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ &&
+                           $name =~ /^${Ident}_$2/) {
+#print "FOO C name<$name>\n";
+                               $suppress_export{$realline_next} = 1;
+
+                       } elsif ($stat !~ /(?:
                                \n.}\s*$|
                                ^.DEFINE_$Ident\(\Q$name\E\)|
                                ^.DECLARE_$Ident\(\Q$name\E\)|
@@ -1806,6 +1869,23 @@ sub process {
                                $herecurr);
                }
 
+# check for static const char * arrays.
+               if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
+                       WARN("static const char * array should probably be static const char * const\n" .
+                               $herecurr);
+               }
+
+# check for static char foo[] = "bar" declarations.
+               if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
+                       WARN("static char array declaration should probably be static const char\n" .
+                               $herecurr);
+               }
+
+# check for declarations of struct pci_device_id
+               if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
+                       WARN("Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
+               }
+
 # check for new typedefs, only function parameters and sparse annotations
 # make sense.
                if ($line =~ /\btypedef\s/ &&
@@ -1899,6 +1979,11 @@ sub process {
                        ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
                }
 
+# missing space after union, struct or enum definition
+               if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
+                   WARN("missing space after $1 definition\n" . $herecurr);
+               }
+
 # check for spacing round square brackets; allowed:
 #  1. with a type on the left -- int [] a;
 #  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
@@ -2176,21 +2261,29 @@ sub process {
                        my $value = $2;
 
                        # Flatten any parentheses
-                       $value =~ s/\)\(/\) \(/g;
+                       $value =~ s/\(/ \(/g;
+                       $value =~ s/\)/\) /g;
                        while ($value =~ s/\[[^\{\}]*\]/1/ ||
                               $value !~ /(?:$Ident|-?$Constant)\s*
                                             $Compare\s*
                                             (?:$Ident|-?$Constant)/x &&
                               $value =~ s/\([^\(\)]*\)/1/) {
                        }
-
-                       if ($value =~ /^(?:$Ident|-?$Constant)$/) {
+#print "value<$value>\n";
+                       if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
                                ERROR("return is not a function, parentheses are not required\n" . $herecurr);
 
                        } elsif ($spacing !~ /\s+/) {
                                ERROR("space required before the open parenthesis '('\n" . $herecurr);
                        }
                }
+# Return of what appears to be an errno should normally be -'ve
+               if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
+                       my $name = $1;
+                       if ($name ne 'EOF' && $name ne 'ERROR') {
+                               WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
+                       }
+               }
 
 # Need a space before open parenthesis after if, while etc
                if ($line=~/\b(if|while|for|switch)\(/) {
@@ -2409,8 +2502,8 @@ sub process {
                                \.$Ident\s*=\s*|
                                ^\"|\"$
                        }x;
-                       #print "REST<$rest> dstat<$dstat>\n";
-                       if ($rest ne '') {
+                       #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
+                       if ($rest ne '' && $rest ne ',') {
                                if ($rest !~ /while\s*\(/ &&
                                    $dstat !~ /$exceptions/)
                                {
@@ -2701,12 +2794,8 @@ sub process {
                        WARN("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
 
-# check for semaphores used as mutexes
-               if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
-                       WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
-               }
-# check for semaphores used as mutexes
-               if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
+# check for semaphores initialized locked
+               if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("consider using a completion\n" . $herecurr);
 
                }
@@ -2839,6 +2928,15 @@ sub process {
                print "\n" if ($quiet == 0);
        }
 
+       if ($quiet == 0) {
+               # If there were whitespace errors which cleanpatch can fix
+               # then suggest that.
+               if ($rpt_cleaners) {
+                       print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
+                       print "      scripts/cleanfile\n\n";
+               }
+       }
+
        if ($clean == 1 && $quiet == 0) {
                print "$vname has no obvious style problems and is ready for submission.\n"
        }