checkpatch: make extern in .h prototypes quieter
[sfrench/cifs-2.6.git] / scripts / checkpatch.pl
index 2ee9eb750560256187d4f236e328b5d7ad2656f8..66cad506b8a2a944f2873856ef0078445f673b8b 100755 (executable)
@@ -31,12 +31,16 @@ my $show_types = 0;
 my $fix = 0;
 my $root;
 my %debug;
-my %ignore_type = ();
 my %camelcase = ();
+my %use_type = ();
+my @use = ();
+my %ignore_type = ();
 my @ignore = ();
 my $help = 0;
 my $configuration_file = ".checkpatch.conf";
 my $max_line_length = 80;
+my $ignore_perl_version = 0;
+my $minimum_perl_version = 5.10.0;
 
 sub help {
        my ($exitcode) = @_;
@@ -54,6 +58,7 @@ Options:
   --terse                    one line per report
   -f, --file                 treat FILE as regular source file
   --subjective, --strict     enable more subjective tests
+  --types TYPE(,TYPE2...)    show only these comma separated message types
   --ignore TYPE(,TYPE2...)   ignore various comma separated message types
   --max-line-length=n        set the maximum line length, if exceeded, warn
   --show-types               show the message "types" in the output
@@ -71,6 +76,8 @@ Options:
                              "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
                              with potential errors corrected to the preferred
                              checkpatch style
+  --ignore-perl-version      override checking of perl version.  expect
+                             runtime errors.
   -h, --help, --version      display this help and exit
 
 When FILE is - read standard input.
@@ -116,6 +123,7 @@ GetOptions(
        'subjective!'   => \$check,
        'strict!'       => \$check,
        'ignore=s'      => \@ignore,
+       'types=s'       => \@use,
        'show-types!'   => \$show_types,
        'max-line-length=i' => \$max_line_length,
        'root=s'        => \$root,
@@ -123,6 +131,7 @@ GetOptions(
        'mailback!'     => \$mailback,
        'summary-file!' => \$summary_file,
        'fix!'          => \$fix,
+       'ignore-perl-version!' => \$ignore_perl_version,
        'debug=s'       => \%debug,
        'test-only=s'   => \$tst_only,
        'h|help'        => \$help,
@@ -133,24 +142,50 @@ help(0) if ($help);
 
 my $exit = 0;
 
+if ($^V && $^V lt $minimum_perl_version) {
+       printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
+       if (!$ignore_perl_version) {
+               exit(1);
+       }
+}
+
 if ($#ARGV < 0) {
        print "$P: no input files\n";
        exit(1);
 }
 
-@ignore = split(/,/, join(',',@ignore));
-foreach my $word (@ignore) {
-       $word =~ s/\s*\n?$//g;
-       $word =~ s/^\s*//g;
-       $word =~ s/\s+/ /g;
-       $word =~ tr/[a-z]/[A-Z]/;
+sub hash_save_array_words {
+       my ($hashRef, $arrayRef) = @_;
+
+       my @array = split(/,/, join(',', @$arrayRef));
+       foreach my $word (@array) {
+               $word =~ s/\s*\n?$//g;
+               $word =~ s/^\s*//g;
+               $word =~ s/\s+/ /g;
+               $word =~ tr/[a-z]/[A-Z]/;
+
+               next if ($word =~ m/^\s*#/);
+               next if ($word =~ m/^\s*$/);
 
-       next if ($word =~ m/^\s*#/);
-       next if ($word =~ m/^\s*$/);
+               $hashRef->{$word}++;
+       }
+}
 
-       $ignore_type{$word}++;
+sub hash_show_words {
+       my ($hashRef, $prefix) = @_;
+
+       if ($quiet == 0 && keys %$hashRef) {
+               print "NOTE: $prefix message types:";
+               foreach my $word (sort keys %$hashRef) {
+                       print " $word";
+               }
+               print "\n\n";
+       }
 }
 
+hash_save_array_words(\%ignore_type, \@ignore);
+hash_save_array_words(\%use_type, \@use);
+
 my $dbg_values = 0;
 my $dbg_possible = 0;
 my $dbg_type = 0;
@@ -207,6 +242,8 @@ our $Sparse = qr{
                        __rcu
                }x;
 
+our $InitAttribute = qr{__(?:mem|cpu|dev|net_|)(?:initdata|initconst|init\b)};
+
 # Notes to $Attribute:
 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
 our $Attribute = qr{
@@ -227,7 +264,7 @@ our $Attribute      = qr{
                        __deprecated|
                        __read_mostly|
                        __kprobes|
-                       __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
+                       $InitAttribute|
                        ____cacheline_aligned|
                        ____cacheline_aligned_in_smp|
                        ____cacheline_internodealigned_in_smp|
@@ -257,6 +294,7 @@ our $Operators      = qr{
                  }x;
 
 our $NonptrType;
+our $NonptrTypeWithAttr;
 our $Type;
 our $Declare;
 
@@ -319,6 +357,12 @@ our @typeList = (
        qr{${Ident}_handler},
        qr{${Ident}_handler_fn},
 );
+our @typeListWithAttr = (
+       @typeList,
+       qr{struct\s+$InitAttribute\s+$Ident},
+       qr{union\s+$InitAttribute\s+$Ident},
+);
+
 our @modifierList = (
        qr{fastcall},
 );
@@ -332,6 +376,7 @@ our $allowed_asm_includes = qr{(?x:
 sub build_types {
        my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
        my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
+       my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
        $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};
        $NonptrType     = qr{
                        (?:$Modifier\s+|const\s+)*
@@ -342,6 +387,15 @@ sub build_types {
                        )
                        (?:\s+$Modifier|\s+const)*
                  }x;
+       $NonptrTypeWithAttr     = qr{
+                       (?:$Modifier\s+|const\s+)*
+                       (?:
+                               (?:typeof|__typeof__)\s*\([^\)]*\)|
+                               (?:$typeTypedefs\b)|
+                               (?:${allWithAttr}\b)
+                       )
+                       (?:\s+$Modifier|\s+const)*
+                 }x;
        $Type   = qr{
                        $NonptrType
                        (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
@@ -1355,7 +1409,9 @@ sub possible {
 my $prefix = '';
 
 sub show_type {
-       return !defined $ignore_type{$_[0]};
+       return defined $use_type{$_[0]} if (scalar keys %use_type > 0);
+
+       return !defined $ignore_type{$_[0]};
 }
 
 sub report {
@@ -1435,7 +1491,23 @@ sub check_absolute_file {
 sub trim {
        my ($string) = @_;
 
-       $string =~ s/(^\s+|\s+$)//g;
+       $string =~ s/^\s+|\s+$//g;
+
+       return $string;
+}
+
+sub ltrim {
+       my ($string) = @_;
+
+       $string =~ s/^\s+//;
+
+       return $string;
+}
+
+sub rtrim {
+       my ($string) = @_;
+
+       $string =~ s/\s+$//;
 
        return $string;
 }
@@ -1532,6 +1604,7 @@ sub process {
        my %suppress_export;
        my $suppress_statement = 0;
 
+       my %signatures = ();
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
@@ -1624,6 +1697,8 @@ sub process {
        $linenr = 0;
        foreach my $line (@lines) {
                $linenr++;
+               my $sline = $line;      #copy of $line
+               $sline =~ s/$;/ /g;     #with comments as spaces
 
                my $rawline = $rawlines[$linenr - 1];
 
@@ -1781,6 +1856,17 @@ sub process {
                                             "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
                                }
                        }
+
+# Check for duplicate signatures
+                       my $sig_nospace = $line;
+                       $sig_nospace =~ s/\s//g;
+                       $sig_nospace = lc($sig_nospace);
+                       if (defined $signatures{$sig_nospace}) {
+                               WARN("BAD_SIGN_OFF",
+                                    "Duplicate signature\n" . $herecurr);
+                       } else {
+                               $signatures{$sig_nospace} = 1;
+                       }
                }
 
 # Check for wrappage within a valid hunk of the file
@@ -1845,15 +1931,17 @@ sub process {
 #trailing whitespace
                if ($line =~ /^\+.*\015/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
-                       ERROR("DOS_LINE_ENDINGS",
-                             "DOS line endings\n" . $herevet);
-
+                       if (ERROR("DOS_LINE_ENDINGS",
+                                 "DOS line endings\n" . $herevet) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/[\s\015]+$//;
+                       }
                } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
                        my $herevet = "$here\n" . cat_vet($rawline) . "\n";
                        if (ERROR("TRAILING_WHITESPACE",
                                  "trailing whitespace\n" . $herevet) &&
                            $fix) {
-                               $fixed[$linenr - 1] =~ s/^(\+.*?)\s+$/$1/;
+                               $fixed[$linenr - 1] =~ s/\s+$//;
                        }
 
                        $rpt_cleaners = 1;
@@ -2060,6 +2148,7 @@ sub process {
                if ($realfile =~ m@^(drivers/net/|net/)@ &&
                    $prevrawline =~ /^\+[ \t]*\/\*/ &&          #starting /*
                    $prevrawline !~ /\*\/[ \t]*$/ &&            #no trailing */
+                   $rawline =~ /^\+/ &&                        #line is new
                    $rawline !~ /^\+[ \t]*\*/) {                #no leading *
                        WARN("NETWORKING_BLOCK_COMMENT_STYLE",
                             "networking block comments start with * on subsequent lines\n" . $hereprev);
@@ -2126,7 +2215,7 @@ sub process {
                    $realline_next);
 #print "LINE<$line>\n";
                if ($linenr >= $suppress_statement &&
-                   $realcnt && $line =~ /.\s*\S/) {
+                   $realcnt && $sline =~ /.\s*\S/) {
                        ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
                                ctx_statement_block($linenr, $realcnt, 0);
                        $stat =~ s/\n./\n /g;
@@ -2486,16 +2575,22 @@ sub process {
                }
 
 # check for global initialisers.
-               if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
-                       ERROR("GLOBAL_INITIALISERS",
-                             "do not initialise globals to 0 or NULL\n" .
-                               $herecurr);
+               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
+                       if (ERROR("GLOBAL_INITIALISERS",
+                                 "do not initialise globals to 0 or NULL\n" .
+                                     $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
+                       }
                }
 # check for static initialisers.
-               if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
-                       ERROR("INITIALISED_STATIC",
-                             "do not initialise statics to 0 or NULL\n" .
-                               $herecurr);
+               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
+                       if (ERROR("INITIALISED_STATIC",
+                                 "do not initialise statics to 0 or NULL\n" .
+                                     $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
+                       }
                }
 
 # check for static const char * arrays.
@@ -2638,8 +2733,12 @@ sub process {
                }
 
                if ($line =~ /\bpr_warning\s*\(/) {
-                       WARN("PREFER_PR_LEVEL",
-                            "Prefer pr_warn(... to pr_warning(...\n" . $herecurr);
+                       if (WARN("PREFER_PR_LEVEL",
+                                "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~
+                                   s/\bpr_warning\b/pr_warn/;
+                       }
                }
 
                if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
@@ -2759,6 +2858,7 @@ sub process {
                        $off = 0;
 
                        my $blank = copy_spacing($opline);
+                       my $last_after = -1;
 
                        for (my $n = 0; $n < $#elements; $n += 2) {
 
@@ -2824,7 +2924,7 @@ sub process {
                                            $cc !~ /^\\/ && $cc !~ /^;/) {
                                                if (ERROR("SPACING",
                                                          "space required after that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+                                                       $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
                                                        $line_fixed = 1;
                                                }
                                        }
@@ -2839,11 +2939,11 @@ sub process {
                                        if ($ctx =~ /Wx.|.xW/) {
                                                if (ERROR("SPACING",
                                                          "spaces prohibited around that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
-                                                       $line_fixed = 1;
+                                                       $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
                                                        if (defined $fix_elements[$n + 2]) {
                                                                $fix_elements[$n + 2] =~ s/^\s+//;
                                                        }
+                                                       $line_fixed = 1;
                                                }
                                        }
 
@@ -2852,8 +2952,9 @@ sub process {
                                        if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
                                                if (ERROR("SPACING",
                                                          "space required after that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
+                                                       $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
                                                        $line_fixed = 1;
+                                                       $last_after = $n;
                                                }
                                        }
 
@@ -2870,8 +2971,10 @@ sub process {
                                        if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
                                                if (ERROR("SPACING",
                                                          "space required before that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
-                                                       $line_fixed = 1;
+                                                       if ($n != $last_after + 2) {
+                                                               $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
+                                                               $line_fixed = 1;
+                                                       }
                                                }
                                        }
                                        if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
@@ -2880,12 +2983,11 @@ sub process {
                                        } elsif ($ctx =~ /.xW/) {
                                                if (ERROR("SPACING",
                                                          "space prohibited after that '$op' $at\n" . $hereptr)) {
-                                                       $fixed_line =~ s/\s+$//;
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
-                                                       $line_fixed = 1;
+                                                       $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
                                                        if (defined $fix_elements[$n + 2]) {
                                                                $fix_elements[$n + 2] =~ s/^\s+//;
                                                        }
+                                                       $line_fixed = 1;
                                                }
                                        }
 
@@ -2894,8 +2996,7 @@ sub process {
                                        if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
                                                if (ERROR("SPACING",
                                                          "space required one side of that '$op' $at\n" . $hereptr)) {
-                                                       $fixed_line =~ s/\s+$//;
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
+                                                       $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
                                                        $line_fixed = 1;
                                                }
                                        }
@@ -2903,20 +3004,18 @@ sub process {
                                            ($ctx =~ /Wx./ && $cc =~ /^;/)) {
                                                if (ERROR("SPACING",
                                                          "space prohibited before that '$op' $at\n" . $hereptr)) {
-                                                       $fixed_line =~ s/\s+$//;
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+                                                       $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
                                                        $line_fixed = 1;
                                                }
                                        }
                                        if ($ctx =~ /ExW/) {
                                                if (ERROR("SPACING",
                                                          "space prohibited after that '$op' $at\n" . $hereptr)) {
-                                                       $fixed_line =~ s/\s+$//;
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
-                                                       $line_fixed = 1;
+                                                       $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
                                                        if (defined $fix_elements[$n + 2]) {
                                                                $fix_elements[$n + 2] =~ s/^\s+//;
                                                        }
+                                                       $line_fixed = 1;
                                                }
                                        }
 
@@ -2930,8 +3029,10 @@ sub process {
                                        if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
                                                if (ERROR("SPACING",
                                                          "need consistent spacing around '$op' $at\n" . $hereptr)) {
-                                                       $fixed_line =~ s/\s+$//;
-                                                       $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+                                                       $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+                                                       if (defined $fix_elements[$n + 2]) {
+                                                               $fix_elements[$n + 2] =~ s/^\s+//;
+                                                       }
                                                        $line_fixed = 1;
                                                }
                                        }
@@ -2942,7 +3043,7 @@ sub process {
                                        if ($ctx =~ /Wx./) {
                                                if (ERROR("SPACING",
                                                          "space prohibited before that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+                                                       $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
                                                        $line_fixed = 1;
                                                }
                                        }
@@ -2969,8 +3070,10 @@ sub process {
                                        if ($ok == 0) {
                                                if (ERROR("SPACING",
                                                          "spaces required around that '$op' $at\n" . $hereptr)) {
-                                                       $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
-                                                       $good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " ";
+                                                       $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+                                                       if (defined $fix_elements[$n + 2]) {
+                                                               $fix_elements[$n + 2] =~ s/^\s+//;
+                                                       }
                                                        $line_fixed = 1;
                                                }
                                        }
@@ -3031,8 +3134,7 @@ sub process {
                        if (ERROR("SPACING",
                                  "space required before the open brace '{'\n" . $herecurr) &&
                            $fix) {
-                               $fixed[$linenr - 1] =~
-                                   s/^(\+.*(?:do|\))){/$1 {/;
+                               $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/;
                        }
                }
 
@@ -3047,8 +3149,12 @@ sub process {
 # closing brace should have a space following it when it has anything
 # on the line
                if ($line =~ /}(?!(?:,|;|\)))\S/) {
-                       ERROR("SPACING",
-                             "space required after that close brace '}'\n" . $herecurr);
+                       if (ERROR("SPACING",
+                                 "space required after that close brace '}'\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~
+                                   s/}((?!(?:,|;|\)))\S)/} $1/;
+                       }
                }
 
 # check spacing on square brackets
@@ -3271,8 +3377,13 @@ sub process {
 
 #gcc binary extension
                        if ($var =~ /^$Binary$/) {
-                               WARN("GCC_BINARY_CONSTANT",
-                                    "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr);
+                               if (WARN("GCC_BINARY_CONSTANT",
+                                        "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
+                                   $fix) {
+                                       my $hexval = sprintf("0x%x", oct($var));
+                                       $fixed[$linenr - 1] =~
+                                           s/\b$var\b/$hexval/;
+                               }
                        }
 
 #CamelCase
@@ -3282,19 +3393,26 @@ sub process {
                            $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
 #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);
+                               while ($var =~ m{($Ident)}g) {
+                                       my $word = $1;
+                                       next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
+                                       seed_camelcase_includes() if ($check);
+                                       if (!defined $camelcase{$word}) {
+                                               $camelcase{$word} = 1;
+                                               CHK("CAMELCASE",
+                                                   "Avoid CamelCase: <$word>\n" . $herecurr);
+                                       }
                                }
                        }
                }
 
 #no spaces allowed after \ in define
-               if ($line=~/\#\s*define.*\\\s$/) {
-                       WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
-                            "Whitepspace after \\ makes next lines useless\n" . $herecurr);
+               if ($line =~ /\#\s*define.*\\\s+$/) {
+                       if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
+                                "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\s+$//;
+                       }
                }
 
 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
@@ -3374,7 +3492,8 @@ sub process {
                            $dstat !~ /^for\s*$Constant$/ &&                            # for (...)
                            $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&   # for (...) bar()
                            $dstat !~ /^do\s*{/ &&                                      # do {...
-                           $dstat !~ /^\({/)                                           # ({...
+                           $dstat !~ /^\({/ &&                                         # ({...
+                           $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
                        {
                                $ctx =~ s/\n*$//;
                                my $herectx = $here . "\n";
@@ -3606,6 +3725,32 @@ sub process {
                        }
                }
 
+sub string_find_replace {
+       my ($string, $find, $replace) = @_;
+
+       $string =~ s/$find/$replace/g;
+
+       return $string;
+}
+
+# check for bad placement of section $InitAttribute (e.g.: __initdata)
+               if ($line =~ /(\b$InitAttribute\b)/) {
+                       my $attr = $1;
+                       if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
+                               my $ptr = $1;
+                               my $var = $2;
+                               if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
+                                     ERROR("MISPLACED_INIT",
+                                           "$attr should be placed after $var\n" . $herecurr)) ||
+                                    ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
+                                     WARN("MISPLACED_INIT",
+                                          "$attr should be placed after $var\n" . $herecurr))) &&
+                                   $fix) {
+                                       $fixed[$linenr - 1] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
+                               }
+                       }
+               }
+
 # prefer usleep_range over udelay
                if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
                        # ignore udelay's < 10, however
@@ -3691,8 +3836,12 @@ sub process {
 
 # Check for __inline__ and __inline, prefer inline
                if ($line =~ /\b(__inline__|__inline)\b/) {
-                       WARN("INLINE",
-                            "plain inline is preferred over $1\n" . $herecurr);
+                       if (WARN("INLINE",
+                                "plain inline is preferred over $1\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
+
+                       }
                }
 
 # Check for __attribute__ packed, prefer __packed
@@ -3709,14 +3858,21 @@ sub process {
 
 # Check for __attribute__ format(printf, prefer __printf
                if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
-                       WARN("PREFER_PRINTF",
-                            "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
+                       if (WARN("PREFER_PRINTF",
+                                "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
+
+                       }
                }
 
 # Check for __attribute__ format(scanf, prefer __scanf
                if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
-                       WARN("PREFER_SCANF",
-                            "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
+                       if (WARN("PREFER_SCANF",
+                                "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
+                       }
                }
 
 # check for sizeof(&)
@@ -3727,8 +3883,11 @@ sub process {
 
 # check for sizeof without parenthesis
                if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
-                       WARN("SIZEOF_PARENTHESIS",
-                            "sizeof $1 should be sizeof($1)\n" . $herecurr);
+                       if (WARN("SIZEOF_PARENTHESIS",
+                                "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
+                       }
                }
 
 # check for line continuations in quoted strings with odd counts of "
@@ -3747,8 +3906,11 @@ sub process {
                if ($line =~ /\bseq_printf\s*\(/) {
                        my $fmt = get_quoted_string($line, $rawline);
                        if ($fmt !~ /[^\\]\%/) {
-                               WARN("PREFER_SEQ_PUTS",
-                                    "Prefer seq_puts to seq_printf\n" . $herecurr);
+                               if (WARN("PREFER_SEQ_PUTS",
+                                        "Prefer seq_puts to seq_printf\n" . $herecurr) &&
+                                   $fix) {
+                                       $fixed[$linenr - 1] =~ s/\bseq_printf\b/seq_puts/;
+                               }
                        }
                }
 
@@ -3810,6 +3972,16 @@ sub process {
                        }
                }
 
+# check for new externs in .h files.
+               if ($realfile =~ /\.h$/ &&
+                   $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
+                       if (CHK("AVOID_EXTERNS",
+                               "extern prototypes should be avoided in .h files\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
+                       }
+               }
+
 # check for new externs in .c files.
                if ($realfile =~ /\.c$/ && defined $stat &&
                    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
@@ -3879,8 +4051,11 @@ sub process {
 
 # check for multiple semicolons
                if ($line =~ /;\s*;\s*$/) {
-                       WARN("ONE_SEMICOLON",
-                            "Statements terminations use 1 semicolon\n" . $herecurr);
+                       if (WARN("ONE_SEMICOLON",
+                                "Statements terminations use 1 semicolon\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
+                       }
                }
 
 # check for switch/default statements without a break;
@@ -3898,9 +4073,12 @@ sub process {
                }
 
 # check for gcc specific __FUNCTION__
-               if ($line =~ /__FUNCTION__/) {
-                       WARN("USE_FUNC",
-                            "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
+               if ($line =~ /\b__FUNCTION__\b/) {
+                       if (WARN("USE_FUNC",
+                                "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
+                           $fix) {
+                               $fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g;
+                       }
                }
 
 # check for use of yield()
@@ -4105,13 +4283,8 @@ sub process {
                }
        }
 
-       if ($quiet == 0 && keys %ignore_type) {
-           print "NOTE: Ignored message types:";
-           foreach my $ignore (sort keys %ignore_type) {
-               print " $ignore";
-           }
-           print "\n\n";
-       }
+       hash_show_words(\%use_type, "Used");
+       hash_show_words(\%ignore_type, "Ignored");
 
        if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
                my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes";