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