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