Merge tag 'imx-fixes-3.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/shawngu...
[cascardo/linux.git] / scripts / checkpatch.pl
index 969b365..374abf4 100755 (executable)
@@ -9,7 +9,8 @@ use strict;
 use POSIX;
 
 my $P = $0;
-$P =~ s@.*/@@g;
+$P =~ s@(.*)/@@g;
+my $D = $1;
 
 my $V = '0.32';
 
@@ -44,6 +45,7 @@ my $max_line_length = 80;
 my $ignore_perl_version = 0;
 my $minimum_perl_version = 5.10.0;
 my $min_conf_desc_length = 4;
+my $spelling_file = "$D/spelling.txt";
 
 sub help {
        my ($exitcode) = @_;
@@ -434,6 +436,29 @@ our $allowed_asm_includes = qr{(?x:
 )};
 # memory.h: ARM has a custom one
 
+# Load common spelling mistakes and build regular expression list.
+my $misspellings;
+my @spelling_list;
+my %spelling_fix;
+open(my $spelling, '<', $spelling_file)
+    or die "$P: Can't open $spelling_file for reading: $!\n";
+while (<$spelling>) {
+       my $line = $_;
+
+       $line =~ s/\s*\n?$//g;
+       $line =~ s/^\s*//g;
+
+       next if ($line =~ m/^\s*#/);
+       next if ($line =~ m/^\s*$/);
+
+       my ($suspect, $fix) = split(/\|\|/, $line);
+
+       push(@spelling_list, $suspect);
+       $spelling_fix{$suspect} = $fix;
+}
+close($spelling);
+$misspellings = join("|", @spelling_list);
+
 sub build_types {
        my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
        my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
@@ -2220,6 +2245,23 @@ sub process {
                            "8-bit UTF-8 used in possible commit log\n" . $herecurr);
                }
 
+# Check for various typo / spelling mistakes
+               if ($in_commit_log || $line =~ /^\+/) {
+                       while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:$|[^a-z@])/gi) {
+                               my $typo = $1;
+                               my $typo_fix = $spelling_fix{lc($typo)};
+                               $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
+                               $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
+                               my $msg_type = \&WARN;
+                               $msg_type = \&CHK if ($file);
+                               if (&{$msg_type}("TYPO_SPELLING",
+                                                "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
+                                   $fix) {
+                                       $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
+                               }
+                       }
+               }
+
 # ignore non-hunk lines and lines being removed
                next if (!$hunk_line || $line =~ /^-/);
 
@@ -2431,7 +2473,7 @@ sub process {
                                "please, no space before tabs\n" . $herevet) &&
                            $fix) {
                                while ($fixed[$fixlinenr] =~
-                                          s/(^\+.*) {8,8}+\t/$1\t\t/) {}
+                                          s/(^\+.*) {8,8}\t/$1\t\t/) {}
                                while ($fixed[$fixlinenr] =~
                                           s/(^\+.*) +\t/$1\t/) {}
                        }
@@ -2599,10 +2641,14 @@ sub process {
                next if ($realfile !~ /\.(h|c)$/);
 
 # check indentation of any line with a bare else
+# (but not if it is a multiple line "if (foo) return bar; else return baz;")
 # if the previous line is a break or return and is indented 1 tab more...
                if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
                        my $tabs = length($1) + 1;
-                       if ($prevline =~ /^\+\t{$tabs,$tabs}(?:break|return)\b/) {
+                       if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
+                           ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
+                            defined $lines[$linenr] &&
+                            $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
                                WARN("UNNECESSARY_ELSE",
                                     "else is not generally useful after a break or return\n" . $hereprev);
                        }
@@ -4066,12 +4112,17 @@ sub process {
                        my $cnt = $realcnt;
                        my ($off, $dstat, $dcond, $rest);
                        my $ctx = '';
+                       my $has_flow_statement = 0;
+                       my $has_arg_concat = 0;
                        ($dstat, $dcond, $ln, $cnt, $off) =
                                ctx_statement_block($linenr, $realcnt, 0);
                        $ctx = $dstat;
                        #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
                        #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
 
+                       $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
+                       $has_arg_concat = 1 if ($ctx =~ /\#\#/);
+
                        $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
                        $dstat =~ s/$;//g;
                        $dstat =~ s/\\\n.//g;
@@ -4136,6 +4187,19 @@ sub process {
                                }
                        }
 
+# check for macros with flow control, but without ## concatenation
+# ## concatenation is commonly a macro that defines a function so ignore those
+                       if ($has_flow_statement && !$has_arg_concat) {
+                               my $herectx = $here . "\n";
+                               my $cnt = statement_rawlines($ctx);
+
+                               for (my $n = 0; $n < $cnt; $n++) {
+                                       $herectx .= raw_line($linenr, $n) . "\n";
+                               }
+                               WARN("MACRO_WITH_FLOW_CONTROL",
+                                    "Macros with flow control statements should be avoided\n" . "$herectx");
+                       }
+
 # check for line continuations outside of #defines, preprocessor #, and asm
 
                } else {
@@ -4344,6 +4408,12 @@ sub process {
                             "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
                }
 
+# concatenated string without spaces between elements
+               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {
+                       CHK("CONCATENATED_STRING",
+                           "Concatenated strings should use spaces between elements\n" . $herecurr);
+               }
+
 # warn about #if 0
                if ($line =~ /^.\s*\#\s*if\s+0\b/) {
                        CHK("REDUNDANT_CODE",
@@ -4377,6 +4447,17 @@ sub process {
                        }
                }
 
+# check for logging functions with KERN_<LEVEL>
+               if ($line !~ /printk\s*\(/ &&
+                   $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
+                       my $level = $1;
+                       if (WARN("UNNECESSARY_KERN_LEVEL",
+                                "Possible unnecessary $level\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$fixlinenr] =~ s/\s*$level\s*//;
+                       }
+               }
+
 # check for bad placement of section $InitAttribute (e.g.: __initdata)
                if ($line =~ /(\b$InitAttribute\b)/) {
                        my $attr = $1;