Merge tag 'xtensa-next-20130710' of git://github.com/czankel/xtensa-linux
[cascardo/linux.git] / scripts / checkpatch.pl
index 9696be5..2ee9eb7 100755 (executable)
@@ -6,6 +6,7 @@
 # Licensed under the terms of the GNU GPL License version 2
 
 use strict;
+use POSIX;
 
 my $P = $0;
 $P =~ s@.*/@@g;
@@ -31,6 +32,7 @@ my $fix = 0;
 my $root;
 my %debug;
 my %ignore_type = ();
+my %camelcase = ();
 my @ignore = ();
 my $help = 0;
 my $configuration_file = ".checkpatch.conf";
@@ -280,7 +282,7 @@ our $typeTypedefs = qr{(?x:
 
 our $logFunctions = qr{(?x:
        printk(?:_ratelimited|_once|)|
-       [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
+       (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
        WARN(?:_RATELIMIT|_ONCE|)|
        panic|
        MODULE_[A-Z_]+
@@ -349,7 +351,6 @@ sub build_types {
 }
 build_types();
 
-
 our $Typecast  = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
 
 # Using $balanced_parens, $LvalOrFunc, or $FuncArg
@@ -369,6 +370,89 @@ sub deparenthesize {
        return $string;
 }
 
+sub seed_camelcase_file {
+       my ($file) = @_;
+
+       return if (!(-f $file));
+
+       local $/;
+
+       open(my $include_file, '<', "$file")
+           or warn "$P: Can't read '$file' $!\n";
+       my $text = <$include_file>;
+       close($include_file);
+
+       my @lines = split('\n', $text);
+
+       foreach my $line (@lines) {
+               next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
+               if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
+                       $camelcase{$1} = 1;
+               }
+               elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*\(/) {
+                       $camelcase{$1} = 1;
+               }
+       }
+}
+
+my $camelcase_seeded = 0;
+sub seed_camelcase_includes {
+       return if ($camelcase_seeded);
+
+       my $files;
+       my $camelcase_cache = "";
+       my @include_files = ();
+
+       $camelcase_seeded = 1;
+
+       if (-d ".git") {
+               my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
+               chomp $git_last_include_commit;
+               $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
+       } else {
+               my $last_mod_date = 0;
+               $files = `find $root/include -name "*.h"`;
+               @include_files = split('\n', $files);
+               foreach my $file (@include_files) {
+                       my $date = POSIX::strftime("%Y%m%d%H%M",
+                                                  localtime((stat $file)[9]));
+                       $last_mod_date = $date if ($last_mod_date < $date);
+               }
+               $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
+       }
+
+       if ($camelcase_cache ne "" && -f $camelcase_cache) {
+               open(my $camelcase_file, '<', "$camelcase_cache")
+                   or warn "$P: Can't read '$camelcase_cache' $!\n";
+               while (<$camelcase_file>) {
+                       chomp;
+                       $camelcase{$_} = 1;
+               }
+               close($camelcase_file);
+
+               return;
+       }
+
+       if (-d ".git") {
+               $files = `git ls-files "include/*.h"`;
+               @include_files = split('\n', $files);
+       }
+
+       foreach my $file (@include_files) {
+               seed_camelcase_file($file);
+       }
+
+       if ($camelcase_cache ne "") {
+               unlink glob ".checkpatch-camelcase.*";
+               open(my $camelcase_file, '>', "$camelcase_cache")
+                   or warn "$P: Can't write '$camelcase_cache' $!\n";
+               foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
+                       print $camelcase_file ("$_\n");
+               }
+               close($camelcase_file);
+       }
+}
+
 $chk_signoff = 0 if ($file);
 
 my @rawlines = ();
@@ -1448,7 +1532,6 @@ sub process {
        my %suppress_export;
        my $suppress_statement = 0;
 
-       my %camelcase = ();
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
@@ -2646,16 +2729,6 @@ sub process {
                        }
                }
 
-# check for whitespace before a non-naked semicolon
-               if ($line =~ /^\+.*\S\s+;/) {
-                       if (WARN("SPACING",
-                                "space prohibited before semicolon\n" . $herecurr) &&
-                           $fix) {
-                               $fixed[$linenr - 1] =~
-                                   s/^(\+.*\S)\s+;/$1;/;
-                       }
-               }
-
 # Check operator spacing.
                if (!($line=~/\#\s*include/)) {
                        my $fixed_line = "";
@@ -2920,6 +2993,16 @@ sub process {
 
                }
 
+# check for whitespace before a non-naked semicolon
+               if ($line =~ /^\+.*\S\s+;/) {
+                       if (WARN("SPACING",
+                                "space prohibited before semicolon\n" . $herecurr) &&
+                           $fix) {
+                               1 while $fixed[$linenr - 1] =~
+                                   s/^(\+.*\S)\s+;/$1;/;
+                       }
+               }
+
 # check for multiple assignments
                if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
                        CHK("MULTIPLE_ASSIGNMENTS",
@@ -3195,11 +3278,16 @@ sub process {
 #CamelCase
                        if ($var !~ /^$Constant$/ &&
                            $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
+#Ignore Page<foo> variants
                            $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
-                           !defined $camelcase{$var}) {
-                               $camelcase{$var} = 1;
-                               CHK("CAMELCASE",
-                                   "Avoid CamelCase: <$var>\n" . $herecurr);
+#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
+                           $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
+                               seed_camelcase_includes() if ($check);
+                               if (!defined $camelcase{$var}) {
+                                       $camelcase{$var} = 1;
+                                       CHK("CAMELCASE",
+                                           "Avoid CamelCase: <$var>\n" . $herecurr);
+                               }
                        }
                }