Whamcloud - gitweb
LU-7589 build: update checkpatch to ~4.13-rc1 kernel
[fs/lustre-release.git] / contrib / scripts / checkpatch.pl
1 #!/usr/bin/env perl
2 # (c) 2001, Dave Jones. (the file handling bit)
3 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5 # (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6 # Licensed under the terms of the GNU GPL License version 2
7
8 # Based on linux/scripts/checkpatch.pl v4.12-11743-g96d0d83 with
9 # some additional Lustre-specific checks.
10
11 use strict;
12 use warnings;
13 use POSIX;
14 use File::Basename;
15 use Cwd 'abs_path';
16 use Term::ANSIColor qw(:constants);
17
18 my $P = $0;
19 my $D = dirname(abs_path($P));
20
21 my $V = '0.32';
22
23 use Getopt::Long qw(:config no_auto_abbrev);
24
25 my $quiet = 0;
26 my $tree = 0;
27 my $chk_signoff = 0;
28 my $chk_patch = 1;
29 my $tst_only;
30 my $emacs = 0;
31 my $terse = 0;
32 my $showfile = 0;
33 my $file = 0;
34 my $git = 0;
35 my %git_commits = ();
36 my $check = 0;
37 my $check_orig = 0;
38 my $summary = 1;
39 my $mailback = 0;
40 my $summary_file = 0;
41 my $show_types = 0;
42 my $list_types = 0;
43 my $fix = 0;
44 my $fix_inplace = 0;
45 my $root;
46 my %debug;
47 my %camelcase = ();
48 my %use_type = ();
49 my @use = ();
50 my %ignore_type = ();
51 my @ignore = ();
52 my $help = 0;
53 my $configuration_file = ".checkpatch.conf";
54 my $max_line_length = 80;
55 my $ignore_perl_version = 0;
56 my $minimum_perl_version = 5.10.0;
57 my $min_conf_desc_length = 4;
58 my $spelling_file = "$D/spelling.txt";
59 my $codespell = 0;
60 my $codespellfile = "/usr/share/codespell/dictionary.txt";
61 my $conststructsfile = "$D/const_structs.checkpatch";
62 my $typedefsfile = "";
63 my $color = "auto";
64 my $allow_c99_comments = 1;
65
66 sub help {
67         my ($exitcode) = @_;
68
69         print << "EOM";
70 Usage: $P [OPTION]... [FILE]...
71 Version: $V
72
73 Options:
74   -q, --quiet                quiet
75   --no-tree                  run without a kernel tree
76   --no-signoff               do not check for 'Signed-off-by' line
77   --patch                    treat FILE as patchfile (default)
78   --emacs                    emacs compile window format
79   --terse                    one line per report
80   --showfile                 emit diffed file position, not input file position
81   -g, --git                  treat FILE as a single commit or git revision range
82                              single git commit with:
83                                <rev>
84                                <rev>^
85                                <rev>~n
86                              multiple git commits with:
87                                <rev1>..<rev2>
88                                <rev1>...<rev2>
89                                <rev>-<count>
90                              git merges are ignored
91   -f, --file                 treat FILE as regular source file
92   --subjective, --strict     enable more subjective tests
93   --list-types               list the possible message types
94   --types TYPE(,TYPE2...)    show only these comma separated message types
95   --ignore TYPE(,TYPE2...)   ignore various comma separated message types
96   --show-types               show the specific message type in the output
97   --max-line-length=n        set the maximum line length, if exceeded, warn
98   --min-conf-desc-length=n   set the min description length, if shorter, warn
99   --root=PATH                PATH to the kernel tree root
100   --no-summary               suppress the per-file summary
101   --mailback                 only produce a report in case of warnings/errors
102   --summary-file             include the filename in summary
103   --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
104                              'values', 'possible', 'type', and 'attr' (default
105                              is all off)
106   --test-only=WORD           report only warnings/errors containing WORD
107                              literally
108   --fix                      EXPERIMENTAL - may create horrible results
109                              If correctable single-line errors exist, create
110                              "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
111                              with potential errors corrected to the preferred
112                              checkpatch style
113   --fix-inplace              EXPERIMENTAL - may create horrible results
114                              Is the same as --fix, but overwrites the input
115                              file.  It's your fault if there's no backup or git
116   --ignore-perl-version      override checking of perl version.  expect
117                              runtime errors.
118   --codespell                Use the codespell dictionary for spelling/typos
119                              (default:/usr/share/codespell/dictionary.txt)
120   --codespellfile            Use this codespell dictionary
121   --typedefsfile             Read additional types from this file
122   --color[=WHEN]             Use colors 'always', 'never', or only when output
123                              is a terminal ('auto'). Default is 'auto'.
124   -h, --help, --version      display this help and exit
125
126 When FILE is - read standard input.
127 EOM
128
129         exit($exitcode);
130 }
131
132 sub uniq {
133         my %seen;
134         return grep { !$seen{$_}++ } @_;
135 }
136
137 sub list_types {
138         my ($exitcode) = @_;
139
140         my $count = 0;
141
142         local $/ = undef;
143
144         open(my $script, '<', abs_path($P)) or
145             die "$P: Can't read '$P' $!\n";
146
147         my $text = <$script>;
148         close($script);
149
150         my @types = ();
151         for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) {
152                 push (@types, $_);
153         }
154         @types = sort(uniq(@types));
155         print("#\tMessage type\n\n");
156         foreach my $type (@types) {
157                 print(++$count . "\t" . $type . "\n");
158         }
159
160         exit($exitcode);
161 }
162
163 my $conf = which_conf($configuration_file);
164 if (-f $conf) {
165         my @conf_args;
166         open(my $conffile, '<', "$conf")
167             or warn "$P: Can't find a readable $configuration_file file $!\n";
168
169         while (<$conffile>) {
170                 my $line = $_;
171
172                 $line =~ s/\s*\n?$//g;
173                 $line =~ s/^\s*//g;
174                 $line =~ s/\s+/ /g;
175
176                 next if ($line =~ m/^\s*#/);
177                 next if ($line =~ m/^\s*$/);
178
179                 my @words = split(" ", $line);
180                 foreach my $word (@words) {
181                         last if ($word =~ m/^#/);
182                         push (@conf_args, $word);
183                 }
184         }
185         close($conffile);
186         unshift(@ARGV, @conf_args) if @conf_args;
187 }
188
189 # Perl's Getopt::Long allows options to take optional arguments after a space.
190 # Prevent --color by itself from consuming other arguments
191 foreach (@ARGV) {
192         if ($_ eq "--color" || $_ eq "-color") {
193                 $_ = "--color=$color";
194         }
195 }
196
197 GetOptions(
198         'q|quiet+'      => \$quiet,
199         'tree!'         => \$tree,
200         'signoff!'      => \$chk_signoff,
201         'patch!'        => \$chk_patch,
202         'emacs!'        => \$emacs,
203         'terse!'        => \$terse,
204         'showfile!'     => \$showfile,
205         'f|file!'       => \$file,
206         'g|git!'        => \$git,
207         'subjective!'   => \$check,
208         'strict!'       => \$check,
209         'ignore=s'      => \@ignore,
210         'types=s'       => \@use,
211         'show-types!'   => \$show_types,
212         'list-types!'   => \$list_types,
213         'max-line-length=i' => \$max_line_length,
214         'min-conf-desc-length=i' => \$min_conf_desc_length,
215         'root=s'        => \$root,
216         'summary!'      => \$summary,
217         'mailback!'     => \$mailback,
218         'summary-file!' => \$summary_file,
219         'fix!'          => \$fix,
220         'fix-inplace!'  => \$fix_inplace,
221         'ignore-perl-version!' => \$ignore_perl_version,
222         'debug=s'       => \%debug,
223         'test-only=s'   => \$tst_only,
224         'codespell!'    => \$codespell,
225         'codespellfile=s'       => \$codespellfile,
226         'typedefsfile=s'        => \$typedefsfile,
227         'color=s'       => \$color,
228         'no-color'      => \$color,     #keep old behaviors of -nocolor
229         'nocolor'       => \$color,     #keep old behaviors of -nocolor
230         'h|help'        => \$help,
231         'version'       => \$help
232 ) or help(1);
233
234 help(0) if ($help);
235
236 list_types(0) if ($list_types);
237
238 $fix = 1 if ($fix_inplace);
239 $check_orig = $check;
240
241 my $exit = 0;
242
243 if ($^V && $^V lt $minimum_perl_version) {
244         printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
245         if (!$ignore_perl_version) {
246                 exit(1);
247         }
248 }
249
250 #if no filenames are given, push '-' to read patch from stdin
251 if ($#ARGV < 0) {
252         push(@ARGV, '-');
253 }
254
255 if ($color =~ /^[01]$/) {
256         $color = !$color;
257 } elsif ($color =~ /^always$/i) {
258         $color = 1;
259 } elsif ($color =~ /^never$/i) {
260         $color = 0;
261 } elsif ($color =~ /^auto$/i) {
262         $color = (-t STDOUT);
263 } else {
264         die "Invalid color mode: $color\n";
265 }
266
267 sub hash_save_array_words {
268         my ($hashRef, $arrayRef) = @_;
269
270         my @array = split(/,/, join(',', @$arrayRef));
271         foreach my $word (@array) {
272                 $word =~ s/\s*\n?$//g;
273                 $word =~ s/^\s*//g;
274                 $word =~ s/\s+/ /g;
275                 $word =~ tr/[a-z]/[A-Z]/;
276
277                 next if ($word =~ m/^\s*#/);
278                 next if ($word =~ m/^\s*$/);
279
280                 $hashRef->{$word}++;
281         }
282 }
283
284 sub hash_show_words {
285         my ($hashRef, $prefix) = @_;
286
287         if (keys %$hashRef) {
288                 print "\nNOTE: $prefix message types:";
289                 foreach my $word (sort keys %$hashRef) {
290                         print " $word";
291                 }
292                 print "\n";
293         }
294 }
295
296 hash_save_array_words(\%ignore_type, \@ignore);
297 hash_save_array_words(\%use_type, \@use);
298
299 my $dbg_values = 0;
300 my $dbg_possible = 0;
301 my $dbg_type = 0;
302 my $dbg_attr = 0;
303 for my $key (keys %debug) {
304         ## no critic
305         eval "\${dbg_$key} = '$debug{$key}';";
306         die "$@" if ($@);
307 }
308
309 my $rpt_cleaners = 0;
310
311 if ($terse) {
312         $emacs = 1;
313         $quiet++;
314 }
315
316 if ($tree) {
317         if (defined $root) {
318                 if (!top_of_kernel_tree($root)) {
319                         die "$P: $root: --root does not point at a valid tree\n";
320                 }
321         } else {
322                 if (top_of_kernel_tree('.')) {
323                         $root = '.';
324                 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
325                                                 top_of_kernel_tree($1)) {
326                         $root = $1;
327                 }
328         }
329
330         if (!defined $root) {
331                 print "Must be run from the top-level dir. of a kernel tree\n";
332                 exit(2);
333         }
334 }
335
336 my $emitted_corrupt = 0;
337
338 our $Ident      = qr{
339                         [A-Za-z_][A-Za-z\d_]*
340                         (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
341                 }x;
342 our $Storage    = qr{extern|static|asmlinkage};
343 our $Sparse     = qr{
344                         __user|
345                         __kernel|
346                         __force|
347                         __iomem|
348                         __must_check|
349                         __init_refok|
350                         __kprobes|
351                         __ref|
352                         __rcu|
353                         __private
354                 }x;
355 our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
356 our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
357 our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
358 our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
359 our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
360
361 # Notes to $Attribute:
362 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
363 our $Attribute  = qr{
364                         const|
365                         __percpu|
366                         __nocast|
367                         __safe|
368                         __bitwise|
369                         __packed__|
370                         __packed2__|
371                         __naked|
372                         __maybe_unused|
373                         __always_unused|
374                         __noreturn|
375                         __used|
376                         __cold|
377                         __pure|
378                         __noclone|
379                         __deprecated|
380                         __read_mostly|
381                         __kprobes|
382                         $InitAttribute|
383                         ____cacheline_aligned|
384                         ____cacheline_aligned_in_smp|
385                         ____cacheline_internodealigned_in_smp|
386                         __weak
387                   }x;
388 our $Modifier;
389 our $Inline     = qr{inline|__always_inline|noinline|__inline|__inline__};
390 our $Member     = qr{->$Ident|\.$Ident|\[[^]]*\]};
391 our $Lval       = qr{$Ident(?:$Member)*};
392
393 our $Int_type   = qr{(?i)llu|ull|ll|lu|ul|l|u};
394 our $Binary     = qr{(?i)0b[01]+$Int_type?};
395 our $Hex        = qr{(?i)0x[0-9a-f]+$Int_type?};
396 our $Int        = qr{[0-9]+$Int_type?};
397 our $Octal      = qr{0[0-7]+$Int_type?};
398 our $String     = qr{"[X\t]*"};
399 our $Float_hex  = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
400 our $Float_dec  = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
401 our $Float_int  = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
402 our $Float      = qr{$Float_hex|$Float_dec|$Float_int};
403 our $Constant   = qr{$Float|$Binary|$Octal|$Hex|$Int};
404 our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
405 our $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
406 our $Arithmetic = qr{\+|-|\*|\/|%};
407 our $Operators  = qr{
408                         <=|>=|==|!=|
409                         =>|->|<<|>>|<|>|!|~|
410                         &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
411                   }x;
412
413 our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
414
415 our $BasicType;
416 our $NonptrType;
417 our $NonptrTypeMisordered;
418 our $NonptrTypeWithAttr;
419 our $Type;
420 our $TypeMisordered;
421 our $Declare;
422 our $DeclareMisordered;
423
424 our $NON_ASCII_UTF8     = qr{
425         [\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
426         |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
427         | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
428         |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
429         |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
430         | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
431         |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
432 }x;
433
434 our $UTF8       = qr{
435         [\x09\x0A\x0D\x20-\x7E]              # ASCII
436         | $NON_ASCII_UTF8
437 }x;
438
439 our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
440 our $typeOtherOSTypedefs = qr{(?x:
441         u_(?:char|short|int|long) |          # bsd
442         u(?:nchar|short|int|long)            # sysv
443 )};
444 our $typeKernelTypedefs = qr{(?x:
445         (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
446         atomic_t
447 )};
448 our $typeTypedefs = qr{(?x:
449         $typeC99Typedefs\b|
450         $typeOtherOSTypedefs\b|
451         $typeKernelTypedefs\b
452 )};
453
454 our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
455
456 our $logFunctions = qr{(?x:
457         printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
458         (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
459         WARN(?:_RATELIMIT|_ONCE|)|
460         CDEBUG|CERROR|CL_LOCK_DEBUG|CWARN|DEBUG_REQ|LCONSOLE_[A-Z]*|
461         panic|
462         MODULE_[A-Z_]+|
463         seq_vprintf|seq_printf|seq_puts
464 )};
465
466 our $signature_tags = qr{(?xi:
467         Signed-off-by:|
468         Acked-by:|
469         Tested-by:|
470         Reviewed-by:|
471         Reported-by:|
472         Suggested-by:|
473         To:|
474         Cc:
475 )};
476
477 our @typeListMisordered = (
478         qr{char\s+(?:un)?signed},
479         qr{int\s+(?:(?:un)?signed\s+)?short\s},
480         qr{int\s+short(?:\s+(?:un)?signed)},
481         qr{short\s+int(?:\s+(?:un)?signed)},
482         qr{(?:un)?signed\s+int\s+short},
483         qr{short\s+(?:un)?signed},
484         qr{long\s+int\s+(?:un)?signed},
485         qr{int\s+long\s+(?:un)?signed},
486         qr{long\s+(?:un)?signed\s+int},
487         qr{int\s+(?:un)?signed\s+long},
488         qr{int\s+(?:un)?signed},
489         qr{int\s+long\s+long\s+(?:un)?signed},
490         qr{long\s+long\s+int\s+(?:un)?signed},
491         qr{long\s+long\s+(?:un)?signed\s+int},
492         qr{long\s+long\s+(?:un)?signed},
493         qr{long\s+(?:un)?signed},
494 );
495
496 our @typeList = (
497         qr{void},
498         qr{(?:(?:un)?signed\s+)?char},
499         qr{(?:(?:un)?signed\s+)?short\s+int},
500         qr{(?:(?:un)?signed\s+)?short},
501         qr{(?:(?:un)?signed\s+)?int},
502         qr{(?:(?:un)?signed\s+)?long\s+int},
503         qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
504         qr{(?:(?:un)?signed\s+)?long\s+long},
505         qr{(?:(?:un)?signed\s+)?long},
506         qr{(?:un)?signed},
507         qr{float},
508         qr{double},
509         qr{bool},
510         qr{struct\s+$Ident},
511         qr{union\s+$Ident},
512         qr{enum\s+$Ident},
513         qr{${Ident}_t},
514         qr{${Ident}_handler},
515         qr{${Ident}_handler_fn},
516         @typeListMisordered,
517 );
518
519 our $C90_int_types = qr{(?x:
520         long\s+long\s+int\s+(?:un)?signed|
521         long\s+long\s+(?:un)?signed\s+int|
522         long\s+long\s+(?:un)?signed|
523         (?:(?:un)?signed\s+)?long\s+long\s+int|
524         (?:(?:un)?signed\s+)?long\s+long|
525         int\s+long\s+long\s+(?:un)?signed|
526         int\s+(?:(?:un)?signed\s+)?long\s+long|
527
528         long\s+int\s+(?:un)?signed|
529         long\s+(?:un)?signed\s+int|
530         long\s+(?:un)?signed|
531         (?:(?:un)?signed\s+)?long\s+int|
532         (?:(?:un)?signed\s+)?long|
533         int\s+long\s+(?:un)?signed|
534         int\s+(?:(?:un)?signed\s+)?long|
535
536         int\s+(?:un)?signed|
537         (?:(?:un)?signed\s+)?int
538 )};
539
540 our @typeListFile = ();
541 our @typeListWithAttr = (
542         @typeList,
543         qr{struct\s+$InitAttribute\s+$Ident},
544         qr{union\s+$InitAttribute\s+$Ident},
545 );
546
547 our @modifierList = (
548         qr{fastcall},
549 );
550 our @modifierListFile = ();
551
552 our @mode_permission_funcs = (
553         ["module_param", 3],
554         ["module_param_(?:array|named|string)", 4],
555         ["module_param_array_named", 5],
556         ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
557         ["proc_create(?:_data|)", 2],
558         ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
559         ["IIO_DEV_ATTR_[A-Z_]+", 1],
560         ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
561         ["SENSOR_TEMPLATE(?:_2|)", 3],
562         ["__ATTR", 2],
563 );
564
565 #Create a search pattern for all these functions to speed up a loop below
566 our $mode_perms_search = "";
567 foreach my $entry (@mode_permission_funcs) {
568         $mode_perms_search .= '|' if ($mode_perms_search ne "");
569         $mode_perms_search .= $entry->[0];
570 }
571
572 our $mode_perms_world_writable = qr{
573         S_IWUGO         |
574         S_IWOTH         |
575         S_IRWXUGO       |
576         S_IALLUGO       |
577         0[0-7][0-7][2367]
578 }x;
579
580 our %mode_permission_string_types = (
581         "S_IRWXU" => 0700,
582         "S_IRUSR" => 0400,
583         "S_IWUSR" => 0200,
584         "S_IXUSR" => 0100,
585         "S_IRWXG" => 0070,
586         "S_IRGRP" => 0040,
587         "S_IWGRP" => 0020,
588         "S_IXGRP" => 0010,
589         "S_IRWXO" => 0007,
590         "S_IROTH" => 0004,
591         "S_IWOTH" => 0002,
592         "S_IXOTH" => 0001,
593         "S_IRWXUGO" => 0777,
594         "S_IRUGO" => 0444,
595         "S_IWUGO" => 0222,
596         "S_IXUGO" => 0111,
597 );
598
599 #Create a search pattern for all these strings to speed up a loop below
600 our $mode_perms_string_search = "";
601 foreach my $entry (keys %mode_permission_string_types) {
602         $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
603         $mode_perms_string_search .= $entry;
604 }
605
606 our $allowed_asm_includes = qr{(?x:
607         irq|
608         memory|
609         time|
610         reboot
611 )};
612 # memory.h: ARM has a custom one
613
614 # Load common spelling mistakes and build regular expression list.
615 my $misspellings;
616 my %spelling_fix;
617
618 if (open(my $spelling, '<', $spelling_file)) {
619         while (<$spelling>) {
620                 my $line = $_;
621
622                 $line =~ s/\s*\n?$//g;
623                 $line =~ s/^\s*//g;
624
625                 next if ($line =~ m/^\s*#/);
626                 next if ($line =~ m/^\s*$/);
627
628                 my ($suspect, $fix) = split(/\|\|/, $line);
629
630                 $spelling_fix{$suspect} = $fix;
631         }
632         close($spelling);
633 } else {
634         warn "No typos will be found - file '$spelling_file': $!\n";
635 }
636
637 if ($codespell) {
638         if (open(my $spelling, '<', $codespellfile)) {
639                 while (<$spelling>) {
640                         my $line = $_;
641
642                         $line =~ s/\s*\n?$//g;
643                         $line =~ s/^\s*//g;
644
645                         next if ($line =~ m/^\s*#/);
646                         next if ($line =~ m/^\s*$/);
647                         next if ($line =~ m/, disabled/i);
648
649                         $line =~ s/,.*$//;
650
651                         my ($suspect, $fix) = split(/->/, $line);
652
653                         $spelling_fix{$suspect} = $fix;
654                 }
655                 close($spelling);
656         } else {
657                 warn "No codespell typos will be found - file '$codespellfile': $!\n";
658         }
659 }
660
661 $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
662
663 sub read_words {
664         my ($wordsRef, $file) = @_;
665
666         if (open(my $words, '<', $file)) {
667                 while (<$words>) {
668                         my $line = $_;
669
670                         $line =~ s/\s*\n?$//g;
671                         $line =~ s/^\s*//g;
672
673                         next if ($line =~ m/^\s*#/);
674                         next if ($line =~ m/^\s*$/);
675                         if ($line =~ /\s/) {
676                                 print("$file: '$line' invalid - ignored\n");
677                                 next;
678                         }
679
680                         $$wordsRef .= '|' if ($$wordsRef ne "");
681                         $$wordsRef .= $line;
682                 }
683                 close($file);
684                 return 1;
685         }
686
687         return 0;
688 }
689
690 my $const_structs = "";
691 read_words(\$const_structs, $conststructsfile)
692     or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
693
694 my $typeOtherTypedefs = "";
695 if (length($typedefsfile)) {
696         read_words(\$typeOtherTypedefs, $typedefsfile)
697             or warn "No additional types will be considered - file '$typedefsfile': $!\n";
698 }
699 $typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
700
701 sub build_types {
702         my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
703         my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
704         my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
705         my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
706         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};
707         $BasicType      = qr{
708                                 (?:$typeTypedefs\b)|
709                                 (?:${all}\b)
710                 }x;
711         $NonptrType     = qr{
712                         (?:$Modifier\s+|const\s+)*
713                         (?:
714                                 (?:typeof|__typeof__)\s*\([^\)]*\)|
715                                 (?:$typeTypedefs\b)|
716                                 (?:${all}\b)
717                         )
718                         (?:\s+$Modifier|\s+const)*
719                   }x;
720         $NonptrTypeMisordered   = qr{
721                         (?:$Modifier\s+|const\s+)*
722                         (?:
723                                 (?:${Misordered}\b)
724                         )
725                         (?:\s+$Modifier|\s+const)*
726                   }x;
727         $NonptrTypeWithAttr     = qr{
728                         (?:$Modifier\s+|const\s+)*
729                         (?:
730                                 (?:typeof|__typeof__)\s*\([^\)]*\)|
731                                 (?:$typeTypedefs\b)|
732                                 (?:${allWithAttr}\b)
733                         )
734                         (?:\s+$Modifier|\s+const)*
735                   }x;
736         $Type   = qr{
737                         $NonptrType
738                         (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
739                         (?:\s+$Inline|\s+$Modifier)*
740                   }x;
741         $TypeMisordered = qr{
742                         $NonptrTypeMisordered
743                         (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
744                         (?:\s+$Inline|\s+$Modifier)*
745                   }x;
746         $Declare        = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
747         $DeclareMisordered      = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
748 }
749 build_types();
750
751 our $Typecast   = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
752
753 # Using $balanced_parens, $LvalOrFunc, or $FuncArg
754 # requires at least perl version v5.10.0
755 # Any use must be runtime checked with $^V
756
757 our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
758 our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
759 our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
760
761 our $declaration_macros = qr{(?x:
762         (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
763         (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
764         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
765 )};
766
767 sub deparenthesize {
768         my ($string) = @_;
769         return "" if (!defined($string));
770
771         while ($string =~ /^\s*\(.*\)\s*$/) {
772                 $string =~ s@^\s*\(\s*@@;
773                 $string =~ s@\s*\)\s*$@@;
774         }
775
776         $string =~ s@\s+@ @g;
777
778         return $string;
779 }
780
781 sub seed_camelcase_file {
782         my ($file) = @_;
783
784         return if (!(-f $file));
785
786         local $/;
787
788         open(my $include_file, '<', "$file")
789             or warn "$P: Can't read '$file' $!\n";
790         my $text = <$include_file>;
791         close($include_file);
792
793         my @lines = split('\n', $text);
794
795         foreach my $line (@lines) {
796                 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
797                 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
798                         $camelcase{$1} = 1;
799                 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
800                         $camelcase{$1} = 1;
801                 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
802                         $camelcase{$1} = 1;
803                 }
804         }
805 }
806
807 sub is_maintained_obsolete {
808         my ($filename) = @_;
809
810         return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
811
812         my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
813
814         return $status =~ /obsolete/i;
815 }
816
817 my $camelcase_seeded = 0;
818 sub seed_camelcase_includes {
819         return if ($camelcase_seeded);
820
821         my $files;
822         my $camelcase_cache = "";
823         my @include_files = ();
824
825         $camelcase_seeded = 1;
826
827         if (-e ".git") {
828                 my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
829                 chomp $git_last_include_commit;
830                 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
831         } else {
832                 my $last_mod_date = 0;
833                 $files = `find $root/include -name "*.h"`;
834                 @include_files = split('\n', $files);
835                 foreach my $file (@include_files) {
836                         my $date = POSIX::strftime("%Y%m%d%H%M",
837                                                    localtime((stat $file)[9]));
838                         $last_mod_date = $date if ($last_mod_date < $date);
839                 }
840                 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
841         }
842
843         if ($camelcase_cache ne "" && -f $camelcase_cache) {
844                 open(my $camelcase_file, '<', "$camelcase_cache")
845                     or warn "$P: Can't read '$camelcase_cache' $!\n";
846                 while (<$camelcase_file>) {
847                         chomp;
848                         $camelcase{$_} = 1;
849                 }
850                 close($camelcase_file);
851
852                 return;
853         }
854
855         if (-e ".git") {
856                 $files = `git ls-files "include/*.h"`;
857                 @include_files = split('\n', $files);
858         }
859
860         foreach my $file (@include_files) {
861                 seed_camelcase_file($file);
862         }
863
864         if ($camelcase_cache ne "") {
865                 unlink glob ".checkpatch-camelcase.*";
866                 open(my $camelcase_file, '>', "$camelcase_cache")
867                     or warn "$P: Can't write '$camelcase_cache' $!\n";
868                 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
869                         print $camelcase_file ("$_\n");
870                 }
871                 close($camelcase_file);
872         }
873 }
874
875 sub git_commit_info {
876         my ($commit, $id, $desc) = @_;
877
878         return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
879
880         my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
881         $output =~ s/^\s*//gm;
882         my @lines = split("\n", $output);
883
884         return ($id, $desc) if ($#lines < 0);
885
886         if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
887 # Maybe one day convert this block of bash into something that returns
888 # all matching commit ids, but it's very slow...
889 #
890 #               echo "checking commits $1..."
891 #               git rev-list --remotes | grep -i "^$1" |
892 #               while read line ; do
893 #                   git log --format='%H %s' -1 $line |
894 #                   echo "commit $(cut -c 1-12,41-)"
895 #               done
896         } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
897                 $id = undef;
898         } else {
899                 $id = substr($lines[0], 0, 12);
900                 $desc = substr($lines[0], 41);
901         }
902
903         return ($id, $desc);
904 }
905
906 $chk_signoff = 0 if ($file);
907
908 my @rawlines = ();
909 my @lines = ();
910 my @fixed = ();
911 my @fixed_inserted = ();
912 my @fixed_deleted = ();
913 my $fixlinenr = -1;
914
915 # If input is git commits, extract all commits from the commit expressions.
916 # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
917 die "$P: No git repository found\n" if ($git && !-e ".git");
918
919 if ($git) {
920         my @commits = ();
921         foreach my $commit_expr (@ARGV) {
922                 my $git_range;
923                 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
924                         $git_range = "-$2 $1";
925                 } elsif ($commit_expr =~ m/\.\./) {
926                         $git_range = "$commit_expr";
927                 } else {
928                         $git_range = "-1 $commit_expr";
929                 }
930                 my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
931                 foreach my $line (split(/\n/, $lines)) {
932                         $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
933                         next if (!defined($1) || !defined($2));
934                         my $sha1 = $1;
935                         my $subject = $2;
936                         unshift(@commits, $sha1);
937                         $git_commits{$sha1} = $subject;
938                 }
939         }
940         die "$P: no git commits after extraction!\n" if (@commits == 0);
941         @ARGV = @commits;
942 }
943
944 my $vname;
945 for my $filename (@ARGV) {
946         my $FILE;
947         if ($git) {
948                 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
949                         die "$P: $filename: git format-patch failed - $!\n";
950         } elsif ($file) {
951                 open($FILE, '-|', "diff -u /dev/null $filename") ||
952                         die "$P: $filename: diff failed - $!\n";
953         } elsif ($filename eq '-') {
954                 open($FILE, '<&STDIN');
955         } else {
956                 open($FILE, '<', "$filename") ||
957                         die "$P: $filename: open failed - $!\n";
958         }
959         if ($filename eq '-') {
960                 $vname = 'Your patch';
961         } elsif ($git) {
962                 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
963         } else {
964                 $vname = $filename;
965         }
966         while (<$FILE>) {
967                 chomp;
968                 push(@rawlines, $_);
969         }
970         close($FILE);
971
972         if ($#ARGV > 0 && $quiet == 0) {
973                 print '-' x length($vname) . "\n";
974                 print "$vname\n";
975                 print '-' x length($vname) . "\n";
976         }
977
978         if (!process($filename)) {
979                 $exit = 1;
980         }
981         @rawlines = ();
982         @lines = ();
983         @fixed = ();
984         @fixed_inserted = ();
985         @fixed_deleted = ();
986         $fixlinenr = -1;
987         @modifierListFile = ();
988         @typeListFile = ();
989         build_types();
990 }
991
992 if (!$quiet) {
993         hash_show_words(\%use_type, "Used");
994         hash_show_words(\%ignore_type, "Ignored");
995
996         if ($^V lt 5.10.0) {
997                 print << "EOM"
998
999 NOTE: perl $^V is not modern enough to detect all possible issues.
1000       An upgrade to at least perl v5.10.0 is suggested.
1001 EOM
1002         }
1003         if ($exit) {
1004                 print << "EOM"
1005
1006 NOTE: If any of the errors are false positives, please report
1007       them to the maintainer, see CHECKPATCH in MAINTAINERS.
1008 EOM
1009         }
1010 }
1011
1012 exit($exit);
1013
1014 sub top_of_kernel_tree {
1015         my ($root) = @_;
1016
1017         my @tree_check = (
1018                 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
1019                 "README", "Documentation", "arch", "include", "drivers",
1020                 "fs", "init", "ipc", "kernel", "lib", "scripts",
1021         );
1022
1023         foreach my $check (@tree_check) {
1024                 if (! -e $root . '/' . $check) {
1025                         return 0;
1026                 }
1027         }
1028         return 1;
1029 }
1030
1031 sub parse_email {
1032         my ($formatted_email) = @_;
1033
1034         my $name = "";
1035         my $address = "";
1036         my $comment = "";
1037
1038         if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1039                 $name = $1;
1040                 $address = $2;
1041                 $comment = $3 if defined $3;
1042         } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1043                 $address = $1;
1044                 $comment = $2 if defined $2;
1045         } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1046                 $address = $1;
1047                 $comment = $2 if defined $2;
1048                 $formatted_email =~ s/$address.*$//;
1049                 $name = $formatted_email;
1050                 $name = trim($name);
1051                 $name =~ s/^\"|\"$//g;
1052                 # If there's a name left after stripping spaces and
1053                 # leading quotes, and the address doesn't have both
1054                 # leading and trailing angle brackets, the address
1055                 # is invalid. ie:
1056                 #   "joe smith joe@smith.com" bad
1057                 #   "joe smith <joe@smith.com" bad
1058                 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1059                         $name = "";
1060                         $address = "";
1061                         $comment = "";
1062                 }
1063         }
1064
1065         $name = trim($name);
1066         $name =~ s/^\"|\"$//g;
1067         $address = trim($address);
1068         $address =~ s/^\<|\>$//g;
1069
1070         if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1071                 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1072                 $name = "\"$name\"";
1073         }
1074
1075         return ($name, $address, $comment);
1076 }
1077
1078 sub format_email {
1079         my ($name, $address) = @_;
1080
1081         my $formatted_email;
1082
1083         $name = trim($name);
1084         $name =~ s/^\"|\"$//g;
1085         $address = trim($address);
1086
1087         if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1088                 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1089                 $name = "\"$name\"";
1090         }
1091
1092         if ("$name" eq "") {
1093                 $formatted_email = "$address";
1094         } else {
1095                 $formatted_email = "$name <$address>";
1096         }
1097
1098         return $formatted_email;
1099 }
1100
1101 sub which {
1102         my ($bin) = @_;
1103
1104         foreach my $path (split(/:/, $ENV{PATH})) {
1105                 if (-e "$path/$bin") {
1106                         return "$path/$bin";
1107                 }
1108         }
1109
1110         return "";
1111 }
1112
1113 sub which_conf {
1114         my ($conf) = @_;
1115
1116         foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1117                 if (-e "$path/$conf") {
1118                         return "$path/$conf";
1119                 }
1120         }
1121
1122         return "";
1123 }
1124
1125 sub expand_tabs {
1126         my ($str) = @_;
1127
1128         my $res = '';
1129         my $n = 0;
1130         for my $c (split(//, $str)) {
1131                 if ($c eq "\t") {
1132                         $res .= ' ';
1133                         $n++;
1134                         for (; ($n % 8) != 0; $n++) {
1135                                 $res .= ' ';
1136                         }
1137                         next;
1138                 }
1139                 $res .= $c;
1140                 $n++;
1141         }
1142
1143         return $res;
1144 }
1145 sub copy_spacing {
1146         (my $res = shift) =~ tr/\t/ /c;
1147         return $res;
1148 }
1149
1150 sub line_stats {
1151         my ($line) = @_;
1152
1153         # Drop the diff line leader and expand tabs
1154         $line =~ s/^.//;
1155         $line = expand_tabs($line);
1156
1157         # Pick the indent from the front of the line.
1158         my ($white) = ($line =~ /^(\s*)/);
1159
1160         return (length($line), length($white));
1161 }
1162
1163 my $sanitise_quote = '';
1164
1165 sub sanitise_line_reset {
1166         my ($in_comment) = @_;
1167
1168         if ($in_comment) {
1169                 $sanitise_quote = '*/';
1170         } else {
1171                 $sanitise_quote = '';
1172         }
1173 }
1174 sub sanitise_line {
1175         my ($line) = @_;
1176
1177         my $res = '';
1178         my $l = '';
1179
1180         my $qlen = 0;
1181         my $off = 0;
1182         my $c;
1183
1184         # Always copy over the diff marker.
1185         $res = substr($line, 0, 1);
1186
1187         for ($off = 1; $off < length($line); $off++) {
1188                 $c = substr($line, $off, 1);
1189
1190                 # Comments we are wacking completly including the begin
1191                 # and end, all to $;.
1192                 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1193                         $sanitise_quote = '*/';
1194
1195                         substr($res, $off, 2, "$;$;");
1196                         $off++;
1197                         next;
1198                 }
1199                 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1200                         $sanitise_quote = '';
1201                         substr($res, $off, 2, "$;$;");
1202                         $off++;
1203                         next;
1204                 }
1205                 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1206                         $sanitise_quote = '//';
1207
1208                         substr($res, $off, 2, $sanitise_quote);
1209                         $off++;
1210                         next;
1211                 }
1212
1213                 # A \ in a string means ignore the next character.
1214                 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1215                     $c eq "\\") {
1216                         substr($res, $off, 2, 'XX');
1217                         $off++;
1218                         next;
1219                 }
1220                 # Regular quotes.
1221                 if ($c eq "'" || $c eq '"') {
1222                         if ($sanitise_quote eq '') {
1223                                 $sanitise_quote = $c;
1224
1225                                 substr($res, $off, 1, $c);
1226                                 next;
1227                         } elsif ($sanitise_quote eq $c) {
1228                                 $sanitise_quote = '';
1229                         }
1230                 }
1231
1232                 #print "c<$c> SQ<$sanitise_quote>\n";
1233                 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1234                         substr($res, $off, 1, $;);
1235                 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1236                         substr($res, $off, 1, $;);
1237                 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1238                         substr($res, $off, 1, 'X');
1239                 } else {
1240                         substr($res, $off, 1, $c);
1241                 }
1242         }
1243
1244         if ($sanitise_quote eq '//') {
1245                 $sanitise_quote = '';
1246         }
1247
1248         # The pathname on a #include may be surrounded by '<' and '>'.
1249         if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1250                 my $clean = 'X' x length($1);
1251                 $res =~ s@\<.*\>@<$clean>@;
1252
1253         # The whole of a #error is a string.
1254         } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1255                 my $clean = 'X' x length($1);
1256                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1257         }
1258
1259         if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1260                 my $match = $1;
1261                 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1262         }
1263
1264         return $res;
1265 }
1266
1267 sub get_quoted_string {
1268         my ($line, $rawline) = @_;
1269
1270         return "" if ($line !~ m/($String)/g);
1271         return substr($rawline, $-[0], $+[0] - $-[0]);
1272 }
1273
1274 sub ctx_statement_block {
1275         my ($linenr, $remain, $off) = @_;
1276         my $line = $linenr - 1;
1277         my $blk = '';
1278         my $soff = $off;
1279         my $coff = $off - 1;
1280         my $coff_set = 0;
1281
1282         my $loff = 0;
1283
1284         my $type = '';
1285         my $level = 0;
1286         my @stack = ();
1287         my $p;
1288         my $c;
1289         my $len = 0;
1290
1291         my $remainder;
1292         while (1) {
1293                 @stack = (['', 0]) if ($#stack == -1);
1294
1295                 #warn "CSB: blk<$blk> remain<$remain>\n";
1296                 # If we are about to drop off the end, pull in more
1297                 # context.
1298                 if ($off >= $len) {
1299                         for (; $remain > 0; $line++) {
1300                                 last if (!defined $lines[$line]);
1301                                 next if ($lines[$line] =~ /^-/);
1302                                 $remain--;
1303                                 $loff = $len;
1304                                 $blk .= $lines[$line] . "\n";
1305                                 $len = length($blk);
1306                                 $line++;
1307                                 last;
1308                         }
1309                         # Bail if there is no further context.
1310                         #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1311                         if ($off >= $len) {
1312                                 last;
1313                         }
1314                         if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1315                                 $level++;
1316                                 $type = '#';
1317                         }
1318                 }
1319                 $p = $c;
1320                 $c = substr($blk, $off, 1);
1321                 $remainder = substr($blk, $off);
1322
1323                 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1324
1325                 # Handle nested #if/#else.
1326                 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1327                         push(@stack, [ $type, $level ]);
1328                 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1329                         ($type, $level) = @{$stack[$#stack - 1]};
1330                 } elsif ($remainder =~ /^#\s*endif\b/) {
1331                         ($type, $level) = @{pop(@stack)};
1332                 }
1333
1334                 # Statement ends at the ';' or a close '}' at the
1335                 # outermost level.
1336                 if ($level == 0 && $c eq ';') {
1337                         last;
1338                 }
1339
1340                 # An else is really a conditional as long as its not else if
1341                 if ($level == 0 && $coff_set == 0 &&
1342                                 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1343                                 $remainder =~ /^(else)(?:\s|{)/ &&
1344                                 $remainder !~ /^else\s+if\b/) {
1345                         $coff = $off + length($1) - 1;
1346                         $coff_set = 1;
1347                         #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1348                         #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1349                 }
1350
1351                 if (($type eq '' || $type eq '(') && $c eq '(') {
1352                         $level++;
1353                         $type = '(';
1354                 }
1355                 if ($type eq '(' && $c eq ')') {
1356                         $level--;
1357                         $type = ($level != 0)? '(' : '';
1358
1359                         if ($level == 0 && $coff < $soff) {
1360                                 $coff = $off;
1361                                 $coff_set = 1;
1362                                 #warn "CSB: mark coff<$coff>\n";
1363                         }
1364                 }
1365                 if (($type eq '' || $type eq '{') && $c eq '{') {
1366                         $level++;
1367                         $type = '{';
1368                 }
1369                 if ($type eq '{' && $c eq '}') {
1370                         $level--;
1371                         $type = ($level != 0)? '{' : '';
1372
1373                         if ($level == 0) {
1374                                 if (substr($blk, $off + 1, 1) eq ';') {
1375                                         $off++;
1376                                 }
1377                                 last;
1378                         }
1379                 }
1380                 # Preprocessor commands end at the newline unless escaped.
1381                 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1382                         $level--;
1383                         $type = '';
1384                         $off++;
1385                         last;
1386                 }
1387                 $off++;
1388         }
1389         # We are truly at the end, so shuffle to the next line.
1390         if ($off == $len) {
1391                 $loff = $len + 1;
1392                 $line++;
1393                 $remain--;
1394         }
1395
1396         my $statement = substr($blk, $soff, $off - $soff + 1);
1397         my $condition = substr($blk, $soff, $coff - $soff + 1);
1398
1399         #warn "STATEMENT<$statement>\n";
1400         #warn "CONDITION<$condition>\n";
1401
1402         #print "coff<$coff> soff<$off> loff<$loff>\n";
1403
1404         return ($statement, $condition,
1405                         $line, $remain + 1, $off - $loff + 1, $level);
1406 }
1407
1408 sub statement_lines {
1409         my ($stmt) = @_;
1410
1411         # Strip the diff line prefixes and rip blank lines at start and end.
1412         $stmt =~ s/(^|\n)./$1/g;
1413         $stmt =~ s/^\s*//;
1414         $stmt =~ s/\s*$//;
1415
1416         my @stmt_lines = ($stmt =~ /\n/g);
1417
1418         return $#stmt_lines + 2;
1419 }
1420
1421 sub statement_rawlines {
1422         my ($stmt) = @_;
1423
1424         my @stmt_lines = ($stmt =~ /\n/g);
1425
1426         return $#stmt_lines + 2;
1427 }
1428
1429 sub statement_block_size {
1430         my ($stmt) = @_;
1431
1432         $stmt =~ s/(^|\n)./$1/g;
1433         $stmt =~ s/^\s*{//;
1434         $stmt =~ s/}\s*$//;
1435         $stmt =~ s/^\s*//;
1436         $stmt =~ s/\s*$//;
1437
1438         my @stmt_lines = ($stmt =~ /\n/g);
1439         my @stmt_statements = ($stmt =~ /;/g);
1440
1441         my $stmt_lines = $#stmt_lines + 2;
1442         my $stmt_statements = $#stmt_statements + 1;
1443
1444         if ($stmt_lines > $stmt_statements) {
1445                 return $stmt_lines;
1446         } else {
1447                 return $stmt_statements;
1448         }
1449 }
1450
1451 sub ctx_statement_full {
1452         my ($linenr, $remain, $off) = @_;
1453         my ($statement, $condition, $level);
1454
1455         my (@chunks);
1456
1457         # Grab the first conditional/block pair.
1458         ($statement, $condition, $linenr, $remain, $off, $level) =
1459                                 ctx_statement_block($linenr, $remain, $off);
1460         #print "F: c<$condition> s<$statement> remain<$remain>\n";
1461         push(@chunks, [ $condition, $statement ]);
1462         if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1463                 return ($level, $linenr, @chunks);
1464         }
1465
1466         # Pull in the following conditional/block pairs and see if they
1467         # could continue the statement.
1468         for (;;) {
1469                 ($statement, $condition, $linenr, $remain, $off, $level) =
1470                                 ctx_statement_block($linenr, $remain, $off);
1471                 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1472                 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1473                 #print "C: push\n";
1474                 push(@chunks, [ $condition, $statement ]);
1475         }
1476
1477         return ($level, $linenr, @chunks);
1478 }
1479
1480 sub ctx_block_get {
1481         my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1482         my $line;
1483         my $start = $linenr - 1;
1484         my $blk = '';
1485         my @o;
1486         my @c;
1487         my @res = ();
1488
1489         my $level = 0;
1490         my @stack = ($level);
1491         for ($line = $start; $remain > 0; $line++) {
1492                 next if ($rawlines[$line] =~ /^-/);
1493                 $remain--;
1494
1495                 $blk .= $rawlines[$line];
1496
1497                 # Handle nested #if/#else.
1498                 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1499                         push(@stack, $level);
1500                 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1501                         $level = $stack[$#stack - 1];
1502                 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1503                         $level = pop(@stack);
1504                 }
1505
1506                 foreach my $c (split(//, $lines[$line])) {
1507                         ##print "C<$c>L<$level><$open$close>O<$off>\n";
1508                         if ($off > 0) {
1509                                 $off--;
1510                                 next;
1511                         }
1512
1513                         if ($c eq $close && $level > 0) {
1514                                 $level--;
1515                                 last if ($level == 0);
1516                         } elsif ($c eq $open) {
1517                                 $level++;
1518                         }
1519                 }
1520
1521                 if (!$outer || $level <= 1) {
1522                         push(@res, $rawlines[$line]);
1523                 }
1524
1525                 last if ($level == 0);
1526         }
1527
1528         return ($level, @res);
1529 }
1530 sub ctx_block_outer {
1531         my ($linenr, $remain) = @_;
1532
1533         my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1534         return @r;
1535 }
1536 sub ctx_block {
1537         my ($linenr, $remain) = @_;
1538
1539         my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1540         return @r;
1541 }
1542 sub ctx_statement {
1543         my ($linenr, $remain, $off) = @_;
1544
1545         my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1546         return @r;
1547 }
1548 sub ctx_block_level {
1549         my ($linenr, $remain) = @_;
1550
1551         return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1552 }
1553 sub ctx_statement_level {
1554         my ($linenr, $remain, $off) = @_;
1555
1556         return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1557 }
1558
1559 sub ctx_locate_comment {
1560         my ($first_line, $end_line) = @_;
1561
1562         # Catch a comment on the end of the line itself.
1563         my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1564         return $current_comment if (defined $current_comment);
1565
1566         # Look through the context and try and figure out if there is a
1567         # comment.
1568         my $in_comment = 0;
1569         $current_comment = '';
1570         for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1571                 my $line = $rawlines[$linenr - 1];
1572                 #warn "           $line\n";
1573                 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1574                         $in_comment = 1;
1575                 }
1576                 if ($line =~ m@/\*@) {
1577                         $in_comment = 1;
1578                 }
1579                 if (!$in_comment && $current_comment ne '') {
1580                         $current_comment = '';
1581                 }
1582                 $current_comment .= $line . "\n" if ($in_comment);
1583                 if ($line =~ m@\*/@) {
1584                         $in_comment = 0;
1585                 }
1586         }
1587
1588         chomp($current_comment);
1589         return($current_comment);
1590 }
1591 sub ctx_has_comment {
1592         my ($first_line, $end_line) = @_;
1593         my $cmt = ctx_locate_comment($first_line, $end_line);
1594
1595         ##print "LINE: $rawlines[$end_line - 1 ]\n";
1596         ##print "CMMT: $cmt\n";
1597
1598         return ($cmt ne '');
1599 }
1600
1601 sub raw_line {
1602         my ($linenr, $cnt) = @_;
1603
1604         my $offset = $linenr - 1;
1605         $cnt++;
1606
1607         my $line;
1608         while ($cnt) {
1609                 $line = $rawlines[$offset++];
1610                 next if (defined($line) && $line =~ /^-/);
1611                 $cnt--;
1612         }
1613
1614         return $line;
1615 }
1616
1617 sub cat_vet {
1618         my ($vet) = @_;
1619         my ($res, $coded);
1620
1621         $res = '';
1622         while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1623                 $res .= $1;
1624                 if ($2 ne '') {
1625                         $coded = sprintf("^%c", unpack('C', $2) + 64);
1626                         $res .= $coded;
1627                 }
1628         }
1629         $res =~ s/$/\$/;
1630
1631         return $res;
1632 }
1633
1634 my $av_preprocessor = 0;
1635 my $av_pending;
1636 my @av_paren_type;
1637 my $av_pend_colon;
1638
1639 sub annotate_reset {
1640         $av_preprocessor = 0;
1641         $av_pending = '_';
1642         @av_paren_type = ('E');
1643         $av_pend_colon = 'O';
1644 }
1645
1646 sub annotate_values {
1647         my ($stream, $type) = @_;
1648
1649         my $res;
1650         my $var = '_' x length($stream);
1651         my $cur = $stream;
1652
1653         print "$stream\n" if ($dbg_values > 1);
1654
1655         while (length($cur)) {
1656                 @av_paren_type = ('E') if ($#av_paren_type < 0);
1657                 print " <" . join('', @av_paren_type) .
1658                                 "> <$type> <$av_pending>" if ($dbg_values > 1);
1659                 if ($cur =~ /^(\s+)/o) {
1660                         print "WS($1)\n" if ($dbg_values > 1);
1661                         if ($1 =~ /\n/ && $av_preprocessor) {
1662                                 $type = pop(@av_paren_type);
1663                                 $av_preprocessor = 0;
1664                         }
1665
1666                 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1667                         print "CAST($1)\n" if ($dbg_values > 1);
1668                         push(@av_paren_type, $type);
1669                         $type = 'c';
1670
1671                 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1672                         print "DECLARE($1)\n" if ($dbg_values > 1);
1673                         $type = 'T';
1674
1675                 } elsif ($cur =~ /^($Modifier)\s*/) {
1676                         print "MODIFIER($1)\n" if ($dbg_values > 1);
1677                         $type = 'T';
1678
1679                 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1680                         print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1681                         $av_preprocessor = 1;
1682                         push(@av_paren_type, $type);
1683                         if ($2 ne '') {
1684                                 $av_pending = 'N';
1685                         }
1686                         $type = 'E';
1687
1688                 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1689                         print "UNDEF($1)\n" if ($dbg_values > 1);
1690                         $av_preprocessor = 1;
1691                         push(@av_paren_type, $type);
1692
1693                 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1694                         print "PRE_START($1)\n" if ($dbg_values > 1);
1695                         $av_preprocessor = 1;
1696
1697                         push(@av_paren_type, $type);
1698                         push(@av_paren_type, $type);
1699                         $type = 'E';
1700
1701                 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1702                         print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1703                         $av_preprocessor = 1;
1704
1705                         push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1706
1707                         $type = 'E';
1708
1709                 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1710                         print "PRE_END($1)\n" if ($dbg_values > 1);
1711
1712                         $av_preprocessor = 1;
1713
1714                         # Assume all arms of the conditional end as this
1715                         # one does, and continue as if the #endif was not here.
1716                         pop(@av_paren_type);
1717                         push(@av_paren_type, $type);
1718                         $type = 'E';
1719
1720                 } elsif ($cur =~ /^(\\\n)/o) {
1721                         print "PRECONT($1)\n" if ($dbg_values > 1);
1722
1723                 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1724                         print "ATTR($1)\n" if ($dbg_values > 1);
1725                         $av_pending = $type;
1726                         $type = 'N';
1727
1728                 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1729                         print "SIZEOF($1)\n" if ($dbg_values > 1);
1730                         if (defined $2) {
1731                                 $av_pending = 'V';
1732                         }
1733                         $type = 'N';
1734
1735                 } elsif ($cur =~ /^(if|while|for)\b/o) {
1736                         print "COND($1)\n" if ($dbg_values > 1);
1737                         $av_pending = 'E';
1738                         $type = 'N';
1739
1740                 } elsif ($cur =~/^(case)/o) {
1741                         print "CASE($1)\n" if ($dbg_values > 1);
1742                         $av_pend_colon = 'C';
1743                         $type = 'N';
1744
1745                 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1746                         print "KEYWORD($1)\n" if ($dbg_values > 1);
1747                         $type = 'N';
1748
1749                 } elsif ($cur =~ /^(\()/o) {
1750                         print "PAREN('$1')\n" if ($dbg_values > 1);
1751                         push(@av_paren_type, $av_pending);
1752                         $av_pending = '_';
1753                         $type = 'N';
1754
1755                 } elsif ($cur =~ /^(\))/o) {
1756                         my $new_type = pop(@av_paren_type);
1757                         if ($new_type ne '_') {
1758                                 $type = $new_type;
1759                                 print "PAREN('$1') -> $type\n"
1760                                                         if ($dbg_values > 1);
1761                         } else {
1762                                 print "PAREN('$1')\n" if ($dbg_values > 1);
1763                         }
1764
1765                 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1766                         print "FUNC($1)\n" if ($dbg_values > 1);
1767                         $type = 'V';
1768                         $av_pending = 'V';
1769
1770                 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1771                         if (defined $2 && $type eq 'C' || $type eq 'T') {
1772                                 $av_pend_colon = 'B';
1773                         } elsif ($type eq 'E') {
1774                                 $av_pend_colon = 'L';
1775                         }
1776                         print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1777                         $type = 'V';
1778
1779                 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1780                         print "IDENT($1)\n" if ($dbg_values > 1);
1781                         $type = 'V';
1782
1783                 } elsif ($cur =~ /^($Assignment)/o) {
1784                         print "ASSIGN($1)\n" if ($dbg_values > 1);
1785                         $type = 'N';
1786
1787                 } elsif ($cur =~/^(;|{|})/) {
1788                         print "END($1)\n" if ($dbg_values > 1);
1789                         $type = 'E';
1790                         $av_pend_colon = 'O';
1791
1792                 } elsif ($cur =~/^(,)/) {
1793                         print "COMMA($1)\n" if ($dbg_values > 1);
1794                         $type = 'C';
1795
1796                 } elsif ($cur =~ /^(\?)/o) {
1797                         print "QUESTION($1)\n" if ($dbg_values > 1);
1798                         $type = 'N';
1799
1800                 } elsif ($cur =~ /^(:)/o) {
1801                         print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1802
1803                         substr($var, length($res), 1, $av_pend_colon);
1804                         if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1805                                 $type = 'E';
1806                         } else {
1807                                 $type = 'N';
1808                         }
1809                         $av_pend_colon = 'O';
1810
1811                 } elsif ($cur =~ /^(\[)/o) {
1812                         print "CLOSE($1)\n" if ($dbg_values > 1);
1813                         $type = 'N';
1814
1815                 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1816                         my $variant;
1817
1818                         print "OPV($1)\n" if ($dbg_values > 1);
1819                         if ($type eq 'V') {
1820                                 $variant = 'B';
1821                         } else {
1822                                 $variant = 'U';
1823                         }
1824
1825                         substr($var, length($res), 1, $variant);
1826                         $type = 'N';
1827
1828                 } elsif ($cur =~ /^($Operators)/o) {
1829                         print "OP($1)\n" if ($dbg_values > 1);
1830                         if ($1 ne '++' && $1 ne '--') {
1831                                 $type = 'N';
1832                         }
1833
1834                 } elsif ($cur =~ /(^.)/o) {
1835                         print "C($1)\n" if ($dbg_values > 1);
1836                 }
1837                 if (defined $1) {
1838                         $cur = substr($cur, length($1));
1839                         $res .= $type x length($1);
1840                 }
1841         }
1842
1843         return ($res, $var);
1844 }
1845
1846 sub possible {
1847         my ($possible, $line) = @_;
1848         my $notPermitted = qr{(?:
1849                 ^(?:
1850                         $Modifier|
1851                         $Storage|
1852                         $Type|
1853                         DEFINE_\S+
1854                 )$|
1855                 ^(?:
1856                         goto|
1857                         return|
1858                         case|
1859                         else|
1860                         asm|__asm__|
1861                         do|
1862                         \#|
1863                         \#\#|
1864                 )(?:\s|$)|
1865                 ^(?:typedef|struct|enum)\b
1866             )}x;
1867         warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1868         if ($possible !~ $notPermitted) {
1869                 # Check for modifiers.
1870                 $possible =~ s/\s*$Storage\s*//g;
1871                 $possible =~ s/\s*$Sparse\s*//g;
1872                 if ($possible =~ /^\s*$/) {
1873
1874                 } elsif ($possible =~ /\s/) {
1875                         $possible =~ s/\s*$Type\s*//g;
1876                         for my $modifier (split(' ', $possible)) {
1877                                 if ($modifier !~ $notPermitted) {
1878                                         warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1879                                         push(@modifierListFile, $modifier);
1880                                 }
1881                         }
1882
1883                 } else {
1884                         warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1885                         push(@typeListFile, $possible);
1886                 }
1887                 build_types();
1888         } else {
1889                 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1890         }
1891 }
1892
1893 my $prefix = '';
1894
1895 sub show_type {
1896         my ($type) = @_;
1897
1898         $type =~ tr/[a-z]/[A-Z]/;
1899
1900         return defined $use_type{$type} if (scalar keys %use_type > 0);
1901
1902         return !defined $ignore_type{$type};
1903 }
1904
1905 sub report {
1906         my ($level, $type, $msg) = @_;
1907
1908         if (!show_type($type) ||
1909             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1910                 return 0;
1911         }
1912         my $output = '';
1913         if ($color) {
1914                 if ($level eq 'ERROR') {
1915                         $output .= RED;
1916                 } elsif ($level eq 'WARNING') {
1917                         $output .= YELLOW;
1918                 } else {
1919                         $output .= GREEN;
1920                 }
1921         }
1922         $output .= $prefix . $level . ':';
1923         if ($show_types) {
1924                 $output .= BLUE if ($color);
1925                 $output .= "$type:";
1926         }
1927         $output .= RESET if ($color);
1928         $output .= ' ' . $msg . "\n";
1929
1930         if ($showfile) {
1931                 my @lines = split("\n", $output, -1);
1932                 splice(@lines, 1, 1);
1933                 $output = join("\n", @lines);
1934         }
1935         $output = (split('\n', $output))[0] . "\n" if ($terse);
1936
1937         push(our @report, $output);
1938
1939         return 1;
1940 }
1941
1942 sub report_dump {
1943         our @report;
1944 }
1945
1946 sub fixup_current_range {
1947         my ($lineRef, $offset, $length) = @_;
1948
1949         if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1950                 my $o = $1;
1951                 my $l = $2;
1952                 my $no = $o + $offset;
1953                 my $nl = $l + $length;
1954                 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1955         }
1956 }
1957
1958 sub fix_inserted_deleted_lines {
1959         my ($linesRef, $insertedRef, $deletedRef) = @_;
1960
1961         my $range_last_linenr = 0;
1962         my $delta_offset = 0;
1963
1964         my $old_linenr = 0;
1965         my $new_linenr = 0;
1966
1967         my $next_insert = 0;
1968         my $next_delete = 0;
1969
1970         my @lines = ();
1971
1972         my $inserted = @{$insertedRef}[$next_insert++];
1973         my $deleted = @{$deletedRef}[$next_delete++];
1974
1975         foreach my $old_line (@{$linesRef}) {
1976                 my $save_line = 1;
1977                 my $line = $old_line;   #don't modify the array
1978                 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {      #new filename
1979                         $delta_offset = 0;
1980                 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {    #new hunk
1981                         $range_last_linenr = $new_linenr;
1982                         fixup_current_range(\$line, $delta_offset, 0);
1983                 }
1984
1985                 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1986                         $deleted = @{$deletedRef}[$next_delete++];
1987                         $save_line = 0;
1988                         fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1989                 }
1990
1991                 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1992                         push(@lines, ${$inserted}{'LINE'});
1993                         $inserted = @{$insertedRef}[$next_insert++];
1994                         $new_linenr++;
1995                         fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1996                 }
1997
1998                 if ($save_line) {
1999                         push(@lines, $line);
2000                         $new_linenr++;
2001                 }
2002
2003                 $old_linenr++;
2004         }
2005
2006         return @lines;
2007 }
2008
2009 sub fix_insert_line {
2010         my ($linenr, $line) = @_;
2011
2012         my $inserted = {
2013                 LINENR => $linenr,
2014                 LINE => $line,
2015         };
2016         push(@fixed_inserted, $inserted);
2017 }
2018
2019 sub fix_delete_line {
2020         my ($linenr, $line) = @_;
2021
2022         my $deleted = {
2023                 LINENR => $linenr,
2024                 LINE => $line,
2025         };
2026
2027         push(@fixed_deleted, $deleted);
2028 }
2029
2030 sub ERROR {
2031         my ($type, $msg) = @_;
2032
2033         if (report("ERROR", $type, $msg)) {
2034                 our $clean = 0;
2035                 our $cnt_error++;
2036                 return 1;
2037         }
2038         return 0;
2039 }
2040 sub WARN {
2041         my ($type, $msg) = @_;
2042
2043         if (report("WARNING", $type, $msg)) {
2044                 our $clean = 0;
2045                 our $cnt_warn++;
2046                 return 1;
2047         }
2048         return 0;
2049 }
2050 sub CHK {
2051         my ($type, $msg) = @_;
2052
2053         if ($check && report("CHECK", $type, $msg)) {
2054                 our $clean = 0;
2055                 our $cnt_chk++;
2056                 return 1;
2057         }
2058         return 0;
2059 }
2060
2061 sub check_absolute_file {
2062         my ($absolute, $herecurr) = @_;
2063         my $file = $absolute;
2064
2065         ##print "absolute<$absolute>\n";
2066
2067         # See if any suffix of this path is a path within the tree.
2068         while ($file =~ s@^[^/]*/@@) {
2069                 if (-f "$root/$file") {
2070                         ##print "file<$file>\n";
2071                         last;
2072                 }
2073         }
2074         if (! -f _)  {
2075                 return 0;
2076         }
2077
2078         # It is, so see if the prefix is acceptable.
2079         my $prefix = $absolute;
2080         substr($prefix, -length($file)) = '';
2081
2082         ##print "prefix<$prefix>\n";
2083         if ($prefix ne ".../") {
2084                 WARN("USE_RELATIVE_PATH",
2085                      "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2086         }
2087 }
2088
2089 sub trim {
2090         my ($string) = @_;
2091
2092         $string =~ s/^\s+|\s+$//g;
2093
2094         return $string;
2095 }
2096
2097 sub ltrim {
2098         my ($string) = @_;
2099
2100         $string =~ s/^\s+//;
2101
2102         return $string;
2103 }
2104
2105 sub rtrim {
2106         my ($string) = @_;
2107
2108         $string =~ s/\s+$//;
2109
2110         return $string;
2111 }
2112
2113 sub string_find_replace {
2114         my ($string, $find, $replace) = @_;
2115
2116         $string =~ s/$find/$replace/g;
2117
2118         return $string;
2119 }
2120
2121 sub tabify {
2122         my ($leading) = @_;
2123
2124         my $source_indent = 8;
2125         my $max_spaces_before_tab = $source_indent - 1;
2126         my $spaces_to_tab = " " x $source_indent;
2127
2128         #convert leading spaces to tabs
2129         1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2130         #Remove spaces before a tab
2131         1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2132
2133         return "$leading";
2134 }
2135
2136 sub pos_last_openparen {
2137         my ($line) = @_;
2138
2139         my $pos = 0;
2140
2141         my $opens = $line =~ tr/\(/\(/;
2142         my $closes = $line =~ tr/\)/\)/;
2143
2144         my $last_openparen = 0;
2145
2146         if (($opens == 0) || ($closes >= $opens)) {
2147                 return -1;
2148         }
2149
2150         my $len = length($line);
2151
2152         for ($pos = 0; $pos < $len; $pos++) {
2153                 my $string = substr($line, $pos);
2154                 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2155                         $pos += length($1) - 1;
2156                 } elsif (substr($line, $pos, 1) eq '(') {
2157                         $last_openparen = $pos;
2158                 } elsif (index($string, '(') == -1) {
2159                         last;
2160                 }
2161         }
2162
2163         return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2164 }
2165
2166 sub process {
2167         my $filename = shift;
2168
2169         my $linenr=0;
2170         my $prevline="";
2171         my $prevrawline="";
2172         my $stashline="";
2173         my $stashrawline="";
2174
2175         my $length;
2176         my $indent;
2177         my $previndent=0;
2178         my $stashindent=0;
2179
2180         our $clean = 1;
2181         my $signoff = 0;
2182         my $is_patch = 0;
2183         my $in_header_lines = $file ? 0 : 1;
2184         my $in_commit_log = 0;          #Scanning lines before patch
2185         my $has_commit_log = 0;         #Encountered lines before patch
2186         my $commit_log_possible_stack_dump = 0;
2187         my $commit_log_long_line = 0;
2188         my $commit_log_has_diff = 0;
2189         my $reported_maintainer_file = 0;
2190         my $non_utf8_charset = 0;
2191
2192         my $last_blank_line = 0;
2193         my $last_coalesced_string_linenr = -1;
2194
2195         our @report = ();
2196         our $cnt_lines = 0;
2197         our $cnt_error = 0;
2198         our $cnt_warn = 0;
2199         our $cnt_chk = 0;
2200
2201         # Trace the real file/line as we go.
2202         my $realfile = '';
2203         my $realline = 0;
2204         my $realcnt = 0;
2205         my $here = '';
2206         my $context_function;           #undef'd unless there's a known function
2207         my $in_comment = 0;
2208         my $comment_edge = 0;
2209         my $first_line = 0;
2210         my $p1_prefix = '';
2211
2212         my $prev_values = 'E';
2213
2214         # suppression flags
2215         my %suppress_ifbraces;
2216         my %suppress_whiletrailers;
2217         my %suppress_export;
2218         my $suppress_statement = 0;
2219
2220         my %signatures = ();
2221
2222         # Pre-scan the patch sanitizing the lines.
2223         # Pre-scan the patch looking for any __setup documentation.
2224         #
2225         my @setup_docs = ();
2226         my $setup_docs = 0;
2227
2228         my $camelcase_file_seeded = 0;
2229
2230         sanitise_line_reset();
2231         my $line;
2232         foreach my $rawline (@rawlines) {
2233                 $linenr++;
2234                 $line = $rawline;
2235
2236                 push(@fixed, $rawline) if ($fix);
2237
2238                 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2239                         $setup_docs = 0;
2240                         if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2241                                 $setup_docs = 1;
2242                         }
2243                         #next;
2244                 }
2245                 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2246                         $realline=$1-1;
2247                         if (defined $2) {
2248                                 $realcnt=$3+1;
2249                         } else {
2250                                 $realcnt=1+1;
2251                         }
2252                         $in_comment = 0;
2253
2254                         # Guestimate if this is a continuing comment.  Run
2255                         # the context looking for a comment "edge".  If this
2256                         # edge is a close comment then we must be in a comment
2257                         # at context start.
2258                         my $edge;
2259                         my $cnt = $realcnt;
2260                         for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2261                                 next if (defined $rawlines[$ln - 1] &&
2262                                          $rawlines[$ln - 1] =~ /^-/);
2263                                 $cnt--;
2264                                 #print "RAW<$rawlines[$ln - 1]>\n";
2265                                 last if (!defined $rawlines[$ln - 1]);
2266                                 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2267                                     $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2268                                         ($edge) = $1;
2269                                         last;
2270                                 }
2271                         }
2272                         if (defined $edge && $edge eq '*/') {
2273                                 $in_comment = 1;
2274                         }
2275
2276                         # Guestimate if this is a continuing comment.  If this
2277                         # is the start of a diff block and this line starts
2278                         # ' *' then it is very likely a comment.
2279                         if (!defined $edge &&
2280                             $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2281                         {
2282                                 $in_comment = 1;
2283                         }
2284
2285                         ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2286                         sanitise_line_reset($in_comment);
2287
2288                 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2289                         # Standardise the strings and chars within the input to
2290                         # simplify matching -- only bother with positive lines.
2291                         $line = sanitise_line($rawline);
2292                 }
2293                 push(@lines, $line);
2294
2295                 if ($realcnt > 1) {
2296                         $realcnt-- if ($line =~ /^(?:\+| |$)/);
2297                 } else {
2298                         $realcnt = 0;
2299                 }
2300
2301                 #print "==>$rawline\n";
2302                 #print "-->$line\n";
2303
2304                 if ($setup_docs && $line =~ /^\+/) {
2305                         push(@setup_docs, $line);
2306                 }
2307         }
2308
2309         $prefix = '';
2310
2311         $realcnt = 0;
2312         $linenr = 0;
2313         $fixlinenr = -1;
2314         foreach my $line (@lines) {
2315                 $linenr++;
2316                 $fixlinenr++;
2317                 my $sline = $line;      #copy of $line
2318                 $sline =~ s/$;/ /g;     #with comments as spaces
2319
2320                 my $rawline = $rawlines[$linenr - 1];
2321
2322 #extract the line range in the file after the patch is applied
2323                 if (!$in_commit_log &&
2324                     $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2325                         my $context = $4;
2326                         $is_patch = 1;
2327                         $first_line = $linenr + 1;
2328                         $realline=$1-1;
2329                         if (defined $2) {
2330                                 $realcnt=$3+1;
2331                         } else {
2332                                 $realcnt=1+1;
2333                         }
2334                         annotate_reset();
2335                         $prev_values = 'E';
2336
2337                         %suppress_ifbraces = ();
2338                         %suppress_whiletrailers = ();
2339                         %suppress_export = ();
2340                         $suppress_statement = 0;
2341                         if ($context =~ /\b(\w+)\s*\(/) {
2342                                 $context_function = $1;
2343                         } else {
2344                                 undef $context_function;
2345                         }
2346                         next;
2347
2348 # track the line number as we move through the hunk, note that
2349 # new versions of GNU diff omit the leading space on completely
2350 # blank context lines so we need to count that too.
2351                 } elsif ($line =~ /^( |\+|$)/) {
2352                         $realline++;
2353                         $realcnt-- if ($realcnt != 0);
2354
2355                         # Measure the line length and indent.
2356                         ($length, $indent) = line_stats($rawline);
2357
2358                         # Track the previous line.
2359                         ($prevline, $stashline) = ($stashline, $line);
2360                         ($previndent, $stashindent) = ($stashindent, $indent);
2361                         ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2362
2363                         #warn "line<$line>\n";
2364
2365                 } elsif ($realcnt == 1) {
2366                         $realcnt--;
2367                 }
2368
2369                 my $hunk_line = ($realcnt != 0);
2370
2371                 $here = "#$linenr: " if (!$file);
2372                 $here = "#$realline: " if ($file);
2373
2374                 my $found_file = 0;
2375                 # extract the filename as it passes
2376                 if ($line =~ /^diff --git.*?(\S+)$/) {
2377                         $realfile = $1;
2378                         $realfile =~ s@^([^/]*)/@@ if (!$file);
2379                         $in_commit_log = 0;
2380                         $found_file = 1;
2381                 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2382                         $realfile = $1;
2383                         $realfile =~ s@^([^/]*)/@@ if (!$file);
2384                         $in_commit_log = 0;
2385
2386                         $p1_prefix = $1;
2387                         if (!$file && $tree && $p1_prefix ne '' &&
2388                             -e "$root/$p1_prefix") {
2389                                 WARN("PATCH_PREFIX",
2390                                      "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2391                         }
2392
2393                         if ($realfile =~ m@^include/asm/@) {
2394                                 ERROR("MODIFIED_INCLUDE_ASM",
2395                                       "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2396                         }
2397                         $found_file = 1;
2398                 }
2399
2400 #make up the handle for any error we report on this line
2401                 if ($showfile) {
2402                         $prefix = "$realfile:$realline: "
2403                 } elsif ($emacs) {
2404                         if ($file) {
2405                                 $prefix = "$filename:$realline: ";
2406                         } else {
2407                                 $prefix = "$filename:$linenr: ";
2408                         }
2409                 }
2410
2411                 if ($found_file) {
2412                         if (is_maintained_obsolete($realfile)) {
2413                                 WARN("OBSOLETE",
2414                                      "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
2415                         }
2416                         if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
2417                                 $check = 1;
2418                         } else {
2419                                 $check = $check_orig;
2420                         }
2421                         next;
2422                 }
2423
2424                 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2425
2426                 my $hereline = "$here\n$rawline\n";
2427                 my $herecurr = "$here\n$rawline\n";
2428                 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2429
2430                 $cnt_lines++ if ($realcnt != 0);
2431
2432 # Check if the commit log has what seems like a diff which can confuse patch
2433                 if ($in_commit_log && !$commit_log_has_diff &&
2434                     (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2435                       $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2436                      $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2437                      $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2438                         ERROR("DIFF_IN_COMMIT_MSG",
2439                               "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2440                         $commit_log_has_diff = 1;
2441                 }
2442
2443 # Check for incorrect file permissions
2444                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2445                         my $permhere = $here . "FILE: $realfile\n";
2446                         if ($realfile !~ m@scripts/@ &&
2447                             $realfile !~ /\.(py|pl|awk|sh)$/) {
2448                                 ERROR("EXECUTE_PERMISSIONS",
2449                                       "do not set execute permissions for source files\n" . $permhere);
2450                         }
2451                 }
2452
2453 # Check the patch for a signoff:
2454                 if ($line =~ /^\s*signed-off-by:/i) {
2455                         $signoff++;
2456                         $in_commit_log = 0;
2457                 }
2458
2459 # Check if MAINTAINERS is being updated.  If so, there's probably no need to
2460 # emit the "does MAINTAINERS need updating?" message on file add/move/delete
2461                 if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2462                         $reported_maintainer_file = 1;
2463                 }
2464
2465 # Check signature styles
2466                 if (!$in_header_lines &&
2467                     $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2468                         my $space_before = $1;
2469                         my $sign_off = $2;
2470                         my $space_after = $3;
2471                         my $email = $4;
2472                         my $ucfirst_sign_off = ucfirst(lc($sign_off));
2473
2474                         if ($sign_off !~ /$signature_tags/) {
2475                                 WARN("BAD_SIGN_OFF",
2476                                      "Non-standard signature: $sign_off\n" . $herecurr);
2477                         }
2478                         if (defined $space_before && $space_before ne "") {
2479                                 if (WARN("BAD_SIGN_OFF",
2480                                          "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2481                                     $fix) {
2482                                         $fixed[$fixlinenr] =
2483                                             "$ucfirst_sign_off $email";
2484                                 }
2485                         }
2486                         if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
2487                                 if (WARN("BAD_SIGN_OFF",
2488                                          "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2489                                     $fix) {
2490                                         $fixed[$fixlinenr] =
2491                                             "$ucfirst_sign_off $email";
2492                                 }
2493
2494                         }
2495                         if (!defined $space_after || $space_after ne " ") {
2496                                 if (WARN("BAD_SIGN_OFF",
2497                                          "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2498                                     $fix) {
2499                                         $fixed[$fixlinenr] =
2500                                             "$ucfirst_sign_off $email";
2501                                 }
2502                         }
2503
2504                         my ($email_name, $email_address, $comment) = parse_email($email);
2505                         my $suggested_email = format_email(($email_name, $email_address));
2506                         if ($suggested_email eq "") {
2507                                 ERROR("BAD_SIGN_OFF",
2508                                       "Unrecognized email address: '$email'\n" . $herecurr);
2509                         } else {
2510                                 my $dequoted = $suggested_email;
2511                                 $dequoted =~ s/^"//;
2512                                 $dequoted =~ s/" </ </;
2513                                 # Don't force email to have quotes
2514                                 # Allow just an angle bracketed address
2515                                 if ("$dequoted$comment" ne $email &&
2516                                     "<$email_address>$comment" ne $email &&
2517                                     "$suggested_email$comment" ne $email) {
2518                                         WARN("BAD_SIGN_OFF",
2519                                              "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2520                                 }
2521                         }
2522
2523 # Check for duplicate signatures
2524                         my $sig_nospace = $line;
2525                         $sig_nospace =~ s/\s//g;
2526                         $sig_nospace = lc($sig_nospace);
2527                         if (defined $signatures{$sig_nospace}) {
2528                                 WARN("BAD_SIGN_OFF",
2529                                      "Duplicate signature\n" . $herecurr);
2530                         } else {
2531                                 $signatures{$sig_nospace} = 1;
2532                         }
2533                 }
2534
2535 # Check email subject for common tools that don't need to be mentioned
2536                 if ($in_header_lines &&
2537                     $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2538                         WARN("EMAIL_SUBJECT",
2539                              "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2540                 }
2541
2542 # Check for old stable address
2543                 if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
2544                         ERROR("STABLE_ADDRESS",
2545                               "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
2546                 }
2547
2548 # Check for unwanted Gerrit info
2549                 if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2550                         ERROR("GERRIT_CHANGE_ID",
2551                               "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
2552                 }
2553
2554 # Check if the commit log is in a possible stack dump
2555                 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2556                     ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2557                      $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2558                                         # timestamp
2559                      $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2560                                         # stack dump address
2561                         $commit_log_possible_stack_dump = 1;
2562                 }
2563
2564 # Check for line lengths > 75 in commit log, warn once
2565                 if ($in_commit_log && !$commit_log_long_line &&
2566                     length($line) > 75 &&
2567                     !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2568                                         # file delta changes
2569                       $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2570                                         # filename then :
2571                       $line =~ /^\s*(?:Fixes:|Link:)/i ||
2572                                         # A Fixes: or Link: line
2573                       $commit_log_possible_stack_dump)) {
2574                         WARN("COMMIT_LOG_LONG_LINE",
2575                              "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
2576                         $commit_log_long_line = 1;
2577                 }
2578
2579 # Reset possible stack dump if a blank line is found
2580                 if ($in_commit_log && $commit_log_possible_stack_dump &&
2581                     $line =~ /^\s*$/) {
2582                         $commit_log_possible_stack_dump = 0;
2583                 }
2584
2585 # Check for git id commit length and improperly formed commit descriptions
2586                 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2587                     $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2588                     $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2589                     ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2590                      ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2591                       $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2592                       $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2593                         my $init_char = "c";
2594                         my $orig_commit = "";
2595                         my $short = 1;
2596                         my $long = 0;
2597                         my $case = 1;
2598                         my $space = 1;
2599                         my $hasdesc = 0;
2600                         my $hasparens = 0;
2601                         my $id = '0123456789ab';
2602                         my $orig_desc = "commit description";
2603                         my $description = "";
2604
2605                         if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2606                                 $init_char = $1;
2607                                 $orig_commit = lc($2);
2608                         } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2609                                 $orig_commit = lc($1);
2610                         }
2611
2612                         $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2613                         $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2614                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2615                         $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2616                         if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2617                                 $orig_desc = $1;
2618                                 $hasparens = 1;
2619                         } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2620                                  defined $rawlines[$linenr] &&
2621                                  $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2622                                 $orig_desc = $1;
2623                                 $hasparens = 1;
2624                         } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2625                                  defined $rawlines[$linenr] &&
2626                                  $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2627                                 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2628                                 $orig_desc = $1;
2629                                 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2630                                 $orig_desc .= " " . $1;
2631                                 $hasparens = 1;
2632                         }
2633
2634                         ($id, $description) = git_commit_info($orig_commit,
2635                                                               $id, $orig_desc);
2636
2637                         if (defined($id) &&
2638                            ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2639                                 ERROR("GIT_COMMIT_ID",
2640                                       "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2641                         }
2642                 }
2643
2644 # Check for added, moved or deleted files
2645                 if (!$reported_maintainer_file && !$in_commit_log &&
2646                     ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2647                      $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2648                      ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2649                       (defined($1) || defined($2))))) {
2650                         $is_patch = 1;
2651                         $reported_maintainer_file = 1;
2652                         WARN("FILE_PATH_CHANGES",
2653                              "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
2654                 }
2655
2656 # Check for wrappage within a valid hunk of the file
2657                 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2658                         ERROR("CORRUPTED_PATCH",
2659                               "patch seems to be corrupt (line wrapped?)\n" .
2660                                 $herecurr) if (!$emitted_corrupt++);
2661                 }
2662
2663 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2664                 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2665                     $rawline !~ m/^$UTF8*$/) {
2666                         my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2667
2668                         my $blank = copy_spacing($rawline);
2669                         my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2670                         my $hereptr = "$hereline$ptr\n";
2671
2672                         CHK("INVALID_UTF8",
2673                             "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2674                 }
2675
2676 # Check if it's the start of a commit log
2677 # (not a header line and we haven't seen the patch filename)
2678                 if ($in_header_lines && $realfile =~ /^$/ &&
2679                     !($rawline =~ /^\s+(?:\S|$)/ ||
2680                       $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
2681                         $in_header_lines = 0;
2682                         $in_commit_log = 1;
2683                         $has_commit_log = 1;
2684                 }
2685
2686 # Check if there is UTF-8 in a commit log when a mail header has explicitly
2687 # declined it, i.e defined some charset where it is missing.
2688                 if ($in_header_lines &&
2689                     $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2690                     $1 !~ /utf-8/i) {
2691                         $non_utf8_charset = 1;
2692                 }
2693
2694                 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2695                     $rawline =~ /$NON_ASCII_UTF8/) {
2696                         WARN("UTF8_BEFORE_PATCH",
2697                             "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2698                 }
2699
2700 # Check for absolute kernel paths in commit message
2701                 if ($tree && $in_commit_log) {
2702                         while ($line =~ m{(?:^|\s)(/\S*)}g) {
2703                                 my $file = $1;
2704
2705                                 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2706                                     check_absolute_file($1, $herecurr)) {
2707                                         #
2708                                 } else {
2709                                         check_absolute_file($file, $herecurr);
2710                                 }
2711                         }
2712                 }
2713
2714 # Check for various typo / spelling mistakes
2715                 if (defined($misspellings) &&
2716                     ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2717                         while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
2718                                 my $typo = $1;
2719                                 my $typo_fix = $spelling_fix{lc($typo)};
2720                                 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
2721                                 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
2722                                 my $msg_type = \&WARN;
2723                                 $msg_type = \&CHK if ($file);
2724                                 if (&{$msg_type}("TYPO_SPELLING",
2725                                                  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
2726                                     $fix) {
2727                                         $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
2728                                 }
2729                         }
2730                 }
2731
2732 # ignore non-hunk lines and lines being removed
2733                 next if (!$hunk_line || $line =~ /^-/);
2734
2735 #trailing whitespace
2736                 if ($line =~ /^\+.*\015/) {
2737                         my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2738                         if (ERROR("DOS_LINE_ENDINGS",
2739                                   "DOS line endings\n" . $herevet) &&
2740                             $fix) {
2741                                 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
2742                         }
2743                 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2744                         my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2745                         if (ERROR("TRAILING_WHITESPACE",
2746                                   "trailing whitespace\n" . $herevet) &&
2747                             $fix) {
2748                                 $fixed[$fixlinenr] =~ s/\s+$//;
2749                         }
2750
2751                         $rpt_cleaners = 1;
2752                 }
2753
2754 # Check for FSF mailing addresses.
2755                 if ($rawline =~ /\bwrite to the Free/i ||
2756                     $rawline =~ /\b675\s+Mass\s+Ave/i ||
2757                     $rawline =~ /\b59\s+Temple\s+Pl/i ||
2758                     $rawline =~ /\b51\s+Franklin\s+St/i) {
2759                         my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2760                         my $msg_type = \&ERROR;
2761                         $msg_type = \&CHK if ($file);
2762                         &{$msg_type}("FSF_MAILING_ADDRESS",
2763                                      "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
2764                 }
2765
2766 # check for Kconfig help text having a real description
2767 # Only applies when adding the entry originally, after that we do not have
2768 # sufficient context to determine whether it is indeed long enough.
2769                 if ($realfile =~ /Kconfig/ &&
2770                     $line =~ /^\+\s*config\s+/) {
2771                         my $length = 0;
2772                         my $cnt = $realcnt;
2773                         my $ln = $linenr + 1;
2774                         my $f;
2775                         my $is_start = 0;
2776                         my $is_end = 0;
2777                         for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
2778                                 $f = $lines[$ln - 1];
2779                                 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2780                                 $is_end = $lines[$ln - 1] =~ /^\+/;
2781
2782                                 next if ($f =~ /^-/);
2783                                 last if (!$file && $f =~ /^\@\@/);
2784
2785                                 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2786                                         $is_start = 1;
2787                                 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2788                                         $length = -1;
2789                                 }
2790
2791                                 $f =~ s/^.//;
2792                                 $f =~ s/#.*//;
2793                                 $f =~ s/^\s+//;
2794                                 next if ($f =~ /^$/);
2795                                 if ($f =~ /^\s*config\s/) {
2796                                         $is_end = 1;
2797                                         last;
2798                                 }
2799                                 $length++;
2800                         }
2801                         if ($is_start && $is_end && $length < $min_conf_desc_length) {
2802                                 WARN("CONFIG_DESCRIPTION",
2803                                      "please write a paragraph that describes the config symbol fully\n" . $herecurr);
2804                         }
2805                         #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
2806                 }
2807
2808 # check for MAINTAINERS entries that don't have the right form
2809                 if ($realfile =~ /^MAINTAINERS$/ &&
2810                     $rawline =~ /^\+[A-Z]:/ &&
2811                     $rawline !~ /^\+[A-Z]:\t\S/) {
2812                         if (WARN("MAINTAINERS_STYLE",
2813                                  "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2814                             $fix) {
2815                                 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2816                         }
2817                 }
2818
2819 # discourage the use of boolean for type definition attributes of Kconfig options
2820                 if ($realfile =~ /Kconfig/ &&
2821                     $line =~ /^\+\s*\bboolean\b/) {
2822                         WARN("CONFIG_TYPE_BOOLEAN",
2823                              "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2824                 }
2825
2826                 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2827                     ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2828                         my $flag = $1;
2829                         my $replacement = {
2830                                 'EXTRA_AFLAGS' =>   'asflags-y',
2831                                 'EXTRA_CFLAGS' =>   'ccflags-y',
2832                                 'EXTRA_CPPFLAGS' => 'cppflags-y',
2833                                 'EXTRA_LDFLAGS' =>  'ldflags-y',
2834                         };
2835
2836                         WARN("DEPRECATED_VARIABLE",
2837                              "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2838                 }
2839
2840 # check for DT compatible documentation
2841                 if (defined $root &&
2842                         (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
2843                          ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
2844
2845                         my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2846
2847                         my $dt_path = $root . "/Documentation/devicetree/bindings/";
2848                         my $vp_file = $dt_path . "vendor-prefixes.txt";
2849
2850                         foreach my $compat (@compats) {
2851                                 my $compat2 = $compat;
2852                                 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2853                                 my $compat3 = $compat;
2854                                 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2855                                 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2856                                 if ( $? >> 8 ) {
2857                                         WARN("UNDOCUMENTED_DT_STRING",
2858                                              "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2859                                 }
2860
2861                                 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
2862                                 my $vendor = $1;
2863                                 `grep -Eq "^$vendor\\b" $vp_file`;
2864                                 if ( $? >> 8 ) {
2865                                         WARN("UNDOCUMENTED_DT_STRING",
2866                                              "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2867                                 }
2868                         }
2869                 }
2870
2871 # check we are in a valid source file if not then ignore this hunk
2872                 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
2873
2874 # line length limit (with some exclusions)
2875 #
2876 # There are a few types of lines that may extend beyond $max_line_length:
2877 #       logging functions like pr_info that end in a string
2878 #       lines with a single string
2879 #       #defines that are a single string
2880 #
2881 # There are 3 different line length message types:
2882 # LONG_LINE_COMMENT     a comment starts before but extends beyond $max_linelength
2883 # LONG_LINE_STRING      a string starts before but extends beyond $max_line_length
2884 # LONG_LINE             all other lines longer than $max_line_length
2885 #
2886 # if LONG_LINE is ignored, the other 2 types are also ignored
2887 #
2888
2889                 if ($line =~ /^\+/ && $length > $max_line_length) {
2890                         my $msg_type = "LONG_LINE";
2891
2892                         # Check the allowed long line types first
2893
2894                         # logging functions that end in a string that starts
2895                         # before $max_line_length
2896                         if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
2897                             length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2898                                 $msg_type = "";
2899
2900                         # lines with only strings (w/ possible termination)
2901                         # #defines with only strings
2902                         } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
2903                                  $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
2904                                 $msg_type = "";
2905
2906                         # EFI_GUID is another special case
2907                         } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
2908                                 $msg_type = "";
2909
2910                         # Otherwise set the alternate message types
2911
2912                         # a comment starts before $max_line_length
2913                         } elsif ($line =~ /($;[\s$;]*)$/ &&
2914                                  length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2915                                 $msg_type = "LONG_LINE_COMMENT"
2916
2917                         # a quoted string starts before $max_line_length
2918                         } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
2919                                  length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
2920                                 $msg_type = "LONG_LINE_STRING"
2921                         }
2922
2923                         if ($msg_type ne "" &&
2924                             (show_type("LONG_LINE") || show_type($msg_type))) {
2925                                 WARN($msg_type,
2926                                      "line over $max_line_length characters\n" . $herecurr);
2927                         }
2928                 }
2929
2930 # check for adding lines without a newline.
2931                 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2932                         WARN("MISSING_EOF_NEWLINE",
2933                              "adding a line without newline at end of file\n" . $herecurr);
2934                 }
2935
2936 # Blackfin: use hi/lo macros
2937                 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
2938                         if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
2939                                 my $herevet = "$here\n" . cat_vet($line) . "\n";
2940                                 ERROR("LO_MACRO",
2941                                       "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
2942                         }
2943                         if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
2944                                 my $herevet = "$here\n" . cat_vet($line) . "\n";
2945                                 ERROR("HI_MACRO",
2946                                       "use the HI() macro, not (... >> 16)\n" . $herevet);
2947                         }
2948                 }
2949
2950 # check we are in a valid source file C or perl if not then ignore this hunk
2951                 next if ($realfile !~ /\.(h|c|pl|dtsi|dts|sh)$/);
2952
2953 # at the beginning of a line any tabs must come first and anything
2954 # more than 8 must use tabs.
2955                 if ($rawline =~ /^\+\s* \t\s*\S/ ||
2956                     $rawline =~ /^\+\s*        \s*/) {
2957                         my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2958                         $rpt_cleaners = 1;
2959                         if (ERROR("CODE_INDENT",
2960                                   "code indent should use tabs where possible\n" . $herevet) &&
2961                             $fix) {
2962                                 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
2963                         }
2964                 }
2965
2966 # check for space before tabs.
2967                 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
2968                         my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2969                         if (WARN("SPACE_BEFORE_TAB",
2970                                 "please, no space before tabs\n" . $herevet) &&
2971                             $fix) {
2972                                 while ($fixed[$fixlinenr] =~
2973                                            s/(^\+.*) {8,8}\t/$1\t\t/) {}
2974                                 while ($fixed[$fixlinenr] =~
2975                                            s/(^\+.*) +\t/$1\t/) {}
2976                         }
2977                 }
2978
2979 # check for && or || at the start of a line
2980                 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2981                         CHK("LOGICAL_CONTINUATIONS",
2982                             "Logical continuations should be on the previous line\n" . $hereprev);
2983                 }
2984
2985 # check indentation starts on a tab stop
2986                 if ($^V && $^V ge 5.10.0 &&
2987                     $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
2988                         my $indent = length($1);
2989                         if ($indent % 8) {
2990                                 if (WARN("TABSTOP",
2991                                          "Statements should start on a tabstop\n" . $herecurr) &&
2992                                     $fix) {
2993                                         $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
2994                                 }
2995                         }
2996                 }
2997
2998 # check multi-line statement indentation matches previous line
2999                 if ($^V && $^V ge 5.10.0 &&
3000                     $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3001                         $prevline =~ /^\+(\t*)(.*)$/;
3002                         my $oldindent = $1;
3003                         my $rest = $2;
3004
3005                         my $pos = pos_last_openparen($rest);
3006                         if ($pos >= 0) {
3007                                 $line =~ /^(\+| )([ \t]*)/;
3008                                 my $newindent = $2;
3009
3010                                 my $goodtabindent = $oldindent .
3011                                         "\t" x ($pos / 8) .
3012                                         " "  x ($pos % 8);
3013                                 my $goodspaceindent = $oldindent . " "  x $pos;
3014
3015                                 if ($newindent ne $goodtabindent &&
3016                                     $newindent ne $goodspaceindent) {
3017
3018                                         if (CHK("PARENTHESIS_ALIGNMENT",
3019                                                 "Alignment should match open parenthesis\n" . $hereprev) &&
3020                                             $fix && $line =~ /^\+/) {
3021                                                 $fixed[$fixlinenr] =~
3022                                                     s/^\+[ \t]*/\+$goodtabindent/;
3023                                         }
3024                                 }
3025                         }
3026                 }
3027
3028 # check for space after cast like "(int) foo" or "(struct foo) bar"
3029 # avoid checking a few false positives:
3030 #   "sizeof(<type>)" or "__alignof__(<type>)"
3031 #   function pointer declarations like "(*foo)(int) = bar;"
3032 #   structure definitions like "(struct foo) { 0 };"
3033 #   multiline macros that define functions
3034 #   known attributes or the __attribute__ keyword
3035                 if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
3036                     (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
3037                         if (CHK("SPACING",
3038                                 "No space is necessary after a cast\n" . $herecurr) &&
3039                             $fix) {
3040                                 $fixed[$fixlinenr] =~
3041                                     s/(\(\s*$Type\s*\))[ \t]+/$1/;
3042                         }
3043                 }
3044
3045 # Block comment styles
3046 # Networking with an initial /*
3047                 if ($realfile =~ m@^(drivers/net/|net/)@ &&
3048                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
3049                     $rawline =~ /^\+[ \t]*\*/ &&
3050                     $realline > 2) {
3051                         WARN("NETWORKING_BLOCK_COMMENT_STYLE",
3052                              "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
3053                 }
3054
3055 # Block comments use * on subsequent lines
3056                 if ($prevline =~ /$;[ \t]*$/ &&                 #ends in comment
3057