blob: 74db2e24fc5e928006c4e7ee7f11c0e75dfd5e9c [file] [log] [blame]
Joe Hershberger05622192011-10-18 10:06:59 +00001#!/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
8use strict;
Tom Rini6b9709d2014-02-27 08:27:28 -05009use POSIX;
Joe Hershberger05622192011-10-18 10:06:59 +000010
11my $P = $0;
12$P =~ s@.*/@@g;
13
14my $V = '0.32';
15
16use Getopt::Long qw(:config no_auto_abbrev);
17
18my $quiet = 0;
19my $tree = 1;
20my $chk_signoff = 1;
21my $chk_patch = 1;
22my $tst_only;
23my $emacs = 0;
24my $terse = 0;
25my $file = 0;
26my $check = 0;
27my $summary = 1;
28my $mailback = 0;
29my $summary_file = 0;
30my $show_types = 0;
Tom Rini6b9709d2014-02-27 08:27:28 -050031my $fix = 0;
32my $fix_inplace = 0;
Joe Hershberger05622192011-10-18 10:06:59 +000033my $root;
34my %debug;
Tom Rini6b9709d2014-02-27 08:27:28 -050035my %camelcase = ();
36my %use_type = ();
37my @use = ();
Joe Hershberger05622192011-10-18 10:06:59 +000038my %ignore_type = ();
39my @ignore = ();
40my $help = 0;
41my $configuration_file = ".checkpatch.conf";
Kim Phillipsd45a6ae2013-02-28 12:53:52 +000042my $max_line_length = 80;
Tom Rini6b9709d2014-02-27 08:27:28 -050043my $ignore_perl_version = 0;
44my $minimum_perl_version = 5.10.0;
Joe Hershberger05622192011-10-18 10:06:59 +000045
46sub help {
47 my ($exitcode) = @_;
48
49 print << "EOM";
50Usage: $P [OPTION]... [FILE]...
51Version: $V
52
53Options:
54 -q, --quiet quiet
55 --no-tree run without a kernel tree
56 --no-signoff do not check for 'Signed-off-by' line
57 --patch treat FILE as patchfile (default)
58 --emacs emacs compile window format
59 --terse one line per report
60 -f, --file treat FILE as regular source file
61 --subjective, --strict enable more subjective tests
Tom Rini6b9709d2014-02-27 08:27:28 -050062 --types TYPE(,TYPE2...) show only these comma separated message types
Joe Hershberger05622192011-10-18 10:06:59 +000063 --ignore TYPE(,TYPE2...) ignore various comma separated message types
Kim Phillipsd45a6ae2013-02-28 12:53:52 +000064 --max-line-length=n set the maximum line length, if exceeded, warn
Joe Hershberger05622192011-10-18 10:06:59 +000065 --show-types show the message "types" in the output
66 --root=PATH PATH to the kernel tree root
67 --no-summary suppress the per-file summary
68 --mailback only produce a report in case of warnings/errors
69 --summary-file include the filename in summary
70 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
71 'values', 'possible', 'type', and 'attr' (default
72 is all off)
73 --test-only=WORD report only warnings/errors containing WORD
74 literally
Tom Rini6b9709d2014-02-27 08:27:28 -050075 --fix EXPERIMENTAL - may create horrible results
76 If correctable single-line errors exist, create
77 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
78 with potential errors corrected to the preferred
79 checkpatch style
80 --fix-inplace EXPERIMENTAL - may create horrible results
81 Is the same as --fix, but overwrites the input
82 file. It's your fault if there's no backup or git
83 --ignore-perl-version override checking of perl version. expect
84 runtime errors.
Joe Hershberger05622192011-10-18 10:06:59 +000085 -h, --help, --version display this help and exit
86
87When FILE is - read standard input.
88EOM
89
90 exit($exitcode);
91}
92
93my $conf = which_conf($configuration_file);
94if (-f $conf) {
95 my @conf_args;
96 open(my $conffile, '<', "$conf")
97 or warn "$P: Can't find a readable $configuration_file file $!\n";
98
99 while (<$conffile>) {
100 my $line = $_;
101
102 $line =~ s/\s*\n?$//g;
103 $line =~ s/^\s*//g;
104 $line =~ s/\s+/ /g;
105
106 next if ($line =~ m/^\s*#/);
107 next if ($line =~ m/^\s*$/);
108
109 my @words = split(" ", $line);
110 foreach my $word (@words) {
111 last if ($word =~ m/^#/);
112 push (@conf_args, $word);
113 }
114 }
115 close($conffile);
116 unshift(@ARGV, @conf_args) if @conf_args;
117}
118
119GetOptions(
120 'q|quiet+' => \$quiet,
121 'tree!' => \$tree,
122 'signoff!' => \$chk_signoff,
123 'patch!' => \$chk_patch,
124 'emacs!' => \$emacs,
125 'terse!' => \$terse,
126 'f|file!' => \$file,
127 'subjective!' => \$check,
128 'strict!' => \$check,
129 'ignore=s' => \@ignore,
Tom Rini6b9709d2014-02-27 08:27:28 -0500130 'types=s' => \@use,
Joe Hershberger05622192011-10-18 10:06:59 +0000131 'show-types!' => \$show_types,
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000132 'max-line-length=i' => \$max_line_length,
Joe Hershberger05622192011-10-18 10:06:59 +0000133 'root=s' => \$root,
134 'summary!' => \$summary,
135 'mailback!' => \$mailback,
136 'summary-file!' => \$summary_file,
Tom Rini6b9709d2014-02-27 08:27:28 -0500137 'fix!' => \$fix,
138 'fix-inplace!' => \$fix_inplace,
139 'ignore-perl-version!' => \$ignore_perl_version,
Joe Hershberger05622192011-10-18 10:06:59 +0000140 'debug=s' => \%debug,
141 'test-only=s' => \$tst_only,
142 'h|help' => \$help,
143 'version' => \$help
144) or help(1);
145
146help(0) if ($help);
147
Tom Rini6b9709d2014-02-27 08:27:28 -0500148$fix = 1 if ($fix_inplace);
149
Joe Hershberger05622192011-10-18 10:06:59 +0000150my $exit = 0;
151
Tom Rini6b9709d2014-02-27 08:27:28 -0500152if ($^V && $^V lt $minimum_perl_version) {
153 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
154 if (!$ignore_perl_version) {
155 exit(1);
156 }
157}
158
Joe Hershberger05622192011-10-18 10:06:59 +0000159if ($#ARGV < 0) {
160 print "$P: no input files\n";
161 exit(1);
162}
163
Tom Rini6b9709d2014-02-27 08:27:28 -0500164sub hash_save_array_words {
165 my ($hashRef, $arrayRef) = @_;
Joe Hershberger05622192011-10-18 10:06:59 +0000166
Tom Rini6b9709d2014-02-27 08:27:28 -0500167 my @array = split(/,/, join(',', @$arrayRef));
168 foreach my $word (@array) {
169 $word =~ s/\s*\n?$//g;
170 $word =~ s/^\s*//g;
171 $word =~ s/\s+/ /g;
172 $word =~ tr/[a-z]/[A-Z]/;
Joe Hershberger05622192011-10-18 10:06:59 +0000173
Tom Rini6b9709d2014-02-27 08:27:28 -0500174 next if ($word =~ m/^\s*#/);
175 next if ($word =~ m/^\s*$/);
176
177 $hashRef->{$word}++;
178 }
Joe Hershberger05622192011-10-18 10:06:59 +0000179}
180
Tom Rini6b9709d2014-02-27 08:27:28 -0500181sub hash_show_words {
182 my ($hashRef, $prefix) = @_;
183
184 if ($quiet == 0 && keys %$hashRef) {
185 print "NOTE: $prefix message types:";
186 foreach my $word (sort keys %$hashRef) {
187 print " $word";
188 }
189 print "\n\n";
190 }
191}
192
193hash_save_array_words(\%ignore_type, \@ignore);
194hash_save_array_words(\%use_type, \@use);
195
Joe Hershberger05622192011-10-18 10:06:59 +0000196my $dbg_values = 0;
197my $dbg_possible = 0;
198my $dbg_type = 0;
199my $dbg_attr = 0;
200for my $key (keys %debug) {
201 ## no critic
202 eval "\${dbg_$key} = '$debug{$key}';";
203 die "$@" if ($@);
204}
205
206my $rpt_cleaners = 0;
207
208if ($terse) {
209 $emacs = 1;
210 $quiet++;
211}
212
213if ($tree) {
214 if (defined $root) {
215 if (!top_of_kernel_tree($root)) {
216 die "$P: $root: --root does not point at a valid tree\n";
217 }
218 } else {
219 if (top_of_kernel_tree('.')) {
220 $root = '.';
221 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
222 top_of_kernel_tree($1)) {
223 $root = $1;
224 }
225 }
226
227 if (!defined $root) {
228 print "Must be run from the top-level dir. of a kernel tree\n";
229 exit(2);
230 }
231}
232
233my $emitted_corrupt = 0;
234
235our $Ident = qr{
236 [A-Za-z_][A-Za-z\d_]*
237 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
238 }x;
239our $Storage = qr{extern|static|asmlinkage};
240our $Sparse = qr{
241 __user|
242 __kernel|
243 __force|
244 __iomem|
245 __must_check|
246 __init_refok|
247 __kprobes|
248 __ref|
249 __rcu
250 }x;
Tom Rini6b9709d2014-02-27 08:27:28 -0500251our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
252our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
253our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
254our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
255our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
Joe Hershberger05622192011-10-18 10:06:59 +0000256
257# Notes to $Attribute:
258# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
259our $Attribute = qr{
260 const|
261 __percpu|
262 __nocast|
263 __safe|
264 __bitwise__|
265 __packed__|
266 __packed2__|
267 __naked|
268 __maybe_unused|
269 __always_unused|
270 __noreturn|
271 __used|
272 __cold|
273 __noclone|
274 __deprecated|
275 __read_mostly|
276 __kprobes|
Tom Rini6b9709d2014-02-27 08:27:28 -0500277 $InitAttribute|
Joe Hershberger05622192011-10-18 10:06:59 +0000278 ____cacheline_aligned|
279 ____cacheline_aligned_in_smp|
280 ____cacheline_internodealigned_in_smp|
281 __weak
282 }x;
283our $Modifier;
284our $Inline = qr{inline|__always_inline|noinline};
285our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
286our $Lval = qr{$Ident(?:$Member)*};
287
Tom Rini6b9709d2014-02-27 08:27:28 -0500288our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
289our $Binary = qr{(?i)0b[01]+$Int_type?};
290our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
291our $Int = qr{[0-9]+$Int_type?};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000292our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
293our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
294our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
295our $Float = qr{$Float_hex|$Float_dec|$Float_int};
Tom Rini6b9709d2014-02-27 08:27:28 -0500296our $Constant = qr{$Float|$Binary|$Hex|$Int};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000297our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
Joe Hershberger05622192011-10-18 10:06:59 +0000298our $Compare = qr{<=|>=|==|!=|<|>};
Tom Rini6b9709d2014-02-27 08:27:28 -0500299our $Arithmetic = qr{\+|-|\*|\/|%};
Joe Hershberger05622192011-10-18 10:06:59 +0000300our $Operators = qr{
301 <=|>=|==|!=|
302 =>|->|<<|>>|<|>|!|~|
Tom Rini6b9709d2014-02-27 08:27:28 -0500303 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
Joe Hershberger05622192011-10-18 10:06:59 +0000304 }x;
305
306our $NonptrType;
Tom Rini6b9709d2014-02-27 08:27:28 -0500307our $NonptrTypeWithAttr;
Joe Hershberger05622192011-10-18 10:06:59 +0000308our $Type;
309our $Declare;
310
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000311our $NON_ASCII_UTF8 = qr{
312 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
Joe Hershberger05622192011-10-18 10:06:59 +0000313 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
314 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
315 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
316 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
317 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
318 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
319}x;
320
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000321our $UTF8 = qr{
322 [\x09\x0A\x0D\x20-\x7E] # ASCII
323 | $NON_ASCII_UTF8
324}x;
325
Joe Hershberger05622192011-10-18 10:06:59 +0000326our $typeTypedefs = qr{(?x:
327 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
328 atomic_t
329)};
330
331our $logFunctions = qr{(?x:
332 printk(?:_ratelimited|_once|)|
Tom Rini6b9709d2014-02-27 08:27:28 -0500333 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
Joe Hershberger05622192011-10-18 10:06:59 +0000334 WARN(?:_RATELIMIT|_ONCE|)|
335 panic|
Tom Rini0cab4212013-03-14 05:36:13 +0000336 debug|
Tom Rini397bfd42013-06-06 09:28:19 -0400337 printf|
Tom Rini6b9709d2014-02-27 08:27:28 -0500338 puts|
339 MODULE_[A-Z_]+|
340 seq_vprintf|seq_printf|seq_puts
Joe Hershberger05622192011-10-18 10:06:59 +0000341)};
342
343our $signature_tags = qr{(?xi:
344 Signed-off-by:|
345 Acked-by:|
346 Tested-by:|
347 Reviewed-by:|
348 Reported-by:|
Tom Rini6b9709d2014-02-27 08:27:28 -0500349 Suggested-by:|
Joe Hershberger05622192011-10-18 10:06:59 +0000350 To:|
351 Cc:
352)};
353
354our @typeList = (
355 qr{void},
356 qr{(?:unsigned\s+)?char},
357 qr{(?:unsigned\s+)?short},
358 qr{(?:unsigned\s+)?int},
359 qr{(?:unsigned\s+)?long},
360 qr{(?:unsigned\s+)?long\s+int},
361 qr{(?:unsigned\s+)?long\s+long},
362 qr{(?:unsigned\s+)?long\s+long\s+int},
363 qr{unsigned},
364 qr{float},
365 qr{double},
366 qr{bool},
367 qr{struct\s+$Ident},
368 qr{union\s+$Ident},
369 qr{enum\s+$Ident},
370 qr{${Ident}_t},
371 qr{${Ident}_handler},
372 qr{${Ident}_handler_fn},
373);
Tom Rini6b9709d2014-02-27 08:27:28 -0500374our @typeListWithAttr = (
375 @typeList,
376 qr{struct\s+$InitAttribute\s+$Ident},
377 qr{union\s+$InitAttribute\s+$Ident},
378);
379
Joe Hershberger05622192011-10-18 10:06:59 +0000380our @modifierList = (
381 qr{fastcall},
382);
383
384our $allowed_asm_includes = qr{(?x:
385 irq|
386 memory
387)};
388# memory.h: ARM has a custom one
389
390sub build_types {
391 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
392 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
Tom Rini6b9709d2014-02-27 08:27:28 -0500393 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
Joe Hershberger05622192011-10-18 10:06:59 +0000394 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
395 $NonptrType = qr{
396 (?:$Modifier\s+|const\s+)*
397 (?:
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000398 (?:typeof|__typeof__)\s*\([^\)]*\)|
Joe Hershberger05622192011-10-18 10:06:59 +0000399 (?:$typeTypedefs\b)|
400 (?:${all}\b)
401 )
402 (?:\s+$Modifier|\s+const)*
403 }x;
Tom Rini6b9709d2014-02-27 08:27:28 -0500404 $NonptrTypeWithAttr = qr{
405 (?:$Modifier\s+|const\s+)*
406 (?:
407 (?:typeof|__typeof__)\s*\([^\)]*\)|
408 (?:$typeTypedefs\b)|
409 (?:${allWithAttr}\b)
410 )
411 (?:\s+$Modifier|\s+const)*
412 }x;
Joe Hershberger05622192011-10-18 10:06:59 +0000413 $Type = qr{
414 $NonptrType
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000415 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
Joe Hershberger05622192011-10-18 10:06:59 +0000416 (?:\s+$Inline|\s+$Modifier)*
417 }x;
418 $Declare = qr{(?:$Storage\s+)?$Type};
419}
420build_types();
421
Joe Hershberger05622192011-10-18 10:06:59 +0000422our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000423
424# Using $balanced_parens, $LvalOrFunc, or $FuncArg
425# requires at least perl version v5.10.0
426# Any use must be runtime checked with $^V
427
428our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
429our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*};
430our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
Joe Hershberger05622192011-10-18 10:06:59 +0000431
432sub deparenthesize {
433 my ($string) = @_;
434 return "" if (!defined($string));
435 $string =~ s@^\s*\(\s*@@g;
436 $string =~ s@\s*\)\s*$@@g;
437 $string =~ s@\s+@ @g;
438 return $string;
439}
440
Tom Rini6b9709d2014-02-27 08:27:28 -0500441sub seed_camelcase_file {
442 my ($file) = @_;
443
444 return if (!(-f $file));
445
446 local $/;
447
448 open(my $include_file, '<', "$file")
449 or warn "$P: Can't read '$file' $!\n";
450 my $text = <$include_file>;
451 close($include_file);
452
453 my @lines = split('\n', $text);
454
455 foreach my $line (@lines) {
456 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
457 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
458 $camelcase{$1} = 1;
459 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
460 $camelcase{$1} = 1;
461 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
462 $camelcase{$1} = 1;
463 }
464 }
465}
466
467my $camelcase_seeded = 0;
468sub seed_camelcase_includes {
469 return if ($camelcase_seeded);
470
471 my $files;
472 my $camelcase_cache = "";
473 my @include_files = ();
474
475 $camelcase_seeded = 1;
476
477 if (-e ".git") {
478 my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
479 chomp $git_last_include_commit;
480 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
481 } else {
482 my $last_mod_date = 0;
483 $files = `find $root/include -name "*.h"`;
484 @include_files = split('\n', $files);
485 foreach my $file (@include_files) {
486 my $date = POSIX::strftime("%Y%m%d%H%M",
487 localtime((stat $file)[9]));
488 $last_mod_date = $date if ($last_mod_date < $date);
489 }
490 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
491 }
492
493 if ($camelcase_cache ne "" && -f $camelcase_cache) {
494 open(my $camelcase_file, '<', "$camelcase_cache")
495 or warn "$P: Can't read '$camelcase_cache' $!\n";
496 while (<$camelcase_file>) {
497 chomp;
498 $camelcase{$_} = 1;
499 }
500 close($camelcase_file);
501
502 return;
503 }
504
505 if (-e ".git") {
506 $files = `git ls-files "include/*.h"`;
507 @include_files = split('\n', $files);
508 }
509
510 foreach my $file (@include_files) {
511 seed_camelcase_file($file);
512 }
513
514 if ($camelcase_cache ne "") {
515 unlink glob ".checkpatch-camelcase.*";
516 open(my $camelcase_file, '>', "$camelcase_cache")
517 or warn "$P: Can't write '$camelcase_cache' $!\n";
518 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
519 print $camelcase_file ("$_\n");
520 }
521 close($camelcase_file);
522 }
523}
524
Joe Hershberger05622192011-10-18 10:06:59 +0000525$chk_signoff = 0 if ($file);
526
Joe Hershberger05622192011-10-18 10:06:59 +0000527my @rawlines = ();
528my @lines = ();
Tom Rini6b9709d2014-02-27 08:27:28 -0500529my @fixed = ();
Joe Hershberger05622192011-10-18 10:06:59 +0000530my $vname;
531for my $filename (@ARGV) {
532 my $FILE;
533 if ($file) {
534 open($FILE, '-|', "diff -u /dev/null $filename") ||
535 die "$P: $filename: diff failed - $!\n";
536 } elsif ($filename eq '-') {
537 open($FILE, '<&STDIN');
538 } else {
539 open($FILE, '<', "$filename") ||
540 die "$P: $filename: open failed - $!\n";
541 }
542 if ($filename eq '-') {
543 $vname = 'Your patch';
544 } else {
545 $vname = $filename;
546 }
547 while (<$FILE>) {
548 chomp;
549 push(@rawlines, $_);
550 }
551 close($FILE);
552 if (!process($filename)) {
553 $exit = 1;
554 }
555 @rawlines = ();
556 @lines = ();
Tom Rini6b9709d2014-02-27 08:27:28 -0500557 @fixed = ();
Joe Hershberger05622192011-10-18 10:06:59 +0000558}
559
560exit($exit);
561
562sub top_of_kernel_tree {
563 my ($root) = @_;
564
565 my @tree_check = (
Tom Rini6b9709d2014-02-27 08:27:28 -0500566 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
Joe Hershberger05622192011-10-18 10:06:59 +0000567 "README", "Documentation", "arch", "include", "drivers",
568 "fs", "init", "ipc", "kernel", "lib", "scripts",
569 );
570
571 foreach my $check (@tree_check) {
572 if (! -e $root . '/' . $check) {
573 return 0;
574 }
575 }
576 return 1;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000577}
Joe Hershberger05622192011-10-18 10:06:59 +0000578
579sub parse_email {
580 my ($formatted_email) = @_;
581
582 my $name = "";
583 my $address = "";
584 my $comment = "";
585
586 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
587 $name = $1;
588 $address = $2;
589 $comment = $3 if defined $3;
590 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
591 $address = $1;
592 $comment = $2 if defined $2;
593 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
594 $address = $1;
595 $comment = $2 if defined $2;
596 $formatted_email =~ s/$address.*$//;
597 $name = $formatted_email;
Tom Rini6b9709d2014-02-27 08:27:28 -0500598 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +0000599 $name =~ s/^\"|\"$//g;
600 # If there's a name left after stripping spaces and
601 # leading quotes, and the address doesn't have both
602 # leading and trailing angle brackets, the address
603 # is invalid. ie:
604 # "joe smith joe@smith.com" bad
605 # "joe smith <joe@smith.com" bad
606 if ($name ne "" && $address !~ /^<[^>]+>$/) {
607 $name = "";
608 $address = "";
609 $comment = "";
610 }
611 }
612
Tom Rini6b9709d2014-02-27 08:27:28 -0500613 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +0000614 $name =~ s/^\"|\"$//g;
Tom Rini6b9709d2014-02-27 08:27:28 -0500615 $address = trim($address);
Joe Hershberger05622192011-10-18 10:06:59 +0000616 $address =~ s/^\<|\>$//g;
617
618 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
619 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
620 $name = "\"$name\"";
621 }
622
623 return ($name, $address, $comment);
624}
625
626sub format_email {
627 my ($name, $address) = @_;
628
629 my $formatted_email;
630
Tom Rini6b9709d2014-02-27 08:27:28 -0500631 $name = trim($name);
Joe Hershberger05622192011-10-18 10:06:59 +0000632 $name =~ s/^\"|\"$//g;
Tom Rini6b9709d2014-02-27 08:27:28 -0500633 $address = trim($address);
Joe Hershberger05622192011-10-18 10:06:59 +0000634
635 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
636 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
637 $name = "\"$name\"";
638 }
639
640 if ("$name" eq "") {
641 $formatted_email = "$address";
642 } else {
643 $formatted_email = "$name <$address>";
644 }
645
646 return $formatted_email;
647}
648
649sub which_conf {
650 my ($conf) = @_;
651
652 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
653 if (-e "$path/$conf") {
654 return "$path/$conf";
655 }
656 }
657
658 return "";
659}
660
661sub expand_tabs {
662 my ($str) = @_;
663
664 my $res = '';
665 my $n = 0;
666 for my $c (split(//, $str)) {
667 if ($c eq "\t") {
668 $res .= ' ';
669 $n++;
670 for (; ($n % 8) != 0; $n++) {
671 $res .= ' ';
672 }
673 next;
674 }
675 $res .= $c;
676 $n++;
677 }
678
679 return $res;
680}
681sub copy_spacing {
682 (my $res = shift) =~ tr/\t/ /c;
683 return $res;
684}
685
686sub line_stats {
687 my ($line) = @_;
688
689 # Drop the diff line leader and expand tabs
690 $line =~ s/^.//;
691 $line = expand_tabs($line);
692
693 # Pick the indent from the front of the line.
694 my ($white) = ($line =~ /^(\s*)/);
695
696 return (length($line), length($white));
697}
698
699my $sanitise_quote = '';
700
701sub sanitise_line_reset {
702 my ($in_comment) = @_;
703
704 if ($in_comment) {
705 $sanitise_quote = '*/';
706 } else {
707 $sanitise_quote = '';
708 }
709}
710sub sanitise_line {
711 my ($line) = @_;
712
713 my $res = '';
714 my $l = '';
715
716 my $qlen = 0;
717 my $off = 0;
718 my $c;
719
720 # Always copy over the diff marker.
721 $res = substr($line, 0, 1);
722
723 for ($off = 1; $off < length($line); $off++) {
724 $c = substr($line, $off, 1);
725
726 # Comments we are wacking completly including the begin
727 # and end, all to $;.
728 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
729 $sanitise_quote = '*/';
730
731 substr($res, $off, 2, "$;$;");
732 $off++;
733 next;
734 }
735 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
736 $sanitise_quote = '';
737 substr($res, $off, 2, "$;$;");
738 $off++;
739 next;
740 }
741 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
742 $sanitise_quote = '//';
743
744 substr($res, $off, 2, $sanitise_quote);
745 $off++;
746 next;
747 }
748
749 # A \ in a string means ignore the next character.
750 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
751 $c eq "\\") {
752 substr($res, $off, 2, 'XX');
753 $off++;
754 next;
755 }
756 # Regular quotes.
757 if ($c eq "'" || $c eq '"') {
758 if ($sanitise_quote eq '') {
759 $sanitise_quote = $c;
760
761 substr($res, $off, 1, $c);
762 next;
763 } elsif ($sanitise_quote eq $c) {
764 $sanitise_quote = '';
765 }
766 }
767
768 #print "c<$c> SQ<$sanitise_quote>\n";
769 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
770 substr($res, $off, 1, $;);
771 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
772 substr($res, $off, 1, $;);
773 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
774 substr($res, $off, 1, 'X');
775 } else {
776 substr($res, $off, 1, $c);
777 }
778 }
779
780 if ($sanitise_quote eq '//') {
781 $sanitise_quote = '';
782 }
783
784 # The pathname on a #include may be surrounded by '<' and '>'.
785 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
786 my $clean = 'X' x length($1);
787 $res =~ s@\<.*\>@<$clean>@;
788
789 # The whole of a #error is a string.
790 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
791 my $clean = 'X' x length($1);
792 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
793 }
794
795 return $res;
796}
797
Tom Rini6b9709d2014-02-27 08:27:28 -0500798sub get_quoted_string {
799 my ($line, $rawline) = @_;
800
801 return "" if ($line !~ m/(\"[X]+\")/g);
802 return substr($rawline, $-[0], $+[0] - $-[0]);
803}
804
Joe Hershberger05622192011-10-18 10:06:59 +0000805sub ctx_statement_block {
806 my ($linenr, $remain, $off) = @_;
807 my $line = $linenr - 1;
808 my $blk = '';
809 my $soff = $off;
810 my $coff = $off - 1;
811 my $coff_set = 0;
812
813 my $loff = 0;
814
815 my $type = '';
816 my $level = 0;
817 my @stack = ();
818 my $p;
819 my $c;
820 my $len = 0;
821
822 my $remainder;
823 while (1) {
824 @stack = (['', 0]) if ($#stack == -1);
825
826 #warn "CSB: blk<$blk> remain<$remain>\n";
827 # If we are about to drop off the end, pull in more
828 # context.
829 if ($off >= $len) {
830 for (; $remain > 0; $line++) {
831 last if (!defined $lines[$line]);
832 next if ($lines[$line] =~ /^-/);
833 $remain--;
834 $loff = $len;
835 $blk .= $lines[$line] . "\n";
836 $len = length($blk);
837 $line++;
838 last;
839 }
840 # Bail if there is no further context.
841 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
842 if ($off >= $len) {
843 last;
844 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000845 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
846 $level++;
847 $type = '#';
848 }
Joe Hershberger05622192011-10-18 10:06:59 +0000849 }
850 $p = $c;
851 $c = substr($blk, $off, 1);
852 $remainder = substr($blk, $off);
853
854 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
855
856 # Handle nested #if/#else.
857 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
858 push(@stack, [ $type, $level ]);
859 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
860 ($type, $level) = @{$stack[$#stack - 1]};
861 } elsif ($remainder =~ /^#\s*endif\b/) {
862 ($type, $level) = @{pop(@stack)};
863 }
864
865 # Statement ends at the ';' or a close '}' at the
866 # outermost level.
867 if ($level == 0 && $c eq ';') {
868 last;
869 }
870
871 # An else is really a conditional as long as its not else if
872 if ($level == 0 && $coff_set == 0 &&
873 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
874 $remainder =~ /^(else)(?:\s|{)/ &&
875 $remainder !~ /^else\s+if\b/) {
876 $coff = $off + length($1) - 1;
877 $coff_set = 1;
878 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
879 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
880 }
881
882 if (($type eq '' || $type eq '(') && $c eq '(') {
883 $level++;
884 $type = '(';
885 }
886 if ($type eq '(' && $c eq ')') {
887 $level--;
888 $type = ($level != 0)? '(' : '';
889
890 if ($level == 0 && $coff < $soff) {
891 $coff = $off;
892 $coff_set = 1;
893 #warn "CSB: mark coff<$coff>\n";
894 }
895 }
896 if (($type eq '' || $type eq '{') && $c eq '{') {
897 $level++;
898 $type = '{';
899 }
900 if ($type eq '{' && $c eq '}') {
901 $level--;
902 $type = ($level != 0)? '{' : '';
903
904 if ($level == 0) {
905 if (substr($blk, $off + 1, 1) eq ';') {
906 $off++;
907 }
908 last;
909 }
910 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +0000911 # Preprocessor commands end at the newline unless escaped.
912 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
913 $level--;
914 $type = '';
915 $off++;
916 last;
917 }
Joe Hershberger05622192011-10-18 10:06:59 +0000918 $off++;
919 }
920 # We are truly at the end, so shuffle to the next line.
921 if ($off == $len) {
922 $loff = $len + 1;
923 $line++;
924 $remain--;
925 }
926
927 my $statement = substr($blk, $soff, $off - $soff + 1);
928 my $condition = substr($blk, $soff, $coff - $soff + 1);
929
930 #warn "STATEMENT<$statement>\n";
931 #warn "CONDITION<$condition>\n";
932
933 #print "coff<$coff> soff<$off> loff<$loff>\n";
934
935 return ($statement, $condition,
936 $line, $remain + 1, $off - $loff + 1, $level);
937}
938
939sub statement_lines {
940 my ($stmt) = @_;
941
942 # Strip the diff line prefixes and rip blank lines at start and end.
943 $stmt =~ s/(^|\n)./$1/g;
944 $stmt =~ s/^\s*//;
945 $stmt =~ s/\s*$//;
946
947 my @stmt_lines = ($stmt =~ /\n/g);
948
949 return $#stmt_lines + 2;
950}
951
952sub statement_rawlines {
953 my ($stmt) = @_;
954
955 my @stmt_lines = ($stmt =~ /\n/g);
956
957 return $#stmt_lines + 2;
958}
959
960sub statement_block_size {
961 my ($stmt) = @_;
962
963 $stmt =~ s/(^|\n)./$1/g;
964 $stmt =~ s/^\s*{//;
965 $stmt =~ s/}\s*$//;
966 $stmt =~ s/^\s*//;
967 $stmt =~ s/\s*$//;
968
969 my @stmt_lines = ($stmt =~ /\n/g);
970 my @stmt_statements = ($stmt =~ /;/g);
971
972 my $stmt_lines = $#stmt_lines + 2;
973 my $stmt_statements = $#stmt_statements + 1;
974
975 if ($stmt_lines > $stmt_statements) {
976 return $stmt_lines;
977 } else {
978 return $stmt_statements;
979 }
980}
981
982sub ctx_statement_full {
983 my ($linenr, $remain, $off) = @_;
984 my ($statement, $condition, $level);
985
986 my (@chunks);
987
988 # Grab the first conditional/block pair.
989 ($statement, $condition, $linenr, $remain, $off, $level) =
990 ctx_statement_block($linenr, $remain, $off);
991 #print "F: c<$condition> s<$statement> remain<$remain>\n";
992 push(@chunks, [ $condition, $statement ]);
993 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
994 return ($level, $linenr, @chunks);
995 }
996
997 # Pull in the following conditional/block pairs and see if they
998 # could continue the statement.
999 for (;;) {
1000 ($statement, $condition, $linenr, $remain, $off, $level) =
1001 ctx_statement_block($linenr, $remain, $off);
1002 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1003 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1004 #print "C: push\n";
1005 push(@chunks, [ $condition, $statement ]);
1006 }
1007
1008 return ($level, $linenr, @chunks);
1009}
1010
1011sub ctx_block_get {
1012 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1013 my $line;
1014 my $start = $linenr - 1;
1015 my $blk = '';
1016 my @o;
1017 my @c;
1018 my @res = ();
1019
1020 my $level = 0;
1021 my @stack = ($level);
1022 for ($line = $start; $remain > 0; $line++) {
1023 next if ($rawlines[$line] =~ /^-/);
1024 $remain--;
1025
1026 $blk .= $rawlines[$line];
1027
1028 # Handle nested #if/#else.
1029 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1030 push(@stack, $level);
1031 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1032 $level = $stack[$#stack - 1];
1033 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1034 $level = pop(@stack);
1035 }
1036
1037 foreach my $c (split(//, $lines[$line])) {
1038 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1039 if ($off > 0) {
1040 $off--;
1041 next;
1042 }
1043
1044 if ($c eq $close && $level > 0) {
1045 $level--;
1046 last if ($level == 0);
1047 } elsif ($c eq $open) {
1048 $level++;
1049 }
1050 }
1051
1052 if (!$outer || $level <= 1) {
1053 push(@res, $rawlines[$line]);
1054 }
1055
1056 last if ($level == 0);
1057 }
1058
1059 return ($level, @res);
1060}
1061sub ctx_block_outer {
1062 my ($linenr, $remain) = @_;
1063
1064 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1065 return @r;
1066}
1067sub ctx_block {
1068 my ($linenr, $remain) = @_;
1069
1070 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1071 return @r;
1072}
1073sub ctx_statement {
1074 my ($linenr, $remain, $off) = @_;
1075
1076 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1077 return @r;
1078}
1079sub ctx_block_level {
1080 my ($linenr, $remain) = @_;
1081
1082 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1083}
1084sub ctx_statement_level {
1085 my ($linenr, $remain, $off) = @_;
1086
1087 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1088}
1089
1090sub ctx_locate_comment {
1091 my ($first_line, $end_line) = @_;
1092
1093 # Catch a comment on the end of the line itself.
1094 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1095 return $current_comment if (defined $current_comment);
1096
1097 # Look through the context and try and figure out if there is a
1098 # comment.
1099 my $in_comment = 0;
1100 $current_comment = '';
1101 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1102 my $line = $rawlines[$linenr - 1];
1103 #warn " $line\n";
1104 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1105 $in_comment = 1;
1106 }
1107 if ($line =~ m@/\*@) {
1108 $in_comment = 1;
1109 }
1110 if (!$in_comment && $current_comment ne '') {
1111 $current_comment = '';
1112 }
1113 $current_comment .= $line . "\n" if ($in_comment);
1114 if ($line =~ m@\*/@) {
1115 $in_comment = 0;
1116 }
1117 }
1118
1119 chomp($current_comment);
1120 return($current_comment);
1121}
1122sub ctx_has_comment {
1123 my ($first_line, $end_line) = @_;
1124 my $cmt = ctx_locate_comment($first_line, $end_line);
1125
1126 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1127 ##print "CMMT: $cmt\n";
1128
1129 return ($cmt ne '');
1130}
1131
1132sub raw_line {
1133 my ($linenr, $cnt) = @_;
1134
1135 my $offset = $linenr - 1;
1136 $cnt++;
1137
1138 my $line;
1139 while ($cnt) {
1140 $line = $rawlines[$offset++];
1141 next if (defined($line) && $line =~ /^-/);
1142 $cnt--;
1143 }
1144
1145 return $line;
1146}
1147
1148sub cat_vet {
1149 my ($vet) = @_;
1150 my ($res, $coded);
1151
1152 $res = '';
1153 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1154 $res .= $1;
1155 if ($2 ne '') {
1156 $coded = sprintf("^%c", unpack('C', $2) + 64);
1157 $res .= $coded;
1158 }
1159 }
1160 $res =~ s/$/\$/;
1161
1162 return $res;
1163}
1164
1165my $av_preprocessor = 0;
1166my $av_pending;
1167my @av_paren_type;
1168my $av_pend_colon;
1169
1170sub annotate_reset {
1171 $av_preprocessor = 0;
1172 $av_pending = '_';
1173 @av_paren_type = ('E');
1174 $av_pend_colon = 'O';
1175}
1176
1177sub annotate_values {
1178 my ($stream, $type) = @_;
1179
1180 my $res;
1181 my $var = '_' x length($stream);
1182 my $cur = $stream;
1183
1184 print "$stream\n" if ($dbg_values > 1);
1185
1186 while (length($cur)) {
1187 @av_paren_type = ('E') if ($#av_paren_type < 0);
1188 print " <" . join('', @av_paren_type) .
1189 "> <$type> <$av_pending>" if ($dbg_values > 1);
1190 if ($cur =~ /^(\s+)/o) {
1191 print "WS($1)\n" if ($dbg_values > 1);
1192 if ($1 =~ /\n/ && $av_preprocessor) {
1193 $type = pop(@av_paren_type);
1194 $av_preprocessor = 0;
1195 }
1196
1197 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1198 print "CAST($1)\n" if ($dbg_values > 1);
1199 push(@av_paren_type, $type);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001200 $type = 'c';
Joe Hershberger05622192011-10-18 10:06:59 +00001201
1202 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1203 print "DECLARE($1)\n" if ($dbg_values > 1);
1204 $type = 'T';
1205
1206 } elsif ($cur =~ /^($Modifier)\s*/) {
1207 print "MODIFIER($1)\n" if ($dbg_values > 1);
1208 $type = 'T';
1209
1210 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1211 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1212 $av_preprocessor = 1;
1213 push(@av_paren_type, $type);
1214 if ($2 ne '') {
1215 $av_pending = 'N';
1216 }
1217 $type = 'E';
1218
1219 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1220 print "UNDEF($1)\n" if ($dbg_values > 1);
1221 $av_preprocessor = 1;
1222 push(@av_paren_type, $type);
1223
1224 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1225 print "PRE_START($1)\n" if ($dbg_values > 1);
1226 $av_preprocessor = 1;
1227
1228 push(@av_paren_type, $type);
1229 push(@av_paren_type, $type);
1230 $type = 'E';
1231
1232 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1233 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1234 $av_preprocessor = 1;
1235
1236 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1237
1238 $type = 'E';
1239
1240 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1241 print "PRE_END($1)\n" if ($dbg_values > 1);
1242
1243 $av_preprocessor = 1;
1244
1245 # Assume all arms of the conditional end as this
1246 # one does, and continue as if the #endif was not here.
1247 pop(@av_paren_type);
1248 push(@av_paren_type, $type);
1249 $type = 'E';
1250
1251 } elsif ($cur =~ /^(\\\n)/o) {
1252 print "PRECONT($1)\n" if ($dbg_values > 1);
1253
1254 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1255 print "ATTR($1)\n" if ($dbg_values > 1);
1256 $av_pending = $type;
1257 $type = 'N';
1258
1259 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1260 print "SIZEOF($1)\n" if ($dbg_values > 1);
1261 if (defined $2) {
1262 $av_pending = 'V';
1263 }
1264 $type = 'N';
1265
1266 } elsif ($cur =~ /^(if|while|for)\b/o) {
1267 print "COND($1)\n" if ($dbg_values > 1);
1268 $av_pending = 'E';
1269 $type = 'N';
1270
1271 } elsif ($cur =~/^(case)/o) {
1272 print "CASE($1)\n" if ($dbg_values > 1);
1273 $av_pend_colon = 'C';
1274 $type = 'N';
1275
1276 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1277 print "KEYWORD($1)\n" if ($dbg_values > 1);
1278 $type = 'N';
1279
1280 } elsif ($cur =~ /^(\()/o) {
1281 print "PAREN('$1')\n" if ($dbg_values > 1);
1282 push(@av_paren_type, $av_pending);
1283 $av_pending = '_';
1284 $type = 'N';
1285
1286 } elsif ($cur =~ /^(\))/o) {
1287 my $new_type = pop(@av_paren_type);
1288 if ($new_type ne '_') {
1289 $type = $new_type;
1290 print "PAREN('$1') -> $type\n"
1291 if ($dbg_values > 1);
1292 } else {
1293 print "PAREN('$1')\n" if ($dbg_values > 1);
1294 }
1295
1296 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1297 print "FUNC($1)\n" if ($dbg_values > 1);
1298 $type = 'V';
1299 $av_pending = 'V';
1300
1301 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1302 if (defined $2 && $type eq 'C' || $type eq 'T') {
1303 $av_pend_colon = 'B';
1304 } elsif ($type eq 'E') {
1305 $av_pend_colon = 'L';
1306 }
1307 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1308 $type = 'V';
1309
1310 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1311 print "IDENT($1)\n" if ($dbg_values > 1);
1312 $type = 'V';
1313
1314 } elsif ($cur =~ /^($Assignment)/o) {
1315 print "ASSIGN($1)\n" if ($dbg_values > 1);
1316 $type = 'N';
1317
1318 } elsif ($cur =~/^(;|{|})/) {
1319 print "END($1)\n" if ($dbg_values > 1);
1320 $type = 'E';
1321 $av_pend_colon = 'O';
1322
1323 } elsif ($cur =~/^(,)/) {
1324 print "COMMA($1)\n" if ($dbg_values > 1);
1325 $type = 'C';
1326
1327 } elsif ($cur =~ /^(\?)/o) {
1328 print "QUESTION($1)\n" if ($dbg_values > 1);
1329 $type = 'N';
1330
1331 } elsif ($cur =~ /^(:)/o) {
1332 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1333
1334 substr($var, length($res), 1, $av_pend_colon);
1335 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1336 $type = 'E';
1337 } else {
1338 $type = 'N';
1339 }
1340 $av_pend_colon = 'O';
1341
1342 } elsif ($cur =~ /^(\[)/o) {
1343 print "CLOSE($1)\n" if ($dbg_values > 1);
1344 $type = 'N';
1345
1346 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1347 my $variant;
1348
1349 print "OPV($1)\n" if ($dbg_values > 1);
1350 if ($type eq 'V') {
1351 $variant = 'B';
1352 } else {
1353 $variant = 'U';
1354 }
1355
1356 substr($var, length($res), 1, $variant);
1357 $type = 'N';
1358
1359 } elsif ($cur =~ /^($Operators)/o) {
1360 print "OP($1)\n" if ($dbg_values > 1);
1361 if ($1 ne '++' && $1 ne '--') {
1362 $type = 'N';
1363 }
1364
1365 } elsif ($cur =~ /(^.)/o) {
1366 print "C($1)\n" if ($dbg_values > 1);
1367 }
1368 if (defined $1) {
1369 $cur = substr($cur, length($1));
1370 $res .= $type x length($1);
1371 }
1372 }
1373
1374 return ($res, $var);
1375}
1376
1377sub possible {
1378 my ($possible, $line) = @_;
1379 my $notPermitted = qr{(?:
1380 ^(?:
1381 $Modifier|
1382 $Storage|
1383 $Type|
1384 DEFINE_\S+
1385 )$|
1386 ^(?:
1387 goto|
1388 return|
1389 case|
1390 else|
1391 asm|__asm__|
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001392 do|
1393 \#|
1394 \#\#|
Joe Hershberger05622192011-10-18 10:06:59 +00001395 )(?:\s|$)|
1396 ^(?:typedef|struct|enum)\b
1397 )}x;
1398 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1399 if ($possible !~ $notPermitted) {
1400 # Check for modifiers.
1401 $possible =~ s/\s*$Storage\s*//g;
1402 $possible =~ s/\s*$Sparse\s*//g;
1403 if ($possible =~ /^\s*$/) {
1404
1405 } elsif ($possible =~ /\s/) {
1406 $possible =~ s/\s*$Type\s*//g;
1407 for my $modifier (split(' ', $possible)) {
1408 if ($modifier !~ $notPermitted) {
1409 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1410 push(@modifierList, $modifier);
1411 }
1412 }
1413
1414 } else {
1415 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1416 push(@typeList, $possible);
1417 }
1418 build_types();
1419 } else {
1420 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1421 }
1422}
1423
1424my $prefix = '';
1425
1426sub show_type {
Tom Rini6b9709d2014-02-27 08:27:28 -05001427 return defined $use_type{$_[0]} if (scalar keys %use_type > 0);
1428
1429 return !defined $ignore_type{$_[0]};
Joe Hershberger05622192011-10-18 10:06:59 +00001430}
1431
1432sub report {
1433 if (!show_type($_[1]) ||
1434 (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) {
1435 return 0;
1436 }
1437 my $line;
1438 if ($show_types) {
1439 $line = "$prefix$_[0]:$_[1]: $_[2]\n";
1440 } else {
1441 $line = "$prefix$_[0]: $_[2]\n";
1442 }
1443 $line = (split('\n', $line))[0] . "\n" if ($terse);
1444
1445 push(our @report, $line);
1446
1447 return 1;
1448}
1449sub report_dump {
1450 our @report;
1451}
1452
1453sub ERROR {
1454 if (report("ERROR", $_[0], $_[1])) {
1455 our $clean = 0;
1456 our $cnt_error++;
Tom Rini6b9709d2014-02-27 08:27:28 -05001457 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00001458 }
Tom Rini6b9709d2014-02-27 08:27:28 -05001459 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001460}
1461sub WARN {
1462 if (report("WARNING", $_[0], $_[1])) {
1463 our $clean = 0;
1464 our $cnt_warn++;
Tom Rini6b9709d2014-02-27 08:27:28 -05001465 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00001466 }
Tom Rini6b9709d2014-02-27 08:27:28 -05001467 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001468}
1469sub CHK {
1470 if ($check && report("CHECK", $_[0], $_[1])) {
1471 our $clean = 0;
1472 our $cnt_chk++;
Tom Rini6b9709d2014-02-27 08:27:28 -05001473 return 1;
Joe Hershberger05622192011-10-18 10:06:59 +00001474 }
Tom Rini6b9709d2014-02-27 08:27:28 -05001475 return 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001476}
1477
1478sub check_absolute_file {
1479 my ($absolute, $herecurr) = @_;
1480 my $file = $absolute;
1481
1482 ##print "absolute<$absolute>\n";
1483
1484 # See if any suffix of this path is a path within the tree.
1485 while ($file =~ s@^[^/]*/@@) {
1486 if (-f "$root/$file") {
1487 ##print "file<$file>\n";
1488 last;
1489 }
1490 }
1491 if (! -f _) {
1492 return 0;
1493 }
1494
1495 # It is, so see if the prefix is acceptable.
1496 my $prefix = $absolute;
1497 substr($prefix, -length($file)) = '';
1498
1499 ##print "prefix<$prefix>\n";
1500 if ($prefix ne ".../") {
1501 WARN("USE_RELATIVE_PATH",
1502 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
1503 }
1504}
1505
Tom Rini6b9709d2014-02-27 08:27:28 -05001506sub trim {
1507 my ($string) = @_;
1508
1509 $string =~ s/^\s+|\s+$//g;
1510
1511 return $string;
1512}
1513
1514sub ltrim {
1515 my ($string) = @_;
1516
1517 $string =~ s/^\s+//;
1518
1519 return $string;
1520}
1521
1522sub rtrim {
1523 my ($string) = @_;
1524
1525 $string =~ s/\s+$//;
1526
1527 return $string;
1528}
1529
1530sub string_find_replace {
1531 my ($string, $find, $replace) = @_;
1532
1533 $string =~ s/$find/$replace/g;
1534
1535 return $string;
1536}
1537
1538sub tabify {
1539 my ($leading) = @_;
1540
1541 my $source_indent = 8;
1542 my $max_spaces_before_tab = $source_indent - 1;
1543 my $spaces_to_tab = " " x $source_indent;
1544
1545 #convert leading spaces to tabs
1546 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
1547 #Remove spaces before a tab
1548 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
1549
1550 return "$leading";
1551}
1552
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001553sub pos_last_openparen {
1554 my ($line) = @_;
1555
1556 my $pos = 0;
1557
1558 my $opens = $line =~ tr/\(/\(/;
1559 my $closes = $line =~ tr/\)/\)/;
1560
1561 my $last_openparen = 0;
1562
1563 if (($opens == 0) || ($closes >= $opens)) {
1564 return -1;
1565 }
1566
1567 my $len = length($line);
1568
1569 for ($pos = 0; $pos < $len; $pos++) {
1570 my $string = substr($line, $pos);
1571 if ($string =~ /^($FuncArg|$balanced_parens)/) {
1572 $pos += length($1) - 1;
1573 } elsif (substr($line, $pos, 1) eq '(') {
1574 $last_openparen = $pos;
1575 } elsif (index($string, '(') == -1) {
1576 last;
1577 }
1578 }
1579
1580 return $last_openparen + 1;
1581}
1582
Joe Hershberger05622192011-10-18 10:06:59 +00001583sub process {
1584 my $filename = shift;
1585
1586 my $linenr=0;
1587 my $prevline="";
1588 my $prevrawline="";
1589 my $stashline="";
1590 my $stashrawline="";
1591
1592 my $length;
1593 my $indent;
1594 my $previndent=0;
1595 my $stashindent=0;
1596
1597 our $clean = 1;
1598 my $signoff = 0;
1599 my $is_patch = 0;
1600
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001601 my $in_header_lines = 1;
1602 my $in_commit_log = 0; #Scanning lines before patch
1603
1604 my $non_utf8_charset = 0;
1605
Joe Hershberger05622192011-10-18 10:06:59 +00001606 our @report = ();
1607 our $cnt_lines = 0;
1608 our $cnt_error = 0;
1609 our $cnt_warn = 0;
1610 our $cnt_chk = 0;
1611
1612 # Trace the real file/line as we go.
1613 my $realfile = '';
1614 my $realline = 0;
1615 my $realcnt = 0;
1616 my $here = '';
1617 my $in_comment = 0;
1618 my $comment_edge = 0;
1619 my $first_line = 0;
1620 my $p1_prefix = '';
1621
1622 my $prev_values = 'E';
1623
1624 # suppression flags
1625 my %suppress_ifbraces;
1626 my %suppress_whiletrailers;
1627 my %suppress_export;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001628 my $suppress_statement = 0;
1629
Tom Rini6b9709d2014-02-27 08:27:28 -05001630 my %signatures = ();
Joe Hershberger05622192011-10-18 10:06:59 +00001631
1632 # Pre-scan the patch sanitizing the lines.
1633 # Pre-scan the patch looking for any __setup documentation.
1634 #
1635 my @setup_docs = ();
1636 my $setup_docs = 0;
1637
Tom Rini6b9709d2014-02-27 08:27:28 -05001638 my $camelcase_file_seeded = 0;
1639
Joe Hershberger05622192011-10-18 10:06:59 +00001640 sanitise_line_reset();
1641 my $line;
1642 foreach my $rawline (@rawlines) {
1643 $linenr++;
1644 $line = $rawline;
1645
Tom Rini6b9709d2014-02-27 08:27:28 -05001646 push(@fixed, $rawline) if ($fix);
1647
Joe Hershberger05622192011-10-18 10:06:59 +00001648 if ($rawline=~/^\+\+\+\s+(\S+)/) {
1649 $setup_docs = 0;
1650 if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1651 $setup_docs = 1;
1652 }
1653 #next;
1654 }
1655 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1656 $realline=$1-1;
1657 if (defined $2) {
1658 $realcnt=$3+1;
1659 } else {
1660 $realcnt=1+1;
1661 }
1662 $in_comment = 0;
1663
1664 # Guestimate if this is a continuing comment. Run
1665 # the context looking for a comment "edge". If this
1666 # edge is a close comment then we must be in a comment
1667 # at context start.
1668 my $edge;
1669 my $cnt = $realcnt;
1670 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
1671 next if (defined $rawlines[$ln - 1] &&
1672 $rawlines[$ln - 1] =~ /^-/);
1673 $cnt--;
1674 #print "RAW<$rawlines[$ln - 1]>\n";
1675 last if (!defined $rawlines[$ln - 1]);
1676 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1677 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1678 ($edge) = $1;
1679 last;
1680 }
1681 }
1682 if (defined $edge && $edge eq '*/') {
1683 $in_comment = 1;
1684 }
1685
1686 # Guestimate if this is a continuing comment. If this
1687 # is the start of a diff block and this line starts
1688 # ' *' then it is very likely a comment.
1689 if (!defined $edge &&
1690 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1691 {
1692 $in_comment = 1;
1693 }
1694
1695 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1696 sanitise_line_reset($in_comment);
1697
1698 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1699 # Standardise the strings and chars within the input to
1700 # simplify matching -- only bother with positive lines.
1701 $line = sanitise_line($rawline);
1702 }
1703 push(@lines, $line);
1704
1705 if ($realcnt > 1) {
1706 $realcnt-- if ($line =~ /^(?:\+| |$)/);
1707 } else {
1708 $realcnt = 0;
1709 }
1710
1711 #print "==>$rawline\n";
1712 #print "-->$line\n";
1713
1714 if ($setup_docs && $line =~ /^\+/) {
1715 push(@setup_docs, $line);
1716 }
1717 }
1718
1719 $prefix = '';
1720
1721 $realcnt = 0;
1722 $linenr = 0;
1723 foreach my $line (@lines) {
1724 $linenr++;
Tom Rini6b9709d2014-02-27 08:27:28 -05001725 my $sline = $line; #copy of $line
1726 $sline =~ s/$;/ /g; #with comments as spaces
Joe Hershberger05622192011-10-18 10:06:59 +00001727
1728 my $rawline = $rawlines[$linenr - 1];
1729
1730#extract the line range in the file after the patch is applied
1731 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1732 $is_patch = 1;
1733 $first_line = $linenr + 1;
1734 $realline=$1-1;
1735 if (defined $2) {
1736 $realcnt=$3+1;
1737 } else {
1738 $realcnt=1+1;
1739 }
1740 annotate_reset();
1741 $prev_values = 'E';
1742
1743 %suppress_ifbraces = ();
1744 %suppress_whiletrailers = ();
1745 %suppress_export = ();
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001746 $suppress_statement = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001747 next;
1748
1749# track the line number as we move through the hunk, note that
1750# new versions of GNU diff omit the leading space on completely
1751# blank context lines so we need to count that too.
1752 } elsif ($line =~ /^( |\+|$)/) {
1753 $realline++;
1754 $realcnt-- if ($realcnt != 0);
1755
1756 # Measure the line length and indent.
1757 ($length, $indent) = line_stats($rawline);
1758
1759 # Track the previous line.
1760 ($prevline, $stashline) = ($stashline, $line);
1761 ($previndent, $stashindent) = ($stashindent, $indent);
1762 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1763
1764 #warn "line<$line>\n";
1765
1766 } elsif ($realcnt == 1) {
1767 $realcnt--;
1768 }
1769
1770 my $hunk_line = ($realcnt != 0);
1771
1772#make up the handle for any error we report on this line
1773 $prefix = "$filename:$realline: " if ($emacs && $file);
1774 $prefix = "$filename:$linenr: " if ($emacs && !$file);
1775
1776 $here = "#$linenr: " if (!$file);
1777 $here = "#$realline: " if ($file);
1778
1779 # extract the filename as it passes
1780 if ($line =~ /^diff --git.*?(\S+)$/) {
1781 $realfile = $1;
Tom Rini6b9709d2014-02-27 08:27:28 -05001782 $realfile =~ s@^([^/]*)/@@ if (!$file);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001783 $in_commit_log = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001784 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1785 $realfile = $1;
Tom Rini6b9709d2014-02-27 08:27:28 -05001786 $realfile =~ s@^([^/]*)/@@ if (!$file);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001787 $in_commit_log = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001788
1789 $p1_prefix = $1;
1790 if (!$file && $tree && $p1_prefix ne '' &&
1791 -e "$root/$p1_prefix") {
1792 WARN("PATCH_PREFIX",
1793 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
1794 }
1795
1796 if ($realfile =~ m@^include/asm/@) {
1797 ERROR("MODIFIED_INCLUDE_ASM",
1798 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1799 }
1800 next;
1801 }
1802
1803 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
1804
1805 my $hereline = "$here\n$rawline\n";
1806 my $herecurr = "$here\n$rawline\n";
1807 my $hereprev = "$here\n$prevrawline\n$rawline\n";
1808
1809 $cnt_lines++ if ($realcnt != 0);
1810
1811# Check for incorrect file permissions
1812 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
1813 my $permhere = $here . "FILE: $realfile\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05001814 if ($realfile !~ m@scripts/@ &&
1815 $realfile !~ /\.(py|pl|awk|sh)$/) {
Joe Hershberger05622192011-10-18 10:06:59 +00001816 ERROR("EXECUTE_PERMISSIONS",
1817 "do not set execute permissions for source files\n" . $permhere);
1818 }
1819 }
1820
1821# Check the patch for a signoff:
1822 if ($line =~ /^\s*signed-off-by:/i) {
1823 $signoff++;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001824 $in_commit_log = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001825 }
1826
1827# Check signature styles
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001828 if (!$in_header_lines &&
1829 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
Joe Hershberger05622192011-10-18 10:06:59 +00001830 my $space_before = $1;
1831 my $sign_off = $2;
1832 my $space_after = $3;
1833 my $email = $4;
1834 my $ucfirst_sign_off = ucfirst(lc($sign_off));
1835
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001836 if ($sign_off !~ /$signature_tags/) {
1837 WARN("BAD_SIGN_OFF",
1838 "Non-standard signature: $sign_off\n" . $herecurr);
1839 }
Joe Hershberger05622192011-10-18 10:06:59 +00001840 if (defined $space_before && $space_before ne "") {
Tom Rini6b9709d2014-02-27 08:27:28 -05001841 if (WARN("BAD_SIGN_OFF",
1842 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
1843 $fix) {
1844 $fixed[$linenr - 1] =
1845 "$ucfirst_sign_off $email";
1846 }
Joe Hershberger05622192011-10-18 10:06:59 +00001847 }
1848 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
Tom Rini6b9709d2014-02-27 08:27:28 -05001849 if (WARN("BAD_SIGN_OFF",
1850 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
1851 $fix) {
1852 $fixed[$linenr - 1] =
1853 "$ucfirst_sign_off $email";
1854 }
1855
Joe Hershberger05622192011-10-18 10:06:59 +00001856 }
1857 if (!defined $space_after || $space_after ne " ") {
Tom Rini6b9709d2014-02-27 08:27:28 -05001858 if (WARN("BAD_SIGN_OFF",
1859 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
1860 $fix) {
1861 $fixed[$linenr - 1] =
1862 "$ucfirst_sign_off $email";
1863 }
Joe Hershberger05622192011-10-18 10:06:59 +00001864 }
1865
1866 my ($email_name, $email_address, $comment) = parse_email($email);
1867 my $suggested_email = format_email(($email_name, $email_address));
1868 if ($suggested_email eq "") {
1869 ERROR("BAD_SIGN_OFF",
1870 "Unrecognized email address: '$email'\n" . $herecurr);
1871 } else {
1872 my $dequoted = $suggested_email;
1873 $dequoted =~ s/^"//;
1874 $dequoted =~ s/" </ </;
1875 # Don't force email to have quotes
1876 # Allow just an angle bracketed address
1877 if ("$dequoted$comment" ne $email &&
1878 "<$email_address>$comment" ne $email &&
1879 "$suggested_email$comment" ne $email) {
1880 WARN("BAD_SIGN_OFF",
1881 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
1882 }
1883 }
Tom Rini6b9709d2014-02-27 08:27:28 -05001884
1885# Check for duplicate signatures
1886 my $sig_nospace = $line;
1887 $sig_nospace =~ s/\s//g;
1888 $sig_nospace = lc($sig_nospace);
1889 if (defined $signatures{$sig_nospace}) {
1890 WARN("BAD_SIGN_OFF",
1891 "Duplicate signature\n" . $herecurr);
1892 } else {
1893 $signatures{$sig_nospace} = 1;
1894 }
Joe Hershberger05622192011-10-18 10:06:59 +00001895 }
1896
1897# Check for wrappage within a valid hunk of the file
1898 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1899 ERROR("CORRUPTED_PATCH",
1900 "patch seems to be corrupt (line wrapped?)\n" .
1901 $herecurr) if (!$emitted_corrupt++);
1902 }
1903
1904# Check for absolute kernel paths.
1905 if ($tree) {
1906 while ($line =~ m{(?:^|\s)(/\S*)}g) {
1907 my $file = $1;
1908
1909 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
1910 check_absolute_file($1, $herecurr)) {
1911 #
1912 } else {
1913 check_absolute_file($file, $herecurr);
1914 }
1915 }
1916 }
1917
1918# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1919 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1920 $rawline !~ m/^$UTF8*$/) {
1921 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1922
1923 my $blank = copy_spacing($rawline);
1924 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1925 my $hereptr = "$hereline$ptr\n";
1926
1927 CHK("INVALID_UTF8",
1928 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
1929 }
1930
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001931# Check if it's the start of a commit log
1932# (not a header line and we haven't seen the patch filename)
1933 if ($in_header_lines && $realfile =~ /^$/ &&
1934 $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
1935 $in_header_lines = 0;
1936 $in_commit_log = 1;
1937 }
1938
1939# Check if there is UTF-8 in a commit log when a mail header has explicitly
1940# declined it, i.e defined some charset where it is missing.
1941 if ($in_header_lines &&
1942 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
1943 $1 !~ /utf-8/i) {
1944 $non_utf8_charset = 1;
1945 }
1946
1947 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
1948 $rawline =~ /$NON_ASCII_UTF8/) {
1949 WARN("UTF8_BEFORE_PATCH",
1950 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
1951 }
1952
Joe Hershberger05622192011-10-18 10:06:59 +00001953# ignore non-hunk lines and lines being removed
1954 next if (!$hunk_line || $line =~ /^-/);
1955
1956#trailing whitespace
1957 if ($line =~ /^\+.*\015/) {
1958 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05001959 if (ERROR("DOS_LINE_ENDINGS",
1960 "DOS line endings\n" . $herevet) &&
1961 $fix) {
1962 $fixed[$linenr - 1] =~ s/[\s\015]+$//;
1963 }
Joe Hershberger05622192011-10-18 10:06:59 +00001964 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1965 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05001966 if (ERROR("TRAILING_WHITESPACE",
1967 "trailing whitespace\n" . $herevet) &&
1968 $fix) {
1969 $fixed[$linenr - 1] =~ s/\s+$//;
1970 }
1971
Joe Hershberger05622192011-10-18 10:06:59 +00001972 $rpt_cleaners = 1;
1973 }
1974
Tom Rini6b9709d2014-02-27 08:27:28 -05001975# Check for FSF mailing addresses.
1976 if ($rawline =~ /\bwrite to the Free/i ||
1977 $rawline =~ /\b59\s+Temple\s+Pl/i ||
1978 $rawline =~ /\b51\s+Franklin\s+St/i) {
1979 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1980 my $msg_type = \&ERROR;
1981 $msg_type = \&CHK if ($file);
1982 &{$msg_type}("FSF_MAILING_ADDRESS",
1983 "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)
1984 }
1985
Joe Hershberger05622192011-10-18 10:06:59 +00001986# check for Kconfig help text having a real description
1987# Only applies when adding the entry originally, after that we do not have
1988# sufficient context to determine whether it is indeed long enough.
1989 if ($realfile =~ /Kconfig/ &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001990 $line =~ /.\s*config\s+/) {
Joe Hershberger05622192011-10-18 10:06:59 +00001991 my $length = 0;
1992 my $cnt = $realcnt;
1993 my $ln = $linenr + 1;
1994 my $f;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001995 my $is_start = 0;
Joe Hershberger05622192011-10-18 10:06:59 +00001996 my $is_end = 0;
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00001997 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
Joe Hershberger05622192011-10-18 10:06:59 +00001998 $f = $lines[$ln - 1];
1999 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2000 $is_end = $lines[$ln - 1] =~ /^\+/;
Joe Hershberger05622192011-10-18 10:06:59 +00002001
2002 next if ($f =~ /^-/);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002003
2004 if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) {
2005 $is_start = 1;
2006 } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) {
2007 $length = -1;
2008 }
2009
Joe Hershberger05622192011-10-18 10:06:59 +00002010 $f =~ s/^.//;
2011 $f =~ s/#.*//;
2012 $f =~ s/^\s+//;
2013 next if ($f =~ /^$/);
2014 if ($f =~ /^\s*config\s/) {
2015 $is_end = 1;
2016 last;
2017 }
2018 $length++;
2019 }
2020 WARN("CONFIG_DESCRIPTION",
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002021 "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);
2022 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
2023 }
2024
2025# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
2026 if ($realfile =~ /Kconfig/ &&
2027 $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
2028 WARN("CONFIG_EXPERIMENTAL",
2029 "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
2030 }
2031
2032 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2033 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2034 my $flag = $1;
2035 my $replacement = {
2036 'EXTRA_AFLAGS' => 'asflags-y',
2037 'EXTRA_CFLAGS' => 'ccflags-y',
2038 'EXTRA_CPPFLAGS' => 'cppflags-y',
2039 'EXTRA_LDFLAGS' => 'ldflags-y',
2040 };
2041
2042 WARN("DEPRECATED_VARIABLE",
2043 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
Joe Hershberger05622192011-10-18 10:06:59 +00002044 }
2045
Tom Rini6b9709d2014-02-27 08:27:28 -05002046# check for DT compatible documentation
2047 if (defined $root && $realfile =~ /\.dts/ &&
2048 $rawline =~ /^\+\s*compatible\s*=/) {
2049 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2050
2051 foreach my $compat (@compats) {
2052 my $compat2 = $compat;
2053 my $dt_path = $root . "/Documentation/devicetree/bindings/";
2054 $compat2 =~ s/\,[a-z]*\-/\,<\.\*>\-/;
2055 `grep -Erq "$compat|$compat2" $dt_path`;
2056 if ( $? >> 8 ) {
2057 WARN("UNDOCUMENTED_DT_STRING",
2058 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2059 }
2060
2061 my $vendor = $compat;
2062 my $vendor_path = $dt_path . "vendor-prefixes.txt";
2063 next if (! -f $vendor_path);
2064 $vendor =~ s/^([a-zA-Z0-9]+)\,.*/$1/;
2065 `grep -Eq "$vendor" $vendor_path`;
2066 if ( $? >> 8 ) {
2067 WARN("UNDOCUMENTED_DT_STRING",
2068 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vendor_path\n" . $herecurr);
2069 }
2070 }
2071 }
2072
Joe Hershberger05622192011-10-18 10:06:59 +00002073# check we are in a valid source file if not then ignore this hunk
2074 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
2075
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002076#line length limit
Joe Hershberger05622192011-10-18 10:06:59 +00002077 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
2078 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
2079 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
2080 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002081 $length > $max_line_length)
Joe Hershberger05622192011-10-18 10:06:59 +00002082 {
2083 WARN("LONG_LINE",
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002084 "line over $max_line_length characters\n" . $herecurr);
2085 }
2086
2087# Check for user-visible strings broken across lines, which breaks the ability
Tom Rini6b9709d2014-02-27 08:27:28 -05002088# to grep for the string. Make exceptions when the previous string ends in a
2089# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
2090# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002091 if ($line =~ /^\+\s*"/ &&
2092 $prevline =~ /"\s*$/ &&
Tom Rini6b9709d2014-02-27 08:27:28 -05002093 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002094 WARN("SPLIT_STRING",
2095 "quoted string split across lines\n" . $hereprev);
Joe Hershberger05622192011-10-18 10:06:59 +00002096 }
2097
2098# check for spaces before a quoted newline
2099 if ($rawline =~ /^.*\".*\s\\n/) {
Tom Rini6b9709d2014-02-27 08:27:28 -05002100 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
2101 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
2102 $fix) {
2103 $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
2104 }
2105
Joe Hershberger05622192011-10-18 10:06:59 +00002106 }
2107
2108# check for adding lines without a newline.
2109 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2110 WARN("MISSING_EOF_NEWLINE",
2111 "adding a line without newline at end of file\n" . $herecurr);
2112 }
2113
2114# Blackfin: use hi/lo macros
2115 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
2116 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
2117 my $herevet = "$here\n" . cat_vet($line) . "\n";
2118 ERROR("LO_MACRO",
2119 "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
2120 }
2121 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
2122 my $herevet = "$here\n" . cat_vet($line) . "\n";
2123 ERROR("HI_MACRO",
2124 "use the HI() macro, not (... >> 16)\n" . $herevet);
2125 }
2126 }
2127
2128# check we are in a valid source file C or perl if not then ignore this hunk
2129 next if ($realfile !~ /\.(h|c|pl)$/);
2130
2131# at the beginning of a line any tabs must come first and anything
2132# more than 8 must use tabs.
2133 if ($rawline =~ /^\+\s* \t\s*\S/ ||
2134 $rawline =~ /^\+\s* \s*/) {
2135 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Joe Hershberger05622192011-10-18 10:06:59 +00002136 $rpt_cleaners = 1;
Tom Rini6b9709d2014-02-27 08:27:28 -05002137 if (ERROR("CODE_INDENT",
2138 "code indent should use tabs where possible\n" . $herevet) &&
2139 $fix) {
2140 $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
2141 }
Joe Hershberger05622192011-10-18 10:06:59 +00002142 }
2143
2144# check for space before tabs.
2145 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
2146 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05002147 if (WARN("SPACE_BEFORE_TAB",
2148 "please, no space before tabs\n" . $herevet) &&
2149 $fix) {
2150 while ($fixed[$linenr - 1] =~
Joe Perchese3a4fac2014-09-23 12:41:02 +02002151 s/(^\+.*) {8,8}\t/$1\t\t/) {}
Tom Rini6b9709d2014-02-27 08:27:28 -05002152 while ($fixed[$linenr - 1] =~
2153 s/(^\+.*) +\t/$1\t/) {}
2154 }
Joe Hershberger05622192011-10-18 10:06:59 +00002155 }
2156
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002157# check for && or || at the start of a line
2158 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2159 CHK("LOGICAL_CONTINUATIONS",
2160 "Logical continuations should be on the previous line\n" . $hereprev);
2161 }
2162
2163# check multi-line statement indentation matches previous line
2164 if ($^V && $^V ge 5.10.0 &&
2165 $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
2166 $prevline =~ /^\+(\t*)(.*)$/;
2167 my $oldindent = $1;
2168 my $rest = $2;
2169
2170 my $pos = pos_last_openparen($rest);
2171 if ($pos >= 0) {
2172 $line =~ /^(\+| )([ \t]*)/;
2173 my $newindent = $2;
2174
2175 my $goodtabindent = $oldindent .
2176 "\t" x ($pos / 8) .
2177 " " x ($pos % 8);
2178 my $goodspaceindent = $oldindent . " " x $pos;
2179
2180 if ($newindent ne $goodtabindent &&
2181 $newindent ne $goodspaceindent) {
Tom Rini6b9709d2014-02-27 08:27:28 -05002182
2183 if (CHK("PARENTHESIS_ALIGNMENT",
2184 "Alignment should match open parenthesis\n" . $hereprev) &&
2185 $fix && $line =~ /^\+/) {
2186 $fixed[$linenr - 1] =~
2187 s/^\+[ \t]*/\+$goodtabindent/;
2188 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002189 }
2190 }
2191 }
2192
Tom Rini6b9709d2014-02-27 08:27:28 -05002193 if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
2194 if (CHK("SPACING",
2195 "No space is necessary after a cast\n" . $hereprev) &&
2196 $fix) {
2197 $fixed[$linenr - 1] =~
2198 s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
2199 }
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002200 }
2201
2202 if ($realfile =~ m@^(drivers/net/|net/)@ &&
Tom Rini6b9709d2014-02-27 08:27:28 -05002203 $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
2204 $rawline =~ /^\+[ \t]*\*/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002205 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2206 "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
2207 }
2208
2209 if ($realfile =~ m@^(drivers/net/|net/)@ &&
Tom Rini6b9709d2014-02-27 08:27:28 -05002210 $prevrawline =~ /^\+[ \t]*\/\*/ && #starting /*
2211 $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
2212 $rawline =~ /^\+/ && #line is new
2213 $rawline !~ /^\+[ \t]*\*/) { #no leading *
2214 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2215 "networking block comments start with * on subsequent lines\n" . $hereprev);
2216 }
2217
2218 if ($realfile =~ m@^(drivers/net/|net/)@ &&
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002219 $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
2220 $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
2221 $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
2222 $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
2223 WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2224 "networking block comments put the trailing */ on a separate line\n" . $herecurr);
2225 }
2226
Joe Hershberger05622192011-10-18 10:06:59 +00002227# check for spaces at the beginning of a line.
2228# Exceptions:
2229# 1) within comments
2230# 2) indented preprocessor commands
2231# 3) hanging labels
Tom Rini6b9709d2014-02-27 08:27:28 -05002232 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
Joe Hershberger05622192011-10-18 10:06:59 +00002233 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Tom Rini6b9709d2014-02-27 08:27:28 -05002234 if (WARN("LEADING_SPACE",
2235 "please, no spaces at the start of a line\n" . $herevet) &&
2236 $fix) {
2237 $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
2238 }
Joe Hershberger05622192011-10-18 10:06:59 +00002239 }
2240
2241# check we are in a valid C source file if not then ignore this hunk
2242 next if ($realfile !~ /\.(h|c)$/);
2243
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002244# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
2245 if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
2246 WARN("CONFIG_EXPERIMENTAL",
2247 "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
2248 }
2249
Joe Hershberger05622192011-10-18 10:06:59 +00002250# check for RCS/CVS revision markers
2251 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2252 WARN("CVS_KEYWORD",
2253 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2254 }
2255
2256# Blackfin: don't use __builtin_bfin_[cs]sync
2257 if ($line =~ /__builtin_bfin_csync/) {
2258 my $herevet = "$here\n" . cat_vet($line) . "\n";
2259 ERROR("CSYNC",
2260 "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
2261 }
2262 if ($line =~ /__builtin_bfin_ssync/) {
2263 my $herevet = "$here\n" . cat_vet($line) . "\n";
2264 ERROR("SSYNC",
2265 "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
2266 }
2267
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002268# check for old HOTPLUG __dev<foo> section markings
2269 if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
2270 WARN("HOTPLUG_SECTION",
2271 "Using $1 is unnecessary\n" . $herecurr);
2272 }
2273
Joe Hershberger05622192011-10-18 10:06:59 +00002274# Check for potential 'bare' types
2275 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
2276 $realline_next);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002277#print "LINE<$line>\n";
2278 if ($linenr >= $suppress_statement &&
Tom Rini6b9709d2014-02-27 08:27:28 -05002279 $realcnt && $sline =~ /.\s*\S/) {
Joe Hershberger05622192011-10-18 10:06:59 +00002280 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2281 ctx_statement_block($linenr, $realcnt, 0);
2282 $stat =~ s/\n./\n /g;
2283 $cond =~ s/\n./\n /g;
2284
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002285#print "linenr<$linenr> <$stat>\n";
2286 # If this statement has no statement boundaries within
2287 # it there is no point in retrying a statement scan
2288 # until we hit end of it.
2289 my $frag = $stat; $frag =~ s/;+\s*$//;
2290 if ($frag !~ /(?:{|;)/) {
2291#print "skip<$line_nr_next>\n";
2292 $suppress_statement = $line_nr_next;
2293 }
2294
Joe Hershberger05622192011-10-18 10:06:59 +00002295 # Find the real next line.
2296 $realline_next = $line_nr_next;
2297 if (defined $realline_next &&
2298 (!defined $lines[$realline_next - 1] ||
2299 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
2300 $realline_next++;
2301 }
2302
2303 my $s = $stat;
2304 $s =~ s/{.*$//s;
2305
2306 # Ignore goto labels.
2307 if ($s =~ /$Ident:\*$/s) {
2308
2309 # Ignore functions being called
2310 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2311
2312 } elsif ($s =~ /^.\s*else\b/s) {
2313
2314 # declarations always start with types
2315 } 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) {
2316 my $type = $1;
2317 $type =~ s/\s+/ /g;
2318 possible($type, "A:" . $s);
2319
2320 # definitions in global scope can only start with types
2321 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2322 possible($1, "B:" . $s);
2323 }
2324
2325 # any (foo ... *) is a pointer cast, and foo is a type
2326 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2327 possible($1, "C:" . $s);
2328 }
2329
2330 # Check for any sort of function declaration.
2331 # int foo(something bar, other baz);
2332 # void (*store_gdt)(x86_descr_ptr *);
2333 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
2334 my ($name_len) = length($1);
2335
2336 my $ctx = $s;
2337 substr($ctx, 0, $name_len + 1, '');
2338 $ctx =~ s/\)[^\)]*$//;
2339
2340 for my $arg (split(/\s*,\s*/, $ctx)) {
2341 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
2342
2343 possible($1, "D:" . $s);
2344 }
2345 }
2346 }
2347
2348 }
2349
2350#
2351# Checks which may be anchored in the context.
2352#
2353
2354# Check for switch () and associated case and default
2355# statements should be at the same indent.
2356 if ($line=~/\bswitch\s*\(.*\)/) {
2357 my $err = '';
2358 my $sep = '';
2359 my @ctx = ctx_block_outer($linenr, $realcnt);
2360 shift(@ctx);
2361 for my $ctx (@ctx) {
2362 my ($clen, $cindent) = line_stats($ctx);
2363 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
2364 $indent != $cindent) {
2365 $err .= "$sep$ctx\n";
2366 $sep = '';
2367 } else {
2368 $sep = "[...]\n";
2369 }
2370 }
2371 if ($err ne '') {
2372 ERROR("SWITCH_CASE_INDENT_LEVEL",
2373 "switch and case should be at the same indent\n$hereline$err");
2374 }
2375 }
2376
2377# if/while/etc brace do not go on next line, unless defining a do while loop,
2378# or if that brace on the next line is for something else
2379 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2380 my $pre_ctx = "$1$2";
2381
2382 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002383
2384 if ($line =~ /^\+\t{6,}/) {
2385 WARN("DEEP_INDENTATION",
2386 "Too many leading tabs - consider code refactoring\n" . $herecurr);
2387 }
2388
Joe Hershberger05622192011-10-18 10:06:59 +00002389 my $ctx_cnt = $realcnt - $#ctx - 1;
2390 my $ctx = join("\n", @ctx);
2391
2392 my $ctx_ln = $linenr;
2393 my $ctx_skip = $realcnt;
2394
2395 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2396 defined $lines[$ctx_ln - 1] &&
2397 $lines[$ctx_ln - 1] =~ /^-/)) {
2398 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2399 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2400 $ctx_ln++;
2401 }
2402
2403 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
2404 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2405
2406 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2407 ERROR("OPEN_BRACE",
2408 "that open brace { should be on the previous line\n" .
2409 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2410 }
2411 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2412 $ctx =~ /\)\s*\;\s*$/ &&
2413 defined $lines[$ctx_ln - 1])
2414 {
2415 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
2416 if ($nindent > $indent) {
2417 WARN("TRAILING_SEMICOLON",
2418 "trailing semicolon indicates no statements, indent implies otherwise\n" .
2419 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2420 }
2421 }
2422 }
2423
2424# Check relative indent for conditionals and blocks.
2425 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
Kim Phillipsd45a6ae2013-02-28 12:53:52 +00002426 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2427 ctx_statement_block($linenr, $realcnt, 0)
2428 if (!defined $stat);
Joe Hershberger05622192011-10-18 10:06:59 +00002429 my ($s, $c) = ($stat, $cond);
2430
2431 substr($s, 0, length($c), '');
2432
2433 # Make sure we remove the line prefixes as we have
2434 # none on the first line, and are going to readd them
2435 # where necessary.
2436 $s =~ s/\n./\n/gs;
2437
2438 # Find out how long the conditional actually is.
2439 my @newlines = ($c =~ /\n/gs);
2440 my $cond_lines = 1 + $#newlines;
2441
2442 # We want to check the first line inside the block
2443 # starting at the end of the conditional, so remove:
2444 # 1) any blank line termination
2445 # 2) any opening brace { on end of the line
2446 # 3) any do (...) {
2447 my $continuation = 0;
2448 my $check = 0;
2449 $s =~ s/^.*\bdo\b//;
2450 $s =~ s/^\s*{//;
2451 if ($s =~ s/^\s*\\//) {
2452 $continuation = 1;
2453 }
2454 if ($s =~ s/^\s*?\n//) {
2455 $check = 1;
2456 $cond_lines++;
2457 }
2458
2459 # Also ignore a loop construct at the end of a
2460 # preprocessor statement.
2461 if (($prevline =~ /^.\s*#\s*define\s/ ||
2462 $prevline =~ /\\\s*$/) && $continuation == 0) {
2463 $check = 0;
2464 }
2465
2466 my $cond_ptr = -1;
2467 $continuation = 0;
2468 while ($cond_ptr != $cond_lines) {
2469 $cond_ptr = $cond_lines;
2470
2471 # If we see an #else/#elif then the code
2472 # is not linear.
2473 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2474 $check = 0;
2475 }
2476
2477 # Ignore:
2478 # 1) blank lines, they should be at 0,
2479 # 2) preprocessor lines, and
2480 # 3) labels.
2481 if ($continuation ||
2482 $s =~ /^\s*?\n/ ||
2483