wmaker: fix possible buffer overrun with filename for Icon Chooser (Coverity #50218)
[wmaker-crm.git] / checkpatch.pl
blobedbfa6b1533301ccb608ba09b7379bcd5ca0a187
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
8 use strict;
9 use POSIX;
11 my $P = $0;
12 $P =~ s@.*/@@g;
14 my $V = '0.32';
16 use Getopt::Long qw(:config no_auto_abbrev);
18 my $quiet = 0;
19 my $chk_patch = 1;
20 my $tst_only;
21 my $emacs = 0;
22 my $terse = 0;
23 my $file = 0;
24 my $check = 0;
25 my $summary = 1;
26 my $mailback = 0;
27 my $summary_file = 0;
28 my $show_types = 0;
29 my $fix = 0;
30 my $fix_inplace = 0;
31 my $root;
32 my %debug;
33 my %camelcase = ();
34 my %use_type = ();
35 my @use = ();
36 my %ignore_type = ();
37 my @ignore = ();
38 my $help = 0;
39 my $configuration_file = ".checkpatch.conf";
40 my $max_line_length = 115;
41 my $ignore_perl_version = 0;
42 my $minimum_perl_version = 5.10.0;
44 sub help {
45 my ($exitcode) = @_;
47 print << "EOM";
48 Usage: $P [OPTION]... [FILE]...
49 Version: $V
51 Options:
52 -q, --quiet quiet
53 --patch treat FILE as patchfile (default)
54 --emacs emacs compile window format
55 --terse one line per report
56 -f, --file treat FILE as regular source file
57 --subjective, --strict enable more subjective tests
58 --types TYPE(,TYPE2...) show only these comma separated message types
59 --ignore TYPE(,TYPE2...) ignore various comma separated message types
60 --max-line-length=n set the maximum line length, if exceeded, warn
61 --show-types show the message "types" in the output
62 --root=PATH PATH to the kernel tree root
63 --no-summary suppress the per-file summary
64 --mailback only produce a report in case of warnings/errors
65 --summary-file include the filename in summary
66 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
67 'values', 'possible', 'type', and 'attr' (default
68 is all off)
69 --test-only=WORD report only warnings/errors containing WORD
70 literally
71 --fix EXPERIMENTAL - may create horrible results
72 If correctable single-line errors exist, create
73 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
74 with potential errors corrected to the preferred
75 checkpatch style
76 --fix-inplace EXPERIMENTAL - may create horrible results
77 Is the same as --fix, but overwrites the input
78 file. It's your fault if there's no backup or git
79 --ignore-perl-version override checking of perl version. expect
80 runtime errors.
81 -h, --help, --version display this help and exit
83 When FILE is - read standard input.
84 EOM
86 exit($exitcode);
89 my $conf = which_conf($configuration_file);
90 if (-f $conf) {
91 my @conf_args;
92 open(my $conffile, '<', "$conf")
93 or warn "$P: Can't find a readable $configuration_file file $!\n";
95 while (<$conffile>) {
96 my $line = $_;
98 $line =~ s/\s*\n?$//g;
99 $line =~ s/^\s*//g;
100 $line =~ s/\s+/ /g;
102 next if ($line =~ m/^\s*#/);
103 next if ($line =~ m/^\s*$/);
105 my @words = split(" ", $line);
106 foreach my $word (@words) {
107 last if ($word =~ m/^#/);
108 push (@conf_args, $word);
111 close($conffile);
112 unshift(@ARGV, @conf_args) if @conf_args;
115 GetOptions(
116 'q|quiet+' => \$quiet,
117 'patch!' => \$chk_patch,
118 'emacs!' => \$emacs,
119 'terse!' => \$terse,
120 'f|file!' => \$file,
121 'subjective!' => \$check,
122 'strict!' => \$check,
123 'ignore=s' => \@ignore,
124 'types=s' => \@use,
125 'show-types!' => \$show_types,
126 'max-line-length=i' => \$max_line_length,
127 'root=s' => \$root,
128 'summary!' => \$summary,
129 'mailback!' => \$mailback,
130 'summary-file!' => \$summary_file,
131 'fix!' => \$fix,
132 'fix-inplace!' => \$fix_inplace,
133 'ignore-perl-version!' => \$ignore_perl_version,
134 'debug=s' => \%debug,
135 'test-only=s' => \$tst_only,
136 'h|help' => \$help,
137 'version' => \$help
138 ) or help(1);
140 help(0) if ($help);
142 $fix = 1 if ($fix_inplace);
144 my $exit = 0;
146 if ($^V && $^V lt $minimum_perl_version) {
147 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
148 if (!$ignore_perl_version) {
149 exit(1);
153 if ($#ARGV < 0) {
154 print "$P: no input files\n";
155 exit(1);
158 sub hash_save_array_words {
159 my ($hashRef, $arrayRef) = @_;
161 my @array = split(/,/, join(',', @$arrayRef));
162 foreach my $word (@array) {
163 $word =~ s/\s*\n?$//g;
164 $word =~ s/^\s*//g;
165 $word =~ s/\s+/ /g;
166 $word =~ tr/[a-z]/[A-Z]/;
168 next if ($word =~ m/^\s*#/);
169 next if ($word =~ m/^\s*$/);
171 $hashRef->{$word}++;
175 sub hash_show_words {
176 my ($hashRef, $prefix) = @_;
178 if ($quiet == 0 && keys %$hashRef) {
179 print "NOTE: $prefix message types:";
180 foreach my $word (sort keys %$hashRef) {
181 print " $word";
183 print "\n\n";
187 hash_save_array_words(\%ignore_type, \@ignore);
188 hash_save_array_words(\%use_type, \@use);
190 my $dbg_values = 0;
191 my $dbg_possible = 0;
192 my $dbg_type = 0;
193 my $dbg_attr = 0;
194 for my $key (keys %debug) {
195 ## no critic
196 eval "\${dbg_$key} = '$debug{$key}';";
197 die "$@" if ($@);
200 my $rpt_cleaners = 0;
202 if ($terse) {
203 $emacs = 1;
204 $quiet++;
207 my $emitted_corrupt = 0;
209 our $Ident = qr{
210 [A-Za-z_][A-Za-z\d_]*
211 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
213 our $Storage = qr{extern|static|asmlinkage};
214 our $Sparse = qr{
215 __user|
216 __kernel|
217 __force|
218 __iomem|
219 __must_check|
220 __init_refok|
221 __kprobes|
222 __ref|
223 __rcu
225 our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
226 our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
227 our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
228 our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
229 our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
231 # Notes to $Attribute:
232 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
233 our $Attribute = qr{
234 const|
235 __percpu|
236 __nocast|
237 __safe|
238 __bitwise__|
239 __packed__|
240 __packed2__|
241 __naked|
242 __maybe_unused|
243 __always_unused|
244 __noreturn|
245 __used|
246 __cold|
247 __noclone|
248 __deprecated|
249 __read_mostly|
250 __kprobes|
251 $InitAttribute|
252 ____cacheline_aligned|
253 ____cacheline_aligned_in_smp|
254 ____cacheline_internodealigned_in_smp|
255 __weak
257 our $Modifier;
258 our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
259 our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
260 our $Lval = qr{$Ident(?:$Member)*};
262 our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
263 our $Binary = qr{(?i)0b[01]+$Int_type?};
264 our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
265 our $Int = qr{[0-9]+$Int_type?};
266 our $Octal = qr{0[0-7]+$Int_type?};
267 our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
268 our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
269 our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
270 our $Float = qr{$Float_hex|$Float_dec|$Float_int};
271 our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
272 our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
273 our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
274 our $Arithmetic = qr{\+|-|\*|\/|%};
275 our $Operators = qr{
276 <=|>=|==|!=|
277 =>|->|<<|>>|<|>|!|~|
278 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
281 our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
283 our $NonptrType;
284 our $NonptrTypeWithAttr;
285 our $Type;
286 our $Declare;
288 our $NON_ASCII_UTF8 = qr{
289 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
290 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
291 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
292 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
293 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
294 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
295 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
298 our $UTF8 = qr{
299 [\x09\x0A\x0D\x20-\x7E] # ASCII
300 | $NON_ASCII_UTF8
303 our $typeTypedefs = qr{(?x:
304 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
305 atomic_t
308 our $logFunctions = qr{(?x:
309 printk(?:_ratelimited|_once|)|
310 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
311 WARN(?:_RATELIMIT|_ONCE|)|
312 panic|
313 MODULE_[A-Z_]+|
314 seq_vprintf|seq_printf|seq_puts
317 our $signature_tags = qr{(?xi:
318 Signed-off-by:|
319 Acked-by:|
320 Tested-by:|
321 Reviewed-by:|
322 Reported-by:|
323 Suggested-by:|
324 To:|
328 our @typeList = (
329 qr{void},
330 qr{(?:unsigned\s+)?char},
331 qr{(?:unsigned\s+)?short},
332 qr{(?:unsigned\s+)?int},
333 qr{(?:unsigned\s+)?long},
334 qr{(?:unsigned\s+)?long\s+int},
335 qr{(?:unsigned\s+)?long\s+long},
336 qr{(?:unsigned\s+)?long\s+long\s+int},
337 qr{unsigned},
338 qr{float},
339 qr{double},
340 qr{bool},
341 qr{struct\s+$Ident},
342 qr{union\s+$Ident},
343 qr{enum\s+$Ident},
344 qr{${Ident}_t},
345 qr{${Ident}_handler},
346 qr{${Ident}_handler_fn},
348 our @typeListWithAttr = (
349 @typeList,
350 qr{struct\s+$InitAttribute\s+$Ident},
351 qr{union\s+$InitAttribute\s+$Ident},
354 our @modifierList = (
355 qr{fastcall},
358 our @mode_permission_funcs = (
359 ["module_param", 3],
360 ["module_param_(?:array|named|string)", 4],
361 ["module_param_array_named", 5],
362 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
363 ["proc_create(?:_data|)", 2],
364 ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2],
367 #Create a search pattern for all these functions to speed up a loop below
368 our $mode_perms_search = "";
369 foreach my $entry (@mode_permission_funcs) {
370 $mode_perms_search .= '|' if ($mode_perms_search ne "");
371 $mode_perms_search .= $entry->[0];
374 our $allowed_asm_includes = qr{(?x:
375 irq|
376 memory
378 # memory.h: ARM has a custom one
380 sub build_types {
381 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
382 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
383 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
384 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
385 $NonptrType = qr{
386 (?:$Modifier\s+|const\s+)*
388 (?:typeof|__typeof__)\s*\([^\)]*\)|
389 (?:$typeTypedefs\b)|
390 (?:${all}\b)
392 (?:\s+$Modifier|\s+const)*
394 $NonptrTypeWithAttr = qr{
395 (?:$Modifier\s+|const\s+)*
397 (?:typeof|__typeof__)\s*\([^\)]*\)|
398 (?:$typeTypedefs\b)|
399 (?:${allWithAttr}\b)
401 (?:\s+$Modifier|\s+const)*
403 $Type = qr{
404 $NonptrType
405 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
406 (?:\s+$Inline|\s+$Modifier)*
408 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
410 build_types();
412 our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
414 # Using $balanced_parens, $LvalOrFunc, or $FuncArg
415 # requires at least perl version v5.10.0
416 # Any use must be runtime checked with $^V
418 our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
419 our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
420 our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
422 sub deparenthesize {
423 my ($string) = @_;
424 return "" if (!defined($string));
426 while ($string =~ /^\s*\(.*\)\s*$/) {
427 $string =~ s@^\s*\(\s*@@;
428 $string =~ s@\s*\)\s*$@@;
431 $string =~ s@\s+@ @g;
433 return $string;
436 sub seed_camelcase_file {
437 my ($file) = @_;
439 return if (!(-f $file));
441 local $/;
443 open(my $include_file, '<', "$file")
444 or warn "$P: Can't read '$file' $!\n";
445 my $text = <$include_file>;
446 close($include_file);
448 my @lines = split('\n', $text);
450 foreach my $line (@lines) {
451 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
452 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
453 $camelcase{$1} = 1;
454 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
455 $camelcase{$1} = 1;
456 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
457 $camelcase{$1} = 1;
462 my $camelcase_seeded = 0;
463 sub seed_camelcase_includes {
464 return if ($camelcase_seeded);
466 my $files;
467 my $camelcase_cache = "";
468 my @include_files = ();
470 $camelcase_seeded = 1;
472 if (-e ".git") {
473 my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
474 chomp $git_last_include_commit;
475 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
476 } else {
477 my $last_mod_date = 0;
478 $files = `find $root/include -name "*.h"`;
479 @include_files = split('\n', $files);
480 foreach my $file (@include_files) {
481 my $date = POSIX::strftime("%Y%m%d%H%M",
482 localtime((stat $file)[9]));
483 $last_mod_date = $date if ($last_mod_date < $date);
485 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
488 if ($camelcase_cache ne "" && -f $camelcase_cache) {
489 open(my $camelcase_file, '<', "$camelcase_cache")
490 or warn "$P: Can't read '$camelcase_cache' $!\n";
491 while (<$camelcase_file>) {
492 chomp;
493 $camelcase{$_} = 1;
495 close($camelcase_file);
497 return;
500 if (-e ".git") {
501 $files = `git ls-files "include/*.h"`;
502 @include_files = split('\n', $files);
505 foreach my $file (@include_files) {
506 seed_camelcase_file($file);
509 if ($camelcase_cache ne "") {
510 unlink glob ".checkpatch-camelcase.*";
511 open(my $camelcase_file, '>', "$camelcase_cache")
512 or warn "$P: Can't write '$camelcase_cache' $!\n";
513 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
514 print $camelcase_file ("$_\n");
516 close($camelcase_file);
520 my @rawlines = ();
521 my @lines = ();
522 my @fixed = ();
523 my $vname;
524 for my $filename (@ARGV) {
525 my $FILE;
526 if ($file) {
527 open($FILE, '-|', "diff -u /dev/null $filename") ||
528 die "$P: $filename: diff failed - $!\n";
529 } elsif ($filename eq '-') {
530 open($FILE, '<&STDIN');
531 } else {
532 open($FILE, '<', "$filename") ||
533 die "$P: $filename: open failed - $!\n";
535 if ($filename eq '-') {
536 $vname = 'Your patch';
537 } else {
538 $vname = $filename;
540 while (<$FILE>) {
541 chomp;
542 push(@rawlines, $_);
544 close($FILE);
545 if (!process($filename)) {
546 $exit = 1;
548 @rawlines = ();
549 @lines = ();
550 @fixed = ();
553 exit($exit);
555 sub parse_email {
556 my ($formatted_email) = @_;
558 my $name = "";
559 my $address = "";
560 my $comment = "";
562 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
563 $name = $1;
564 $address = $2;
565 $comment = $3 if defined $3;
566 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
567 $address = $1;
568 $comment = $2 if defined $2;
569 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
570 $address = $1;
571 $comment = $2 if defined $2;
572 $formatted_email =~ s/$address.*$//;
573 $name = $formatted_email;
574 $name = trim($name);
575 $name =~ s/^\"|\"$//g;
576 # If there's a name left after stripping spaces and
577 # leading quotes, and the address doesn't have both
578 # leading and trailing angle brackets, the address
579 # is invalid. ie:
580 # "joe smith joe@smith.com" bad
581 # "joe smith <joe@smith.com" bad
582 if ($name ne "" && $address !~ /^<[^>]+>$/) {
583 $name = "";
584 $address = "";
585 $comment = "";
589 $name = trim($name);
590 $name =~ s/^\"|\"$//g;
591 $address = trim($address);
592 $address =~ s/^\<|\>$//g;
594 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
595 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
596 $name = "\"$name\"";
599 return ($name, $address, $comment);
602 sub format_email {
603 my ($name, $address) = @_;
605 my $formatted_email;
607 $name = trim($name);
608 $name =~ s/^\"|\"$//g;
609 $address = trim($address);
611 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
612 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
613 $name = "\"$name\"";
616 if ("$name" eq "") {
617 $formatted_email = "$address";
618 } else {
619 $formatted_email = "$name <$address>";
622 return $formatted_email;
625 sub which_conf {
626 my ($conf) = @_;
628 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
629 if (-e "$path/$conf") {
630 return "$path/$conf";
634 return "";
637 sub expand_tabs {
638 my ($str) = @_;
640 my $res = '';
641 my $n = 0;
642 for my $c (split(//, $str)) {
643 if ($c eq "\t") {
644 $res .= ' ';
645 $n++;
646 for (; ($n % 8) != 0; $n++) {
647 $res .= ' ';
649 next;
651 $res .= $c;
652 $n++;
655 return $res;
657 sub copy_spacing {
658 (my $res = shift) =~ tr/\t/ /c;
659 return $res;
662 sub line_stats {
663 my ($line) = @_;
665 # Drop the diff line leader and expand tabs
666 $line =~ s/^.//;
667 $line = expand_tabs($line);
669 # Pick the indent from the front of the line.
670 my ($white) = ($line =~ /^(\s*)/);
672 return (length($line), length($white));
675 my $sanitise_quote = '';
677 sub sanitise_line_reset {
678 my ($in_comment) = @_;
680 if ($in_comment) {
681 $sanitise_quote = '*/';
682 } else {
683 $sanitise_quote = '';
686 sub sanitise_line {
687 my ($line) = @_;
689 my $res = '';
690 my $l = '';
692 my $qlen = 0;
693 my $off = 0;
694 my $c;
696 # Always copy over the diff marker.
697 $res = substr($line, 0, 1);
699 for ($off = 1; $off < length($line); $off++) {
700 $c = substr($line, $off, 1);
702 # Comments we are wacking completly including the begin
703 # and end, all to $;.
704 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
705 $sanitise_quote = '*/';
707 substr($res, $off, 2, "$;$;");
708 $off++;
709 next;
711 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
712 $sanitise_quote = '';
713 substr($res, $off, 2, "$;$;");
714 $off++;
715 next;
717 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
718 $sanitise_quote = '//';
720 substr($res, $off, 2, $sanitise_quote);
721 $off++;
722 next;
725 # A \ in a string means ignore the next character.
726 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
727 $c eq "\\") {
728 substr($res, $off, 2, 'XX');
729 $off++;
730 next;
732 # Regular quotes.
733 if ($c eq "'" || $c eq '"') {
734 if ($sanitise_quote eq '') {
735 $sanitise_quote = $c;
737 substr($res, $off, 1, $c);
738 next;
739 } elsif ($sanitise_quote eq $c) {
740 $sanitise_quote = '';
744 #print "c<$c> SQ<$sanitise_quote>\n";
745 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
746 substr($res, $off, 1, $;);
747 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
748 substr($res, $off, 1, $;);
749 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
750 substr($res, $off, 1, 'X');
751 } else {
752 substr($res, $off, 1, $c);
756 if ($sanitise_quote eq '//') {
757 $sanitise_quote = '';
760 # The pathname on a #include may be surrounded by '<' and '>'.
761 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
762 my $clean = 'X' x length($1);
763 $res =~ s@\<.*\>@<$clean>@;
765 # The whole of a #error is a string.
766 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
767 my $clean = 'X' x length($1);
768 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
771 return $res;
774 sub get_quoted_string {
775 my ($line, $rawline) = @_;
777 return "" if ($line !~ m/(\"[X]+\")/g);
778 return substr($rawline, $-[0], $+[0] - $-[0]);
781 sub ctx_statement_block {
782 my ($linenr, $remain, $off) = @_;
783 my $line = $linenr - 1;
784 my $blk = '';
785 my $soff = $off;
786 my $coff = $off - 1;
787 my $coff_set = 0;
789 my $loff = 0;
791 my $type = '';
792 my $level = 0;
793 my @stack = ();
794 my $p;
795 my $c;
796 my $len = 0;
798 my $remainder;
799 while (1) {
800 @stack = (['', 0]) if ($#stack == -1);
802 #warn "CSB: blk<$blk> remain<$remain>\n";
803 # If we are about to drop off the end, pull in more
804 # context.
805 if ($off >= $len) {
806 for (; $remain > 0; $line++) {
807 last if (!defined $lines[$line]);
808 next if ($lines[$line] =~ /^-/);
809 $remain--;
810 $loff = $len;
811 $blk .= $lines[$line] . "\n";
812 $len = length($blk);
813 $line++;
814 last;
816 # Bail if there is no further context.
817 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
818 if ($off >= $len) {
819 last;
821 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
822 $level++;
823 $type = '#';
826 $p = $c;
827 $c = substr($blk, $off, 1);
828 $remainder = substr($blk, $off);
830 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
832 # Handle nested #if/#else.
833 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
834 push(@stack, [ $type, $level ]);
835 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
836 ($type, $level) = @{$stack[$#stack - 1]};
837 } elsif ($remainder =~ /^#\s*endif\b/) {
838 ($type, $level) = @{pop(@stack)};
841 # Statement ends at the ';' or a close '}' at the
842 # outermost level.
843 if ($level == 0 && $c eq ';') {
844 last;
847 # An else is really a conditional as long as its not else if
848 if ($level == 0 && $coff_set == 0 &&
849 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
850 $remainder =~ /^(else)(?:\s|{)/ &&
851 $remainder !~ /^else\s+if\b/) {
852 $coff = $off + length($1) - 1;
853 $coff_set = 1;
854 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
855 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
858 if (($type eq '' || $type eq '(') && $c eq '(') {
859 $level++;
860 $type = '(';
862 if ($type eq '(' && $c eq ')') {
863 $level--;
864 $type = ($level != 0)? '(' : '';
866 if ($level == 0 && $coff < $soff) {
867 $coff = $off;
868 $coff_set = 1;
869 #warn "CSB: mark coff<$coff>\n";
872 if (($type eq '' || $type eq '{') && $c eq '{') {
873 $level++;
874 $type = '{';
876 if ($type eq '{' && $c eq '}') {
877 $level--;
878 $type = ($level != 0)? '{' : '';
880 if ($level == 0) {
881 if (substr($blk, $off + 1, 1) eq ';') {
882 $off++;
884 last;
887 # Preprocessor commands end at the newline unless escaped.
888 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
889 $level--;
890 $type = '';
891 $off++;
892 last;
894 $off++;
896 # We are truly at the end, so shuffle to the next line.
897 if ($off == $len) {
898 $loff = $len + 1;
899 $line++;
900 $remain--;
903 my $statement = substr($blk, $soff, $off - $soff + 1);
904 my $condition = substr($blk, $soff, $coff - $soff + 1);
906 #warn "STATEMENT<$statement>\n";
907 #warn "CONDITION<$condition>\n";
909 #print "coff<$coff> soff<$off> loff<$loff>\n";
911 return ($statement, $condition,
912 $line, $remain + 1, $off - $loff + 1, $level);
915 sub statement_lines {
916 my ($stmt) = @_;
918 # Strip the diff line prefixes and rip blank lines at start and end.
919 $stmt =~ s/(^|\n)./$1/g;
920 $stmt =~ s/^\s*//;
921 $stmt =~ s/\s*$//;
923 my @stmt_lines = ($stmt =~ /\n/g);
925 return $#stmt_lines + 2;
928 sub statement_rawlines {
929 my ($stmt) = @_;
931 my @stmt_lines = ($stmt =~ /\n/g);
933 return $#stmt_lines + 2;
936 sub statement_block_size {
937 my ($stmt) = @_;
939 $stmt =~ s/(^|\n)./$1/g;
940 $stmt =~ s/^\s*{//;
941 $stmt =~ s/}\s*$//;
942 $stmt =~ s/^\s*//;
943 $stmt =~ s/\s*$//;
945 my @stmt_lines = ($stmt =~ /\n/g);
946 my @stmt_statements = ($stmt =~ /;/g);
948 my $stmt_lines = $#stmt_lines + 2;
949 my $stmt_statements = $#stmt_statements + 1;
951 if ($stmt_lines > $stmt_statements) {
952 return $stmt_lines;
953 } else {
954 return $stmt_statements;
958 sub ctx_statement_full {
959 my ($linenr, $remain, $off) = @_;
960 my ($statement, $condition, $level);
962 my (@chunks);
964 # Grab the first conditional/block pair.
965 ($statement, $condition, $linenr, $remain, $off, $level) =
966 ctx_statement_block($linenr, $remain, $off);
967 #print "F: c<$condition> s<$statement> remain<$remain>\n";
968 push(@chunks, [ $condition, $statement ]);
969 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
970 return ($level, $linenr, @chunks);
973 # Pull in the following conditional/block pairs and see if they
974 # could continue the statement.
975 for (;;) {
976 ($statement, $condition, $linenr, $remain, $off, $level) =
977 ctx_statement_block($linenr, $remain, $off);
978 #print "C: c<$condition> s<$statement> remain<$remain>\n";
979 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
980 #print "C: push\n";
981 push(@chunks, [ $condition, $statement ]);
984 return ($level, $linenr, @chunks);
987 sub ctx_block_get {
988 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
989 my $line;
990 my $start = $linenr - 1;
991 my $blk = '';
992 my @o;
993 my @c;
994 my @res = ();
996 my $level = 0;
997 my @stack = ($level);
998 for ($line = $start; $remain > 0; $line++) {
999 next if ($rawlines[$line] =~ /^-/);
1000 $remain--;
1002 $blk .= $rawlines[$line];
1004 # Handle nested #if/#else.
1005 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1006 push(@stack, $level);
1007 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1008 $level = $stack[$#stack - 1];
1009 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1010 $level = pop(@stack);
1013 foreach my $c (split(//, $lines[$line])) {
1014 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1015 if ($off > 0) {
1016 $off--;
1017 next;
1020 if ($c eq $close && $level > 0) {
1021 $level--;
1022 last if ($level == 0);
1023 } elsif ($c eq $open) {
1024 $level++;
1028 if (!$outer || $level <= 1) {
1029 push(@res, $rawlines[$line]);
1032 last if ($level == 0);
1035 return ($level, @res);
1037 sub ctx_block_outer {
1038 my ($linenr, $remain) = @_;
1040 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1041 return @r;
1043 sub ctx_block {
1044 my ($linenr, $remain) = @_;
1046 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1047 return @r;
1049 sub ctx_statement {
1050 my ($linenr, $remain, $off) = @_;
1052 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1053 return @r;
1055 sub ctx_block_level {
1056 my ($linenr, $remain) = @_;
1058 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1060 sub ctx_statement_level {
1061 my ($linenr, $remain, $off) = @_;
1063 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1066 sub ctx_locate_comment {
1067 my ($first_line, $end_line) = @_;
1069 # Catch a comment on the end of the line itself.
1070 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1071 return $current_comment if (defined $current_comment);
1073 # Look through the context and try and figure out if there is a
1074 # comment.
1075 my $in_comment = 0;
1076 $current_comment = '';
1077 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1078 my $line = $rawlines[$linenr - 1];
1079 #warn " $line\n";
1080 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1081 $in_comment = 1;
1083 if ($line =~ m@/\*@) {
1084 $in_comment = 1;
1086 if (!$in_comment && $current_comment ne '') {
1087 $current_comment = '';
1089 $current_comment .= $line . "\n" if ($in_comment);
1090 if ($line =~ m@\*/@) {
1091 $in_comment = 0;
1095 chomp($current_comment);
1096 return($current_comment);
1098 sub ctx_has_comment {
1099 my ($first_line, $end_line) = @_;
1100 my $cmt = ctx_locate_comment($first_line, $end_line);
1102 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1103 ##print "CMMT: $cmt\n";
1105 return ($cmt ne '');
1108 sub raw_line {
1109 my ($linenr, $cnt) = @_;
1111 my $offset = $linenr - 1;
1112 $cnt++;
1114 my $line;
1115 while ($cnt) {
1116 $line = $rawlines[$offset++];
1117 next if (defined($line) && $line =~ /^-/);
1118 $cnt--;
1121 return $line;
1124 sub cat_vet {
1125 my ($vet) = @_;
1126 my ($res, $coded);
1128 $res = '';
1129 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1130 $res .= $1;
1131 if ($2 ne '') {
1132 $coded = sprintf("^%c", unpack('C', $2) + 64);
1133 $res .= $coded;
1136 $res =~ s/$/\$/;
1138 return $res;
1141 my $av_preprocessor = 0;
1142 my $av_pending;
1143 my @av_paren_type;
1144 my $av_pend_colon;
1146 sub annotate_reset {
1147 $av_preprocessor = 0;
1148 $av_pending = '_';
1149 @av_paren_type = ('E');
1150 $av_pend_colon = 'O';
1153 sub annotate_values {
1154 my ($stream, $type) = @_;
1156 my $res;
1157 my $var = '_' x length($stream);
1158 my $cur = $stream;
1160 print "$stream\n" if ($dbg_values > 1);
1162 while (length($cur)) {
1163 @av_paren_type = ('E') if ($#av_paren_type < 0);
1164 print " <" . join('', @av_paren_type) .
1165 "> <$type> <$av_pending>" if ($dbg_values > 1);
1166 if ($cur =~ /^(\s+)/o) {
1167 print "WS($1)\n" if ($dbg_values > 1);
1168 if ($1 =~ /\n/ && $av_preprocessor) {
1169 $type = pop(@av_paren_type);
1170 $av_preprocessor = 0;
1173 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1174 print "CAST($1)\n" if ($dbg_values > 1);
1175 push(@av_paren_type, $type);
1176 $type = 'c';
1178 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1179 print "DECLARE($1)\n" if ($dbg_values > 1);
1180 $type = 'T';
1182 } elsif ($cur =~ /^($Modifier)\s*/) {
1183 print "MODIFIER($1)\n" if ($dbg_values > 1);
1184 $type = 'T';
1186 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1187 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1188 $av_preprocessor = 1;
1189 push(@av_paren_type, $type);
1190 if ($2 ne '') {
1191 $av_pending = 'N';
1193 $type = 'E';
1195 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1196 print "UNDEF($1)\n" if ($dbg_values > 1);
1197 $av_preprocessor = 1;
1198 push(@av_paren_type, $type);
1200 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1201 print "PRE_START($1)\n" if ($dbg_values > 1);
1202 $av_preprocessor = 1;
1204 push(@av_paren_type, $type);
1205 push(@av_paren_type, $type);
1206 $type = 'E';
1208 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1209 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1210 $av_preprocessor = 1;
1212 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1214 $type = 'E';
1216 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1217 print "PRE_END($1)\n" if ($dbg_values > 1);
1219 $av_preprocessor = 1;
1221 # Assume all arms of the conditional end as this
1222 # one does, and continue as if the #endif was not here.
1223 pop(@av_paren_type);
1224 push(@av_paren_type, $type);
1225 $type = 'E';
1227 } elsif ($cur =~ /^(\\\n)/o) {
1228 print "PRECONT($1)\n" if ($dbg_values > 1);
1230 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1231 print "ATTR($1)\n" if ($dbg_values > 1);
1232 $av_pending = $type;
1233 $type = 'N';
1235 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1236 print "SIZEOF($1)\n" if ($dbg_values > 1);
1237 if (defined $2) {
1238 $av_pending = 'V';
1240 $type = 'N';
1242 } elsif ($cur =~ /^(if|while|for)\b/o) {
1243 print "COND($1)\n" if ($dbg_values > 1);
1244 $av_pending = 'E';
1245 $type = 'N';
1247 } elsif ($cur =~/^(case)/o) {
1248 print "CASE($1)\n" if ($dbg_values > 1);
1249 $av_pend_colon = 'C';
1250 $type = 'N';
1252 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1253 print "KEYWORD($1)\n" if ($dbg_values > 1);
1254 $type = 'N';
1256 } elsif ($cur =~ /^(\()/o) {
1257 print "PAREN('$1')\n" if ($dbg_values > 1);
1258 push(@av_paren_type, $av_pending);
1259 $av_pending = '_';
1260 $type = 'N';
1262 } elsif ($cur =~ /^(\))/o) {
1263 my $new_type = pop(@av_paren_type);
1264 if ($new_type ne '_') {
1265 $type = $new_type;
1266 print "PAREN('$1') -> $type\n"
1267 if ($dbg_values > 1);
1268 } else {
1269 print "PAREN('$1')\n" if ($dbg_values > 1);
1272 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1273 print "FUNC($1)\n" if ($dbg_values > 1);
1274 $type = 'V';
1275 $av_pending = 'V';
1277 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1278 if (defined $2 && $type eq 'C' || $type eq 'T') {
1279 $av_pend_colon = 'B';
1280 } elsif ($type eq 'E') {
1281 $av_pend_colon = 'L';
1283 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1284 $type = 'V';
1286 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1287 print "IDENT($1)\n" if ($dbg_values > 1);
1288 $type = 'V';
1290 } elsif ($cur =~ /^($Assignment)/o) {
1291 print "ASSIGN($1)\n" if ($dbg_values > 1);
1292 $type = 'N';
1294 } elsif ($cur =~/^(;|{|})/) {
1295 print "END($1)\n" if ($dbg_values > 1);
1296 $type = 'E';
1297 $av_pend_colon = 'O';
1299 } elsif ($cur =~/^(,)/) {
1300 print "COMMA($1)\n" if ($dbg_values > 1);
1301 $type = 'C';
1303 } elsif ($cur =~ /^(\?)/o) {
1304 print "QUESTION($1)\n" if ($dbg_values > 1);
1305 $type = 'N';
1307 } elsif ($cur =~ /^(:)/o) {
1308 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1310 substr($var, length($res), 1, $av_pend_colon);
1311 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1312 $type = 'E';
1313 } else {
1314 $type = 'N';
1316 $av_pend_colon = 'O';
1318 } elsif ($cur =~ /^(\[)/o) {
1319 print "CLOSE($1)\n" if ($dbg_values > 1);
1320 $type = 'N';
1322 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1323 my $variant;
1325 print "OPV($1)\n" if ($dbg_values > 1);
1326 if ($type eq 'V') {
1327 $variant = 'B';
1328 } else {
1329 $variant = 'U';
1332 substr($var, length($res), 1, $variant);
1333 $type = 'N';
1335 } elsif ($cur =~ /^($Operators)/o) {
1336 print "OP($1)\n" if ($dbg_values > 1);
1337 if ($1 ne '++' && $1 ne '--') {
1338 $type = 'N';
1341 } elsif ($cur =~ /(^.)/o) {
1342 print "C($1)\n" if ($dbg_values > 1);
1344 if (defined $1) {
1345 $cur = substr($cur, length($1));
1346 $res .= $type x length($1);
1350 return ($res, $var);
1353 sub possible {
1354 my ($possible, $line) = @_;
1355 my $notPermitted = qr{(?:
1356 ^(?:
1357 $Modifier|
1358 $Storage|
1359 $Type|
1360 DEFINE_\S+
1362 ^(?:
1363 goto|
1364 return|
1365 case|
1366 else|
1367 asm|__asm__|
1370 \#\#|
1371 )(?:\s|$)|
1372 ^(?:typedef|struct|enum)\b
1373 )}x;
1374 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1375 if ($possible !~ $notPermitted) {
1376 # Check for modifiers.
1377 $possible =~ s/\s*$Storage\s*//g;
1378 $possible =~ s/\s*$Sparse\s*//g;
1379 if ($possible =~ /^\s*$/) {
1381 } elsif ($possible =~ /\s/) {
1382 $possible =~ s/\s*$Type\s*//g;
1383 for my $modifier (split(' ', $possible)) {
1384 if ($modifier !~ $notPermitted) {
1385 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1386 push(@modifierList, $modifier);
1390 } else {
1391 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1392 push(@typeList, $possible);
1394 build_types();
1395 } else {
1396 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1400 my $prefix = '';
1402 sub show_type {
1403 my ($type) = @_;
1405 return defined $use_type{$type} if (scalar keys %use_type > 0);
1407 return !defined $ignore_type{$type};
1410 sub report {
1411 my ($level, $type, $msg) = @_;
1413 if (!show_type($type) ||
1414 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1415 return 0;
1417 my $line;
1418 if ($show_types) {
1419 $line = "$prefix$level:$type: $msg\n";
1420 } else {
1421 $line = "$prefix$level: $msg\n";
1423 $line = (split('\n', $line))[0] . "\n" if ($terse);
1425 push(our @report, $line);
1427 return 1;
1430 sub report_dump {
1431 our @report;
1434 sub ERROR {
1435 my ($type, $msg) = @_;
1437 if (report("ERROR", $type, $msg)) {
1438 our $clean = 0;
1439 our $cnt_error++;
1440 return 1;
1442 return 0;
1444 sub WARN {
1445 my ($type, $msg) = @_;
1447 if (report("WARNING", $type, $msg)) {
1448 our $clean = 0;
1449 our $cnt_warn++;
1450 return 1;
1452 return 0;
1454 sub CHK {
1455 my ($type, $msg) = @_;
1457 if ($check && report("CHECK", $type, $msg)) {
1458 our $clean = 0;
1459 our $cnt_chk++;
1460 return 1;
1462 return 0;
1465 sub trim {
1466 my ($string) = @_;
1468 $string =~ s/^\s+|\s+$//g;
1470 return $string;
1473 sub ltrim {
1474 my ($string) = @_;
1476 $string =~ s/^\s+//;
1478 return $string;
1481 sub rtrim {
1482 my ($string) = @_;
1484 $string =~ s/\s+$//;
1486 return $string;
1489 sub string_find_replace {
1490 my ($string, $find, $replace) = @_;
1492 $string =~ s/$find/$replace/g;
1494 return $string;
1497 sub tabify {
1498 my ($leading) = @_;
1500 my $source_indent = 8;
1501 my $max_spaces_before_tab = $source_indent - 1;
1502 my $spaces_to_tab = " " x $source_indent;
1504 #convert leading spaces to tabs
1505 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
1506 #Remove spaces before a tab
1507 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
1509 return "$leading";
1512 sub pos_last_openparen {
1513 my ($line) = @_;
1515 my $pos = 0;
1517 my $opens = $line =~ tr/\(/\(/;
1518 my $closes = $line =~ tr/\)/\)/;
1520 my $last_openparen = 0;
1522 if (($opens == 0) || ($closes >= $opens)) {
1523 return -1;
1526 my $len = length($line);
1528 for ($pos = 0; $pos < $len; $pos++) {
1529 my $string = substr($line, $pos);
1530 if ($string =~ /^($FuncArg|$balanced_parens)/) {
1531 $pos += length($1) - 1;
1532 } elsif (substr($line, $pos, 1) eq '(') {
1533 $last_openparen = $pos;
1534 } elsif (index($string, '(') == -1) {
1535 last;
1539 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
1542 sub process {
1543 my $filename = shift;
1545 my $linenr=0;
1546 my $prevline="";
1547 my $prevrawline="";
1548 my $stashline="";
1549 my $stashrawline="";
1551 my $length;
1552 my $indent;
1553 my $previndent=0;
1554 my $stashindent=0;
1556 our $clean = 1;
1557 my $signoff = 0;
1558 my $is_patch = 0;
1560 my $in_header_lines = 1;
1561 my $in_commit_log = 0; #Scanning lines before patch
1563 my $non_utf8_charset = 0;
1565 our @report = ();
1566 our $cnt_lines = 0;
1567 our $cnt_error = 0;
1568 our $cnt_warn = 0;
1569 our $cnt_chk = 0;
1571 # Trace the real file/line as we go.
1572 my $realfile = '';
1573 my $realline = 0;
1574 my $realcnt = 0;
1575 my $here = '';
1576 my $in_comment = 0;
1577 my $comment_edge = 0;
1578 my $first_line = 0;
1579 my $p1_prefix = '';
1581 my $prev_values = 'E';
1583 # suppression flags
1584 my %suppress_ifbraces;
1585 my %suppress_whiletrailers;
1586 my %suppress_export;
1587 my $suppress_statement = 0;
1589 my %signatures = ();
1591 # Pre-scan the patch sanitizing the lines.
1592 # Pre-scan the patch looking for any __setup documentation.
1594 my @setup_docs = ();
1595 my $setup_docs = 0;
1597 my $camelcase_file_seeded = 0;
1599 sanitise_line_reset();
1600 my $line;
1601 foreach my $rawline (@rawlines) {
1602 $linenr++;
1603 $line = $rawline;
1605 push(@fixed, $rawline) if ($fix);
1607 if ($rawline=~/^\+\+\+\s+(\S+)/) {
1608 $setup_docs = 0;
1609 if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1610 $setup_docs = 1;
1612 #next;
1614 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1615 $realline=$1-1;
1616 if (defined $2) {
1617 $realcnt=$3+1;
1618 } else {
1619 $realcnt=1+1;
1621 $in_comment = 0;
1623 # Guestimate if this is a continuing comment. Run
1624 # the context looking for a comment "edge". If this
1625 # edge is a close comment then we must be in a comment
1626 # at context start.
1627 my $edge;
1628 my $cnt = $realcnt;
1629 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
1630 next if (defined $rawlines[$ln - 1] &&
1631 $rawlines[$ln - 1] =~ /^-/);
1632 $cnt--;
1633 #print "RAW<$rawlines[$ln - 1]>\n";
1634 last if (!defined $rawlines[$ln - 1]);
1635 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1636 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1637 ($edge) = $1;
1638 last;
1641 if (defined $edge && $edge eq '*/') {
1642 $in_comment = 1;
1645 # Guestimate if this is a continuing comment. If this
1646 # is the start of a diff block and this line starts
1647 # ' *' then it is very likely a comment.
1648 if (!defined $edge &&
1649 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1651 $in_comment = 1;
1654 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1655 sanitise_line_reset($in_comment);
1657 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1658 # Standardise the strings and chars within the input to
1659 # simplify matching -- only bother with positive lines.
1660 $line = sanitise_line($rawline);
1662 push(@lines, $line);
1664 if ($realcnt > 1) {
1665 $realcnt-- if ($line =~ /^(?:\+| |$)/);
1666 } else {
1667 $realcnt = 0;
1670 #print "==>$rawline\n";
1671 #print "-->$line\n";
1673 if ($setup_docs && $line =~ /^\+/) {
1674 push(@setup_docs, $line);
1678 $prefix = '';
1680 $realcnt = 0;
1681 $linenr = 0;
1682 foreach my $line (@lines) {
1683 $linenr++;
1684 my $sline = $line; #copy of $line
1685 $sline =~ s/$;/ /g; #with comments as spaces
1687 my $rawline = $rawlines[$linenr - 1];
1689 #extract the line range in the file after the patch is applied
1690 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1691 $is_patch = 1;
1692 $first_line = $linenr + 1;
1693 $realline=$1-1;
1694 if (defined $2) {
1695 $realcnt=$3+1;
1696 } else {
1697 $realcnt=1+1;
1699 annotate_reset();
1700 $prev_values = 'E';
1702 %suppress_ifbraces = ();
1703 %suppress_whiletrailers = ();
1704 %suppress_export = ();
1705 $suppress_statement = 0;
1706 next;
1708 # track the line number as we move through the hunk, note that
1709 # new versions of GNU diff omit the leading space on completely
1710 # blank context lines so we need to count that too.
1711 } elsif ($line =~ /^( |\+|$)/) {
1712 $realline++;
1713 $realcnt-- if ($realcnt != 0);
1715 # Measure the line length and indent.
1716 ($length, $indent) = line_stats($rawline);
1718 # Track the previous line.
1719 ($prevline, $stashline) = ($stashline, $line);
1720 ($previndent, $stashindent) = ($stashindent, $indent);
1721 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1723 #warn "line<$line>\n";
1725 } elsif ($realcnt == 1) {
1726 $realcnt--;
1729 my $hunk_line = ($realcnt != 0);
1731 #make up the handle for any error we report on this line
1732 $prefix = "$filename:$realline: " if ($emacs && $file);
1733 $prefix = "$filename:$linenr: " if ($emacs && !$file);
1735 $here = "#$linenr: " if (!$file);
1736 $here = "#$realline: " if ($file);
1738 # extract the filename as it passes
1739 if ($line =~ /^diff --git.*?(\S+)$/) {
1740 $realfile = $1;
1741 $realfile =~ s@^([^/]*)/@@ if (!$file);
1742 $in_commit_log = 0;
1743 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1744 $realfile = $1;
1745 $realfile =~ s@^([^/]*)/@@ if (!$file);
1746 $in_commit_log = 0;
1748 next;
1751 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
1753 my $hereline = "$here\n$rawline\n";
1754 my $herecurr = "$here\n$rawline\n";
1755 my $hereprev = "$here\n$prevrawline\n$rawline\n";
1757 $cnt_lines++ if ($realcnt != 0);
1759 # Check for incorrect file permissions
1760 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
1761 my $permhere = $here . "FILE: $realfile\n";
1762 if ($realfile !~ m@scripts/@ &&
1763 $realfile !~ /\.(py|pl|awk|sh)$/) {
1764 ERROR("EXECUTE_PERMISSIONS",
1765 "do not set execute permissions for source files\n" . $permhere);
1769 # Check the patch for a signoff:
1770 if ($line =~ /^\s*signed-off-by:/i) {
1771 $signoff++;
1772 $in_commit_log = 0;
1775 # Check for wrappage within a valid hunk of the file
1776 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1777 ERROR("CORRUPTED_PATCH",
1778 "patch seems to be corrupt (line wrapped?)\n" .
1779 $herecurr) if (!$emitted_corrupt++);
1782 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1783 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1784 $rawline !~ m/^$UTF8*$/) {
1785 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1787 my $blank = copy_spacing($rawline);
1788 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1789 my $hereptr = "$hereline$ptr\n";
1791 CHK("INVALID_UTF8",
1792 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
1795 # Check if it's the start of a commit log
1796 # (not a header line and we haven't seen the patch filename)
1797 if ($in_header_lines && $realfile =~ /^$/ &&
1798 $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
1799 $in_header_lines = 0;
1800 $in_commit_log = 1;
1803 # Check if there is UTF-8 in a commit log when a mail header has explicitly
1804 # declined it, i.e defined some charset where it is missing.
1805 if ($in_header_lines &&
1806 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
1807 $1 !~ /utf-8/i) {
1808 $non_utf8_charset = 1;
1811 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
1812 $rawline =~ /$NON_ASCII_UTF8/) {
1813 WARN("UTF8_BEFORE_PATCH",
1814 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
1817 # ignore non-hunk lines and lines being removed
1818 next if (!$hunk_line || $line =~ /^-/);
1820 #trailing whitespace
1821 if ($line =~ /^\+.*\015/) {
1822 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1823 if (ERROR("DOS_LINE_ENDINGS",
1824 "DOS line endings\n" . $herevet) &&
1825 $fix) {
1826 $fixed[$linenr - 1] =~ s/[\s\015]+$//;
1828 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1829 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1830 if (ERROR("TRAILING_WHITESPACE",
1831 "trailing whitespace\n" . $herevet) &&
1832 $fix) {
1833 $fixed[$linenr - 1] =~ s/\s+$//;
1836 $rpt_cleaners = 1;
1839 # Check for FSF mailing addresses.
1840 if ($rawline =~ /\bwrite to the Free/i ||
1841 $rawline =~ /\b59\s+Temple\s+Pl/i ||
1842 $rawline =~ /\b51\s+Franklin\s+St/i) {
1843 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1844 my $msg_type = \&ERROR;
1845 $msg_type = \&CHK if ($file);
1846 &{$msg_type}("FSF_MAILING_ADDRESS",
1847 "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)
1850 # check we are in a valid source file if not then ignore this hunk
1851 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1853 #line length limit
1854 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1855 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1856 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
1857 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
1858 $length > $max_line_length)
1860 WARN("LONG_LINE",
1861 "line over $max_line_length characters\n" . $herecurr);
1864 # Check for user-visible strings broken across lines, which breaks the ability
1865 # to grep for the string. Make exceptions when the previous string ends in a
1866 # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
1867 # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
1868 if ($line =~ /^\+\s*"/ &&
1869 $prevline =~ /"\s*$/ &&
1870 $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
1871 WARN("SPLIT_STRING",
1872 "quoted string split across lines\n" . $hereprev);
1875 # check for spaces before a quoted newline
1876 if ($rawline =~ /^.*\".*\s\\n/) {
1877 if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
1878 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
1879 $fix) {
1880 $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
1885 # check for adding lines without a newline.
1886 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1887 WARN("MISSING_EOF_NEWLINE",
1888 "adding a line without newline at end of file\n" . $herecurr);
1891 # check we are in a valid source file C or perl if not then ignore this hunk
1892 next if ($realfile !~ /\.(h|c|pl)$/);
1894 # at the beginning of a line any tabs must come first and anything
1895 # more than 8 must use tabs.
1896 if ($rawline =~ /^\+\s* \t\s*\S/ ||
1897 $rawline =~ /^\+\s* \s*/) {
1898 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1899 $rpt_cleaners = 1;
1900 if (ERROR("CODE_INDENT",
1901 "code indent should use tabs where possible\n" . $herevet) &&
1902 $fix) {
1903 $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
1907 # check for space before tabs.
1908 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
1909 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1910 if (WARN("SPACE_BEFORE_TAB",
1911 "please, no space before tabs\n" . $herevet) &&
1912 $fix) {
1913 while ($fixed[$linenr - 1] =~
1914 s/(^\+.*) {8,8}+\t/$1\t\t/) {}
1915 while ($fixed[$linenr - 1] =~
1916 s/(^\+.*) +\t/$1\t/) {}
1920 # check for && or || at the start of a line
1921 if ($rawline =~ /^\+\s*(&&|\|\|)/) {
1922 CHK("LOGICAL_CONTINUATIONS",
1923 "Logical continuations should be on the previous line\n" . $hereprev);
1926 # check multi-line statement indentation matches previous line
1927 if ($^V && $^V ge 5.10.0 &&
1928 $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
1929 $prevline =~ /^\+(\t*)(.*)$/;
1930 my $oldindent = $1;
1931 my $rest = $2;
1933 my $pos = pos_last_openparen($rest);
1934 if ($pos >= 0) {
1935 $line =~ /^(\+| )([ \t]*)/;
1936 my $newindent = $2;
1938 my $goodtabindent = $oldindent .
1939 "\t" x ($pos / 8) .
1940 " " x ($pos % 8);
1941 my $goodspaceindent = $oldindent . " " x $pos;
1943 if ($newindent ne $goodtabindent &&
1944 $newindent ne $goodspaceindent) {
1946 if (CHK("PARENTHESIS_ALIGNMENT",
1947 "Alignment should match open parenthesis\n" . $hereprev) &&
1948 $fix && $line =~ /^\+/) {
1949 $fixed[$linenr - 1] =~
1950 s/^\+[ \t]*/\+$goodtabindent/;
1956 if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
1957 if (CHK("SPACING",
1958 "No space is necessary after a cast\n" . $hereprev) &&
1959 $fix) {
1960 $fixed[$linenr - 1] =~
1961 s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
1965 # check for spaces at the beginning of a line.
1966 # Exceptions:
1967 # 1) within comments
1968 # 2) indented preprocessor commands
1969 # 3) hanging labels
1970 if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
1971 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1972 if (WARN("LEADING_SPACE",
1973 "please, no spaces at the start of a line\n" . $herevet) &&
1974 $fix) {
1975 $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
1979 # check we are in a valid C source file if not then ignore this hunk
1980 next if ($realfile !~ /\.(h|c)$/);
1982 # check for RCS/CVS revision markers
1983 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
1984 WARN("CVS_KEYWORD",
1985 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
1988 # Check for potential 'bare' types
1989 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
1990 $realline_next);
1991 #print "LINE<$line>\n";
1992 if ($linenr >= $suppress_statement &&
1993 $realcnt && $sline =~ /.\s*\S/) {
1994 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
1995 ctx_statement_block($linenr, $realcnt, 0);
1996 $stat =~ s/\n./\n /g;
1997 $cond =~ s/\n./\n /g;
1999 #print "linenr<$linenr> <$stat>\n";
2000 # If this statement has no statement boundaries within
2001 # it there is no point in retrying a statement scan
2002 # until we hit end of it.
2003 my $frag = $stat; $frag =~ s/;+\s*$//;
2004 if ($frag !~ /(?:{|;)/) {
2005 #print "skip<$line_nr_next>\n";
2006 $suppress_statement = $line_nr_next;
2009 # Find the real next line.
2010 $realline_next = $line_nr_next;
2011 if (defined $realline_next &&
2012 (!defined $lines[$realline_next - 1] ||
2013 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
2014 $realline_next++;
2017 my $s = $stat;
2018 $s =~ s/{.*$//s;
2020 # Ignore goto labels.
2021 if ($s =~ /$Ident:\*$/s) {
2023 # Ignore functions being called
2024 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2026 } elsif ($s =~ /^.\s*else\b/s) {
2028 # declarations always start with types
2029 } 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) {
2030 my $type = $1;
2031 $type =~ s/\s+/ /g;
2032 possible($type, "A:" . $s);
2034 # definitions in global scope can only start with types
2035 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2036 possible($1, "B:" . $s);
2039 # any (foo ... *) is a pointer cast, and foo is a type
2040 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2041 possible($1, "C:" . $s);
2044 # Check for any sort of function declaration.
2045 # int foo(something bar, other baz);
2046 # void (*store_gdt)(x86_descr_ptr *);
2047 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
2048 my ($name_len) = length($1);
2050 my $ctx = $s;
2051 substr($ctx, 0, $name_len + 1, '');
2052 $ctx =~ s/\)[^\)]*$//;
2054 for my $arg (split(/\s*,\s*/, $ctx)) {
2055 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
2057 possible($1, "D:" . $s);
2065 # Checks which may be anchored in the context.
2068 # Check for switch () and associated case and default
2069 # statements should be at the same indent.
2070 if ($line=~/\bswitch\s*\(.*\)/) {
2071 my $err = '';
2072 my $sep = '';
2073 my @ctx = ctx_block_outer($linenr, $realcnt);
2074 shift(@ctx);
2075 for my $ctx (@ctx) {
2076 my ($clen, $cindent) = line_stats($ctx);
2077 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
2078 $indent != $cindent) {
2079 $err .= "$sep$ctx\n";
2080 $sep = '';
2081 } else {
2082 $sep = "[...]\n";
2085 if ($err ne '') {
2086 ERROR("SWITCH_CASE_INDENT_LEVEL",
2087 "switch and case should be at the same indent\n$hereline$err");
2091 # if/while/etc brace do not go on next line, unless defining a do while loop,
2092 # or if that brace on the next line is for something else
2093 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2094 my $pre_ctx = "$1$2";
2096 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
2098 if ($line =~ /^\+\t{6,}/) {
2099 WARN("DEEP_INDENTATION",
2100 "Too many leading tabs - consider code refactoring\n" . $herecurr);
2103 my $ctx_cnt = $realcnt - $#ctx - 1;
2104 my $ctx = join("\n", @ctx);
2106 my $ctx_ln = $linenr;
2107 my $ctx_skip = $realcnt;
2109 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2110 defined $lines[$ctx_ln - 1] &&
2111 $lines[$ctx_ln - 1] =~ /^-/)) {
2112 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2113 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2114 $ctx_ln++;
2117 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
2118 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2120 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2121 ERROR("OPEN_BRACE",
2122 "that open brace { should be on the previous line\n" .
2123 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2125 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2126 $ctx =~ /\)\s*\;\s*$/ &&
2127 defined $lines[$ctx_ln - 1])
2129 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
2130 if ($nindent > $indent) {
2131 WARN("TRAILING_SEMICOLON",
2132 "trailing semicolon indicates no statements, indent implies otherwise\n" .
2133 "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2138 # Check relative indent for conditionals and blocks.
2139 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
2140 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2141 ctx_statement_block($linenr, $realcnt, 0)
2142 if (!defined $stat);
2143 my ($s, $c) = ($stat, $cond);
2145 substr($s, 0, length($c), '');
2147 # Make sure we remove the line prefixes as we have
2148 # none on the first line, and are going to readd them
2149 # where necessary.
2150 $s =~ s/\n./\n/gs;
2152 # Find out how long the conditional actually is.
2153 my @newlines = ($c =~ /\n/gs);
2154 my $cond_lines = 1 + $#newlines;
2156 # We want to check the first line inside the block
2157 # starting at the end of the conditional, so remove:
2158 # 1) any blank line termination
2159 # 2) any opening brace { on end of the line
2160 # 3) any do (...) {
2161 my $continuation = 0;
2162 my $check = 0;
2163 $s =~ s/^.*\bdo\b//;
2164 $s =~ s/^\s*{//;
2165 if ($s =~ s/^\s*\\//) {
2166 $continuation = 1;
2168 if ($s =~ s/^\s*?\n//) {
2169 $check = 1;
2170 $cond_lines++;
2173 # Also ignore a loop construct at the end of a
2174 # preprocessor statement.
2175 if (($prevline =~ /^.\s*#\s*define\s/ ||
2176 $prevline =~ /\\\s*$/) && $continuation == 0) {
2177 $check = 0;
2180 my $cond_ptr = -1;
2181 $continuation = 0;
2182 while ($cond_ptr != $cond_lines) {
2183 $cond_ptr = $cond_lines;
2185 # If we see an #else/#elif then the code
2186 # is not linear.
2187 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2188 $check = 0;
2191 # Ignore:
2192 # 1) blank lines, they should be at 0,
2193 # 2) preprocessor lines, and
2194 # 3) labels.
2195 if ($continuation ||
2196 $s =~ /^\s*?\n/ ||
2197 $s =~ /^\s*#\s*?/ ||
2198 $s =~ /^\s*$Ident\s*:/) {
2199 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
2200 if ($s =~ s/^.*?\n//) {
2201 $cond_lines++;
2206 my (undef, $sindent) = line_stats("+" . $s);
2207 my $stat_real = raw_line($linenr, $cond_lines);
2209 # Check if either of these lines are modified, else
2210 # this is not this patch's fault.
2211 if (!defined($stat_real) ||
2212 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
2213 $check = 0;
2215 if (defined($stat_real) && $cond_lines > 1) {
2216 $stat_real = "[...]\n$stat_real";
2219 #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
2221 if ($check && (($sindent % 8) != 0 ||
2222 ($sindent <= $indent && $s ne ''))) {
2223 WARN("SUSPECT_CODE_INDENT",
2224 "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
2228 # Track the 'values' across context and added lines.
2229 my $opline = $line; $opline =~ s/^./ /;
2230 my ($curr_values, $curr_vars) =
2231 annotate_values($opline . "\n", $prev_values);
2232 $curr_values = $prev_values . $curr_values;
2233 if ($dbg_values) {
2234 my $outline = $opline; $outline =~ s/\t/ /g;
2235 print "$linenr > .$outline\n";
2236 print "$linenr > $curr_values\n";
2237 print "$linenr > $curr_vars\n";
2239 $prev_values = substr($curr_values, -1);
2241 #ignore lines not being added
2242 next if ($line =~ /^[^\+]/);
2244 # TEST: allow direct testing of the type matcher.
2245 if ($dbg_type) {
2246 if ($line =~ /^.\s*$Declare\s*$/) {
2247 ERROR("TEST_TYPE",
2248 "TEST: is type\n" . $herecurr);
2249 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
2250 ERROR("TEST_NOT_TYPE",
2251 "TEST: is not type ($1 is)\n". $herecurr);
2253 next;
2255 # TEST: allow direct testing of the attribute matcher.
2256 if ($dbg_attr) {
2257 if ($line =~ /^.\s*$Modifier\s*$/) {
2258 ERROR("TEST_ATTR",
2259 "TEST: is attr\n" . $herecurr);
2260 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
2261 ERROR("TEST_NOT_ATTR",
2262 "TEST: is not attr ($1 is)\n". $herecurr);
2264 next;
2267 # check for initialisation to aggregates open brace on the next line
2268 if ($line =~ /^.\s*{/ &&
2269 $prevline =~ /(?:^|[^=])=\s*$/) {
2270 ERROR("OPEN_BRACE",
2271 "that open brace { should be on the previous line\n" . $hereprev);
2275 # Checks which are anchored on the added line.
2278 # check for malformed paths in #include statements (uses RAW line)
2279 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
2280 my $path = $1;
2281 if ($path =~ m{//}) {
2282 ERROR("MALFORMED_INCLUDE",
2283 "malformed #include filename\n" . $herecurr);
2287 # no C99 // comments
2288 if ($line =~ m{//}) {
2289 if (ERROR("C99_COMMENTS",
2290 "do not use C99 // comments\n" . $herecurr) &&
2291 $fix) {
2292 my $line = $fixed[$linenr - 1];
2293 if ($line =~ /\/\/(.*)$/) {
2294 my $comment = trim($1);
2295 $fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
2299 # Remove C99 comments.
2300 $line =~ s@//.*@@;
2301 $opline =~ s@//.*@@;
2303 # check for global initialisers.
2304 if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
2305 if (ERROR("GLOBAL_INITIALISERS",
2306 "do not initialise globals to 0 or NULL\n" .
2307 $herecurr) &&
2308 $fix) {
2309 $fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
2312 # check for static initialisers.
2313 if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
2314 if (ERROR("INITIALISED_STATIC",
2315 "do not initialise statics to 0 or NULL\n" .
2316 $herecurr) &&
2317 $fix) {
2318 $fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
2322 # check for static const char * arrays.
2323 if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
2324 WARN("STATIC_CONST_CHAR_ARRAY",
2325 "static const char * array should probably be static const char * const\n" .
2326 $herecurr);
2329 # check for static char foo[] = "bar" declarations.
2330 if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
2331 WARN("STATIC_CONST_CHAR_ARRAY",
2332 "static char array declaration should probably be static const char\n" .
2333 $herecurr);
2336 # check for non-global char *foo[] = {"bar", ...} declarations.
2337 if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
2338 WARN("STATIC_CONST_CHAR_ARRAY",
2339 "char * array declaration might be better as static const\n" .
2340 $herecurr);
2343 # check for function declarations without arguments like "int foo()"
2344 if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
2345 if (ERROR("FUNCTION_WITHOUT_ARGS",
2346 "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
2347 $fix) {
2348 $fixed[$linenr - 1] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
2352 # check for new typedefs, only function parameters and sparse annotations
2353 # make sense.
2354 if ($line =~ /\btypedef\s/ &&
2355 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
2356 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
2357 $line !~ /\b$typeTypedefs\b/ &&
2358 $line !~ /\b__bitwise(?:__|)\b/) {
2359 WARN("NEW_TYPEDEFS",
2360 "do not add new typedefs\n" . $herecurr);
2363 # * goes on variable not on type
2364 # (char*[ const])
2365 while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
2366 #print "AA<$1>\n";
2367 my ($ident, $from, $to) = ($1, $2, $2);
2369 # Should start with a space.
2370 $to =~ s/^(\S)/ $1/;
2371 # Should not end with a space.
2372 $to =~ s/\s+$//;
2373 # '*'s should not have spaces between.
2374 while ($to =~ s/\*\s+\*/\*\*/) {
2377 ## print "1: from<$from> to<$to> ident<$ident>\n";
2378 if ($from ne $to) {
2379 if (ERROR("POINTER_LOCATION",
2380 "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
2381 $fix) {
2382 my $sub_from = $ident;
2383 my $sub_to = $ident;
2384 $sub_to =~ s/\Q$from\E/$to/;
2385 $fixed[$linenr - 1] =~
2386 s@\Q$sub_from\E@$sub_to@;
2390 while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
2391 #print "BB<$1>\n";
2392 my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
2394 # Should start with a space.
2395 $to =~ s/^(\S)/ $1/;
2396 # Should not end with a space.
2397 $to =~ s/\s+$//;
2398 # '*'s should not have spaces between.
2399 while ($to =~ s/\*\s+\*/\*\*/) {
2401 # Modifiers should have spaces.
2402 $to =~ s/(\b$Modifier$)/$1 /;
2404 ## print "2: from<$from> to<$to> ident<$ident>\n";
2405 if ($from ne $to && $ident !~ /^$Modifier$/) {
2406 if (ERROR("POINTER_LOCATION",
2407 "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
2408 $fix) {
2410 my $sub_from = $match;
2411 my $sub_to = $match;
2412 $sub_to =~ s/\Q$from\E/$to/;
2413 $fixed[$linenr - 1] =~
2414 s@\Q$sub_from\E@$sub_to@;
2420 # function brace can't be on same line, except for #defines of do while,
2421 # or if closed on same line
2422 if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
2423 !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
2424 ERROR("OPEN_BRACE",
2425 "open brace '{' following function declarations go on the next line\n" . $herecurr);
2428 # open braces for enum, union and struct go on the same line.
2429 if ($line =~ /^.\s*{/ &&
2430 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2431 ERROR("OPEN_BRACE",
2432 "open brace '{' following $1 go on the same line\n" . $hereprev);
2435 # missing space after union, struct or enum definition
2436 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
2437 if (WARN("SPACING",
2438 "missing space after $1 definition\n" . $herecurr) &&
2439 $fix) {
2440 $fixed[$linenr - 1] =~
2441 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
2445 # Function pointer declarations
2446 # check spacing between type, funcptr, and args
2447 # canonical declaration is "type (*funcptr)(args...)"
2448 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
2449 my $declare = $1;
2450 my $pre_pointer_space = $2;
2451 my $post_pointer_space = $3;
2452 my $funcname = $4;
2453 my $post_funcname_space = $5;
2454 my $pre_args_space = $6;
2456 # the $Declare variable will capture all spaces after the type
2457 # so check it for a missing trailing missing space but pointer return types
2458 # don't need a space so don't warn for those.
2459 my $post_declare_space = "";
2460 if ($declare =~ /(\s+)$/) {
2461 $post_declare_space = $1;
2462 $declare = rtrim($declare);
2464 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
2465 WARN("SPACING",
2466 "missing space after return type\n" . $herecurr);
2467 $post_declare_space = " ";
2470 # unnecessary space "type (*funcptr)(args...)"
2471 # This test is not currently implemented because these declarations are
2472 # equivalent to
2473 # int foo(int bar, ...)
2474 # and this is form shouldn't/doesn't generate a checkpatch warning.
2476 # elsif ($declare =~ /\s{2,}$/) {
2477 # WARN("SPACING",
2478 # "Multiple spaces after return type\n" . $herecurr);
2481 # unnecessary space "type ( *funcptr)(args...)"
2482 if (defined $pre_pointer_space &&
2483 $pre_pointer_space =~ /^\s/) {
2484 WARN("SPACING",
2485 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
2488 # unnecessary space "type (* funcptr)(args...)"
2489 if (defined $post_pointer_space &&
2490 $post_pointer_space =~ /^\s/) {
2491 WARN("SPACING",
2492 "Unnecessary space before function pointer name\n" . $herecurr);
2495 # unnecessary space "type (*funcptr )(args...)"
2496 if (defined $post_funcname_space &&
2497 $post_funcname_space =~ /^\s/) {
2498 WARN("SPACING",
2499 "Unnecessary space after function pointer name\n" . $herecurr);
2502 # unnecessary space "type (*funcptr) (args...)"
2503 if (defined $pre_args_space &&
2504 $pre_args_space =~ /^\s/) {
2505 WARN("SPACING",
2506 "Unnecessary space before function pointer arguments\n" . $herecurr);
2509 if (show_type("SPACING") && $fix) {
2510 $fixed[$linenr - 1] =~
2511 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
2515 # check for spacing round square brackets; allowed:
2516 # 1. with a type on the left -- int [] a;
2517 # 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2518 # 3. inside a curly brace -- = { [0...10] = 5 }
2519 while ($line =~ /(.*?\s)\[/g) {
2520 my ($where, $prefix) = ($-[1], $1);
2521 if ($prefix !~ /$Type\s+$/ &&
2522 ($where != 0 || $prefix !~ /^.\s+$/) &&
2523 $prefix !~ /[{,]\s+$/) {
2524 if (ERROR("BRACKET_SPACE",
2525 "space prohibited before open square bracket '['\n" . $herecurr) &&
2526 $fix) {
2527 $fixed[$linenr - 1] =~
2528 s/^(\+.*?)\s+\[/$1\[/;
2533 # check for spaces between functions and their parentheses.
2534 while ($line =~ /($Ident)\s+\(/g) {
2535 my $name = $1;
2536 my $ctx_before = substr($line, 0, $-[1]);
2537 my $ctx = "$ctx_before$name";
2539 # Ignore those directives where spaces _are_ permitted.
2540 if ($name =~ /^(?:
2541 if|for|while|switch|return|case|
2542 volatile|__volatile__|
2543 __attribute__|format|__extension__|
2544 asm|__asm__)$/x)
2546 # cpp #define statements have non-optional spaces, ie
2547 # if there is a space between the name and the open
2548 # parenthesis it is simply not a parameter group.
2549 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
2551 # cpp #elif statement condition may start with a (
2552 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
2554 # If this whole things ends with a type its most
2555 # likely a typedef for a function.
2556 } elsif ($ctx =~ /$Type$/) {
2558 } else {
2559 if (WARN("SPACING",
2560 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
2561 $fix) {
2562 $fixed[$linenr - 1] =~
2563 s/\b$name\s+\(/$name\(/;
2568 # Check operator spacing.
2569 if (!($line=~/\#\s*include/)) {
2570 my $fixed_line = "";
2571 my $line_fixed = 0;
2573 my $ops = qr{
2574 <<=|>>=|<=|>=|==|!=|
2575 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
2576 =>|->|<<|>>|<|>|=|!|~|
2577 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
2578 \?:|\?|:
2580 my @elements = split(/($ops|;)/, $opline);
2582 my @fix_elements = ();
2583 my $off = 0;
2585 foreach my $el (@elements) {
2586 push(@fix_elements, substr($rawline, $off, length($el)));
2587 $off += length($el);
2590 $off = 0;
2592 my $blank = copy_spacing($opline);
2593 my $last_after = -1;
2595 for (my $n = 0; $n < $#elements; $n += 2) {
2597 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
2599 ## print("n: <$n> good: <$good>\n");
2601 $off += length($elements[$n]);
2603 # Pick up the preceding and succeeding characters.
2604 my $ca = substr($opline, 0, $off);
2605 my $cc = '';
2606 if (length($opline) >= ($off + length($elements[$n + 1]))) {
2607 $cc = substr($opline, $off + length($elements[$n + 1]));
2609 my $cb = "$ca$;$cc";
2611 my $a = '';
2612 $a = 'V' if ($elements[$n] ne '');
2613 $a = 'W' if ($elements[$n] =~ /\s$/);
2614 $a = 'C' if ($elements[$n] =~ /$;$/);
2615 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
2616 $a = 'O' if ($elements[$n] eq '');
2617 $a = 'E' if ($ca =~ /^\s*$/);
2619 my $op = $elements[$n + 1];
2621 my $c = '';
2622 if (defined $elements[$n + 2]) {
2623 $c = 'V' if ($elements[$n + 2] ne '');
2624 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
2625 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
2626 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
2627 $c = 'O' if ($elements[$n + 2] eq '');
2628 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
2629 } else {
2630 $c = 'E';
2633 my $ctx = "${a}x${c}";
2635 my $at = "(ctx:$ctx)";
2637 my $ptr = substr($blank, 0, $off) . "^";
2638 my $hereptr = "$hereline$ptr\n";
2640 # Pull out the value of this operator.
2641 my $op_type = substr($curr_values, $off + 1, 1);
2643 # Get the full operator variant.
2644 my $opv = $op . substr($curr_vars, $off, 1);
2646 # Ignore operators passed as parameters.
2647 if ($op_type ne 'V' &&
2648 $ca =~ /\s$/ && $cc =~ /^\s*,/) {
2650 # # Ignore comments
2651 # } elsif ($op =~ /^$;+$/) {
2653 # ; should have either the end of line or a space or \ after it
2654 } elsif ($op eq ';') {
2655 if ($ctx !~ /.x[WEBC]/ &&
2656 $cc !~ /^\\/ && $cc !~ /^;/) {
2657 if (ERROR("SPACING",
2658 "space required after that '$op' $at\n" . $hereptr)) {
2659 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2660 $line_fixed = 1;
2664 # // is a comment
2665 } elsif ($op eq '//') {
2667 # : when part of a bitfield
2668 } elsif ($opv eq ':B') {
2669 # skip the bitfield test for now
2671 # No spaces for:
2672 # ->
2673 } elsif ($op eq '->') {
2674 if ($ctx =~ /Wx.|.xW/) {
2675 if (ERROR("SPACING",
2676 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
2677 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2678 if (defined $fix_elements[$n + 2]) {
2679 $fix_elements[$n + 2] =~ s/^\s+//;
2681 $line_fixed = 1;
2685 # , must have a space on the right.
2686 } elsif ($op eq ',') {
2687 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
2688 if (ERROR("SPACING",
2689 "space required after that '$op' $at\n" . $hereptr)) {
2690 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2691 $line_fixed = 1;
2692 $last_after = $n;
2696 # '*' as part of a type definition -- reported already.
2697 } elsif ($opv eq '*_') {
2698 #warn "'*' is part of type\n";
2700 # unary operators should have a space before and
2701 # none after. May be left adjacent to another
2702 # unary operator, or a cast
2703 } elsif ($op eq '!' || $op eq '~' ||
2704 $opv eq '*U' || $opv eq '-U' ||
2705 $opv eq '&U' || $opv eq '&&U') {
2706 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
2707 if (ERROR("SPACING",
2708 "space required before that '$op' $at\n" . $hereptr)) {
2709 if ($n != $last_after + 2) {
2710 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
2711 $line_fixed = 1;
2715 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2716 # A unary '*' may be const
2718 } elsif ($ctx =~ /.xW/) {
2719 if (ERROR("SPACING",
2720 "space prohibited after that '$op' $at\n" . $hereptr)) {
2721 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
2722 if (defined $fix_elements[$n + 2]) {
2723 $fix_elements[$n + 2] =~ s/^\s+//;
2725 $line_fixed = 1;
2729 # unary ++ and unary -- are allowed no space on one side.
2730 } elsif ($op eq '++' or $op eq '--') {
2731 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
2732 if (ERROR("SPACING",
2733 "space required one side of that '$op' $at\n" . $hereptr)) {
2734 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2735 $line_fixed = 1;
2738 if ($ctx =~ /Wx[BE]/ ||
2739 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
2740 if (ERROR("SPACING",
2741 "space prohibited before that '$op' $at\n" . $hereptr)) {
2742 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2743 $line_fixed = 1;
2746 if ($ctx =~ /ExW/) {
2747 if (ERROR("SPACING",
2748 "space prohibited after that '$op' $at\n" . $hereptr)) {
2749 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
2750 if (defined $fix_elements[$n + 2]) {
2751 $fix_elements[$n + 2] =~ s/^\s+//;
2753 $line_fixed = 1;
2757 # << and >> may either have or not have spaces both sides
2758 } elsif ($op eq '<<' or $op eq '>>' or
2759 $op eq '&' or $op eq '^' or $op eq '|' or
2760 $op eq '+' or $op eq '-' or
2761 $op eq '*' or $op eq '/' or
2762 $op eq '%')
2764 if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
2765 if (ERROR("SPACING",
2766 "need consistent spacing around '$op' $at\n" . $hereptr)) {
2767 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2768 if (defined $fix_elements[$n + 2]) {
2769 $fix_elements[$n + 2] =~ s/^\s+//;
2771 $line_fixed = 1;
2775 # A colon needs no spaces before when it is
2776 # terminating a case value or a label.
2777 } elsif ($opv eq ':C' || $opv eq ':L') {
2778 if ($ctx =~ /Wx./) {
2779 if (ERROR("SPACING",
2780 "space prohibited before that '$op' $at\n" . $hereptr)) {
2781 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2782 $line_fixed = 1;
2786 # All the others need spaces both sides.
2787 } elsif ($ctx !~ /[EWC]x[CWE]/) {
2788 my $ok = 0;
2790 # Ignore email addresses <foo@bar>
2791 if (($op eq '<' &&
2792 $cc =~ /^\S+\@\S+>/) ||
2793 ($op eq '>' &&
2794 $ca =~ /<\S+\@\S+$/))
2796 $ok = 1;
2799 # messages are ERROR, but ?: are CHK
2800 if ($ok == 0) {
2801 my $msg_type = \&ERROR;
2802 $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
2804 if (&{$msg_type}("SPACING",
2805 "spaces required around that '$op' $at\n" . $hereptr)) {
2806 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2807 if (defined $fix_elements[$n + 2]) {
2808 $fix_elements[$n + 2] =~ s/^\s+//;
2810 $line_fixed = 1;
2814 $off += length($elements[$n + 1]);
2816 ## print("n: <$n> GOOD: <$good>\n");
2818 $fixed_line = $fixed_line . $good;
2821 if (($#elements % 2) == 0) {
2822 $fixed_line = $fixed_line . $fix_elements[$#elements];
2825 if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
2826 $fixed[$linenr - 1] = $fixed_line;
2832 # check for whitespace before a non-naked semicolon
2833 if ($line =~ /^\+.*\S\s+;\s*$/) {
2834 if (WARN("SPACING",
2835 "space prohibited before semicolon\n" . $herecurr) &&
2836 $fix) {
2837 1 while $fixed[$linenr - 1] =~
2838 s/^(\+.*\S)\s+;/$1;/;
2842 # check for multiple assignments
2843 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
2844 CHK("MULTIPLE_ASSIGNMENTS",
2845 "multiple assignments should be avoided\n" . $herecurr);
2849 #need space before brace following if, while, etc
2850 if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
2851 $line =~ /do{/) {
2852 if (ERROR("SPACING",
2853 "space required before the open brace '{'\n" . $herecurr) &&
2854 $fix) {
2855 $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/;
2859 # closing brace should have a space following it when it has anything
2860 # on the line
2861 if ($line =~ /}(?!(?:,|;|\)))\S/) {
2862 if (ERROR("SPACING",
2863 "space required after that close brace '}'\n" . $herecurr) &&
2864 $fix) {
2865 $fixed[$linenr - 1] =~
2866 s/}((?!(?:,|;|\)))\S)/} $1/;
2870 # check spacing on square brackets
2871 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
2872 if (ERROR("SPACING",
2873 "space prohibited after that open square bracket '['\n" . $herecurr) &&
2874 $fix) {
2875 $fixed[$linenr - 1] =~
2876 s/\[\s+/\[/;
2879 if ($line =~ /\s\]/) {
2880 if (ERROR("SPACING",
2881 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
2882 $fix) {
2883 $fixed[$linenr - 1] =~
2884 s/\s+\]/\]/;
2888 # check spacing on parentheses
2889 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
2890 $line !~ /for\s*\(\s+;/) {
2891 if (ERROR("SPACING",
2892 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
2893 $fix) {
2894 $fixed[$linenr - 1] =~
2895 s/\(\s+/\(/;
2898 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
2899 $line !~ /for\s*\(.*;\s+\)/ &&
2900 $line !~ /:\s+\)/) {
2901 if (ERROR("SPACING",
2902 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
2903 $fix) {
2904 $fixed[$linenr - 1] =~
2905 s/\s+\)/\)/;
2909 #goto labels aren't indented, allow a single space however
2910 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
2911 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
2912 if (WARN("INDENTED_LABEL",
2913 "labels should not be indented\n" . $herecurr) &&
2914 $fix) {
2915 $fixed[$linenr - 1] =~
2916 s/^(.)\s+/$1/;
2920 # return is not a function
2921 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
2922 my $spacing = $1;
2923 if ($^V && $^V ge 5.10.0 &&
2924 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
2925 my $value = $1;
2926 $value = deparenthesize($value);
2927 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
2928 ERROR("RETURN_PARENTHESES",
2929 "return is not a function, parentheses are not required\n" . $herecurr);
2931 } elsif ($spacing !~ /\s+/) {
2932 ERROR("SPACING",
2933 "space required before the open parenthesis '('\n" . $herecurr);
2937 # if statements using unnecessary parentheses - ie: if ((foo == bar))
2938 if ($^V && $^V ge 5.10.0 &&
2939 $line =~ /\bif\s*((?:\(\s*){2,})/) {
2940 my $openparens = $1;
2941 my $count = $openparens =~ tr@\(@\(@;
2942 my $msg = "";
2943 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
2944 my $comp = $4; #Not $1 because of $LvalOrFunc
2945 $msg = " - maybe == should be = ?" if ($comp eq "==");
2946 WARN("UNNECESSARY_PARENTHESES",
2947 "Unnecessary parentheses$msg\n" . $herecurr);
2951 # Return of what appears to be an errno should normally be -'ve
2952 if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
2953 my $name = $1;
2954 if ($name ne 'EOF' && $name ne 'ERROR') {
2955 WARN("USE_NEGATIVE_ERRNO",
2956 "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
2960 # Need a space before open parenthesis after if, while etc
2961 if ($line =~ /\b(if|while|for|switch)\(/) {
2962 if (ERROR("SPACING",
2963 "space required before the open parenthesis '('\n" . $herecurr) &&
2964 $fix) {
2965 $fixed[$linenr - 1] =~
2966 s/\b(if|while|for|switch)\(/$1 \(/;
2970 # Check for illegal assignment in if conditional -- and check for trailing
2971 # statements after the conditional.
2972 if ($line =~ /do\s*(?!{)/) {
2973 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2974 ctx_statement_block($linenr, $realcnt, 0)
2975 if (!defined $stat);
2976 my ($stat_next) = ctx_statement_block($line_nr_next,
2977 $remain_next, $off_next);
2978 $stat_next =~ s/\n./\n /g;
2979 ##print "stat<$stat> stat_next<$stat_next>\n";
2981 if ($stat_next =~ /^\s*while\b/) {
2982 # If the statement carries leading newlines,
2983 # then count those as offsets.
2984 my ($whitespace) =
2985 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
2986 my $offset =
2987 statement_rawlines($whitespace) - 1;
2989 $suppress_whiletrailers{$line_nr_next +
2990 $offset} = 1;
2993 if (!defined $suppress_whiletrailers{$linenr} &&
2994 defined($stat) && defined($cond) &&
2995 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
2996 my ($s, $c) = ($stat, $cond);
2998 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
2999 ERROR("ASSIGN_IN_IF",
3000 "do not use assignment in if condition\n" . $herecurr);
3003 # Find out what is on the end of the line after the
3004 # conditional.
3005 substr($s, 0, length($c), '');
3006 $s =~ s/\n.*//g;
3007 $s =~ s/$;//g; # Remove any comments
3008 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
3009 $c !~ /}\s*while\s*/)
3011 # Find out how long the conditional actually is.
3012 my @newlines = ($c =~ /\n/gs);
3013 my $cond_lines = 1 + $#newlines;
3014 my $stat_real = '';
3016 $stat_real = raw_line($linenr, $cond_lines)
3017 . "\n" if ($cond_lines);
3018 if (defined($stat_real) && $cond_lines > 1) {
3019 $stat_real = "[...]\n$stat_real";
3022 ERROR("TRAILING_STATEMENTS",
3023 "trailing statements should be on next line\n" . $herecurr . $stat_real);
3027 # Check for bitwise tests written as boolean
3028 if ($line =~ /
3030 (?:\[|\(|\&\&|\|\|)
3031 \s*0[xX][0-9]+\s*
3032 (?:\&\&|\|\|)
3034 (?:\&\&|\|\|)
3035 \s*0[xX][0-9]+\s*
3036 (?:\&\&|\|\||\)|\])
3037 )/x)
3039 WARN("HEXADECIMAL_BOOLEAN_TEST",
3040 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
3043 # if and else should not have general statements after it
3044 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
3045 my $s = $1;
3046 $s =~ s/$;//g; # Remove any comments
3047 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3048 ERROR("TRAILING_STATEMENTS",
3049 "trailing statements should be on next line\n" . $herecurr);
3052 # if should not continue a brace
3053 if ($line =~ /}\s*if\b/) {
3054 ERROR("TRAILING_STATEMENTS",
3055 "trailing statements should be on next line\n" .
3056 $herecurr);
3058 # case and default should not have general statements after them
3059 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3060 $line !~ /\G(?:
3061 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3062 \s*return\s+
3063 )/xg)
3065 ERROR("TRAILING_STATEMENTS",
3066 "trailing statements should be on next line\n" . $herecurr);
3069 # Check for }<nl>else {, these must be at the same
3070 # indent level to be relevant to each other.
3071 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
3072 $previndent == $indent) {
3073 ERROR("ELSE_AFTER_BRACE",
3074 "else should follow close brace '}'\n" . $hereprev);
3077 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3078 $previndent == $indent) {
3079 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3081 # Find out what is on the end of the line after the
3082 # conditional.
3083 substr($s, 0, length($c), '');
3084 $s =~ s/\n.*//g;
3086 if ($s =~ /^\s*;/) {
3087 ERROR("WHILE_AFTER_BRACE",
3088 "while should follow close brace '}'\n" . $hereprev);
3092 #Specific variable tests
3093 while ($line =~ m{($Constant|$Lval)}g) {
3094 my $var = $1;
3096 #gcc binary extension
3097 if ($var =~ /^$Binary$/) {
3098 if (WARN("GCC_BINARY_CONSTANT",
3099 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
3100 $fix) {
3101 my $hexval = sprintf("0x%x", oct($var));
3102 $fixed[$linenr - 1] =~
3103 s/\b$var\b/$hexval/;
3107 #CamelCase
3108 if ($var !~ /^$Constant$/ &&
3109 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
3110 #Ignore Page<foo> variants
3111 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
3112 #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
3113 $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
3114 while ($var =~ m{($Ident)}g) {
3115 my $word = $1;
3116 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
3117 if ($check) {
3118 seed_camelcase_includes();
3119 if (!$file && !$camelcase_file_seeded) {
3120 seed_camelcase_file($realfile);
3121 $camelcase_file_seeded = 1;
3124 if (!defined $camelcase{$word}) {
3125 $camelcase{$word} = 1;
3126 CHK("CAMELCASE",
3127 "Avoid CamelCase: <$word>\n" . $herecurr);
3133 #no spaces allowed after \ in define
3134 if ($line =~ /\#\s*define.*\\\s+$/) {
3135 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3136 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
3137 $fix) {
3138 $fixed[$linenr - 1] =~ s/\s+$//;
3142 # multi-statement macros should be enclosed in a do while loop, grab the
3143 # first statement and ensure its the whole macro if its not enclosed
3144 # in a known good container
3145 if ($realfile !~ m@/vmlinux.lds.h$@ &&
3146 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3147 my $ln = $linenr;
3148 my $cnt = $realcnt;
3149 my ($off, $dstat, $dcond, $rest);
3150 my $ctx = '';
3151 ($dstat, $dcond, $ln, $cnt, $off) =
3152 ctx_statement_block($linenr, $realcnt, 0);
3153 $ctx = $dstat;
3154 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3155 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3157 $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3158 $dstat =~ s/$;//g;
3159 $dstat =~ s/\\\n.//g;
3160 $dstat =~ s/^\s*//s;
3161 $dstat =~ s/\s*$//s;
3163 # Flatten any parentheses and braces
3164 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3165 $dstat =~ s/\{[^\{\}]*\}/1/ ||
3166 $dstat =~ s/\[[^\[\]]*\]/1/)
3170 # Flatten any obvious string concatentation.
3171 while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3172 $dstat =~ s/$Ident\s*("X*")/$1/)
3176 my $exceptions = qr{
3177 $Declare|
3178 module_param_named|
3179 MODULE_PARM_DESC|
3180 DECLARE_PER_CPU|
3181 DEFINE_PER_CPU|
3182 __typeof__\(|
3183 union|
3184 struct|
3185 \.$Ident\s*=\s*|
3186 ^\"|\"$
3188 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3189 if ($dstat ne '' &&
3190 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
3191 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
3192 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3193 $dstat !~ /^'X'$/ && # character constants
3194 $dstat !~ /$exceptions/ &&
3195 $dstat !~ /^\.$Ident\s*=/ && # .foo =
3196 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
3197 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
3198 $dstat !~ /^for\s*$Constant$/ && # for (...)
3199 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
3200 $dstat !~ /^do\s*{/ && # do {...
3201 $dstat !~ /^\({/ && # ({...
3202 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
3204 $ctx =~ s/\n*$//;
3205 my $herectx = $here . "\n";
3206 my $cnt = statement_rawlines($ctx);
3208 for (my $n = 0; $n < $cnt; $n++) {
3209 $herectx .= raw_line($linenr, $n) . "\n";
3212 if ($dstat =~ /;/) {
3213 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3214 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3215 } else {
3216 ERROR("COMPLEX_MACRO",
3217 "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3221 # check for line continuations outside of #defines, preprocessor #, and asm
3223 } else {
3224 if ($prevline !~ /^..*\\$/ &&
3225 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
3226 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
3227 $line =~ /^\+.*\\$/) {
3228 WARN("LINE_CONTINUATIONS",
3229 "Avoid unnecessary line continuations\n" . $herecurr);
3233 # do {} while (0) macro tests:
3234 # single-statement macros do not need to be enclosed in do while (0) loop,
3235 # macro should not end with a semicolon
3236 if ($^V && $^V ge 5.10.0 &&
3237 $realfile !~ m@/vmlinux.lds.h$@ &&
3238 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3239 my $ln = $linenr;
3240 my $cnt = $realcnt;
3241 my ($off, $dstat, $dcond, $rest);
3242 my $ctx = '';
3243 ($dstat, $dcond, $ln, $cnt, $off) =
3244 ctx_statement_block($linenr, $realcnt, 0);
3245 $ctx = $dstat;
3247 $dstat =~ s/\\\n.//g;
3249 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3250 my $stmts = $2;
3251 my $semis = $3;
3253 $ctx =~ s/\n*$//;
3254 my $cnt = statement_rawlines($ctx);
3255 my $herectx = $here . "\n";
3257 for (my $n = 0; $n < $cnt; $n++) {
3258 $herectx .= raw_line($linenr, $n) . "\n";
3261 if (($stmts =~ tr/;/;/) == 1 &&
3262 $stmts !~ /^\s*(if|while|for|switch)\b/) {
3263 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3264 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3266 if (defined $semis && $semis ne "") {
3267 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3268 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3273 # check for redundant bracing round if etc
3274 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
3275 my ($level, $endln, @chunks) =
3276 ctx_statement_full($linenr, $realcnt, 1);
3277 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3278 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3279 if ($#chunks > 0 && $level == 0) {
3280 my @allowed = ();
3281 my $allow = 0;
3282 my $seen = 0;
3283 my $herectx = $here . "\n";
3284 my $ln = $linenr - 1;
3285 for my $chunk (@chunks) {
3286 my ($cond, $block) = @{$chunk};
3288 # If the condition carries leading newlines, then count those as offsets.
3289 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3290 my $offset = statement_rawlines($whitespace) - 1;
3292 $allowed[$allow] = 0;
3293 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3295 # We have looked at and allowed this specific line.
3296 $suppress_ifbraces{$ln + $offset} = 1;
3298 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3299 $ln += statement_rawlines($block) - 1;
3301 substr($block, 0, length($cond), '');
3303 $seen++ if ($block =~ /^\s*{/);
3305 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3306 if (statement_lines($cond) > 1) {
3307 #print "APW: ALLOWED: cond<$cond>\n";
3308 $allowed[$allow] = 1;
3310 if ($block =~/\b(?:if|for|while)\b/) {
3311 #print "APW: ALLOWED: block<$block>\n";
3312 $allowed[$allow] = 1;
3314 if (statement_block_size($block) > 1) {
3315 #print "APW: ALLOWED: lines block<$block>\n";
3316 $allowed[$allow] = 1;
3318 $allow++;
3320 if ($seen) {
3321 my $sum_allowed = 0;
3322 foreach (@allowed) {
3323 $sum_allowed += $_;
3325 if ($sum_allowed == 0) {
3326 WARN("BRACES",
3327 "braces {} are not necessary for any arm of this statement\n" . $herectx);
3328 } elsif ($sum_allowed != $allow &&
3329 $seen != $allow) {
3330 CHK("BRACES",
3331 "braces {} should be used on all arms of this statement\n" . $herectx);
3336 if (!defined $suppress_ifbraces{$linenr - 1} &&
3337 $line =~ /\b(if|while|for|else)\b/) {
3338 my $allowed = 0;
3340 # Check the pre-context.
3341 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3342 #print "APW: ALLOWED: pre<$1>\n";
3343 $allowed = 1;
3346 my ($level, $endln, @chunks) =
3347 ctx_statement_full($linenr, $realcnt, $-[0]);
3349 # Check the condition.
3350 my ($cond, $block) = @{$chunks[0]};
3351 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3352 if (defined $cond) {
3353 substr($block, 0, length($cond), '');
3355 if (statement_lines($cond) > 1) {
3356 #print "APW: ALLOWED: cond<$cond>\n";
3357 $allowed = 1;
3359 if ($block =~/\b(?:if|for|while)\b/) {
3360 #print "APW: ALLOWED: block<$block>\n";
3361 $allowed = 1;
3363 if (statement_block_size($block) > 1) {
3364 #print "APW: ALLOWED: lines block<$block>\n";
3365 $allowed = 1;
3367 # Check the post-context.
3368 if (defined $chunks[1]) {
3369 my ($cond, $block) = @{$chunks[1]};
3370 if (defined $cond) {
3371 substr($block, 0, length($cond), '');
3373 if ($block =~ /^\s*\{/) {
3374 #print "APW: ALLOWED: chunk-1 block<$block>\n";
3375 $allowed = 1;
3378 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
3379 my $herectx = $here . "\n";
3380 my $cnt = statement_rawlines($block);
3382 for (my $n = 0; $n < $cnt; $n++) {
3383 $herectx .= raw_line($linenr, $n) . "\n";
3386 WARN("BRACES",
3387 "braces {} are not necessary for single statement blocks\n" . $herectx);
3391 # check for unnecessary blank lines around braces
3392 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
3393 CHK("BRACES",
3394 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
3396 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
3397 CHK("BRACES",
3398 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
3401 # warn about #if 0
3402 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3403 CHK("REDUNDANT_CODE",
3404 "if this code is redundant consider removing it\n" .
3405 $herecurr);
3408 # check for needless "if (<foo>) fn(<foo>)" uses
3409 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
3410 my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
3411 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
3412 WARN('NEEDLESS_IF',
3413 "$1(NULL) is safe this check is probably not required\n" . $hereprev);
3417 # check for bad placement of section $InitAttribute (e.g.: __initdata)
3418 if ($line =~ /(\b$InitAttribute\b)/) {
3419 my $attr = $1;
3420 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
3421 my $ptr = $1;
3422 my $var = $2;
3423 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
3424 ERROR("MISPLACED_INIT",
3425 "$attr should be placed after $var\n" . $herecurr)) ||
3426 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
3427 WARN("MISPLACED_INIT",
3428 "$attr should be placed after $var\n" . $herecurr))) &&
3429 $fix) {
3430 $fixed[$linenr - 1] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
3435 # check for $InitAttributeData (ie: __initdata) with const
3436 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
3437 my $attr = $1;
3438 $attr =~ /($InitAttributePrefix)(.*)/;
3439 my $attr_prefix = $1;
3440 my $attr_type = $2;
3441 if (ERROR("INIT_ATTRIBUTE",
3442 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
3443 $fix) {
3444 $fixed[$linenr - 1] =~
3445 s/$InitAttributeData/${attr_prefix}initconst/;
3449 # check for $InitAttributeConst (ie: __initconst) without const
3450 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
3451 my $attr = $1;
3452 if (ERROR("INIT_ATTRIBUTE",
3453 "Use of $attr requires a separate use of const\n" . $herecurr) &&
3454 $fix) {
3455 my $lead = $fixed[$linenr - 1] =~
3456 /(^\+\s*(?:static\s+))/;
3457 $lead = rtrim($1);
3458 $lead = "$lead " if ($lead !~ /^\+$/);
3459 $lead = "${lead}const ";
3460 $fixed[$linenr - 1] =~ s/(^\+\s*(?:static\s+))/$lead/;
3464 # warn about #ifdefs in C files
3465 # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
3466 # print "#ifdef in C files should be avoided\n";
3467 # print "$herecurr";
3468 # $clean = 0;
3471 # warn about spacing in #ifdefs
3472 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
3473 if (ERROR("SPACING",
3474 "exactly one space required after that #$1\n" . $herecurr) &&
3475 $fix) {
3476 $fixed[$linenr - 1] =~
3477 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
3482 # Check that the storage class is at the beginning of a declaration
3483 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3484 WARN("STORAGE_CLASS",
3485 "storage class should be at the beginning of the declaration\n" . $herecurr)
3488 # check the location of the inline attribute, that it is between
3489 # storage class and type.
3490 if ($line =~ /\b$Type\s+$Inline\b/ ||
3491 $line =~ /\b$Inline\s+$Storage\b/) {
3492 ERROR("INLINE_LOCATION",
3493 "inline keyword should sit between storage class and type\n" . $herecurr);
3496 # Check for __inline__ and __inline, prefer inline
3497 if ($realfile !~ m@\binclude/uapi/@ &&
3498 $line =~ /\b(__inline__|__inline)\b/) {
3499 if (WARN("INLINE",
3500 "plain inline is preferred over $1\n" . $herecurr) &&
3501 $fix) {
3502 $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
3507 # Check for __attribute__ packed, prefer __packed
3508 if ($realfile !~ m@\binclude/uapi/@ &&
3509 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3510 WARN("PREFER_PACKED",
3511 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
3514 # Check for __attribute__ aligned, prefer __aligned
3515 if ($realfile !~ m@\binclude/uapi/@ &&
3516 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3517 WARN("PREFER_ALIGNED",
3518 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
3521 # Check for __attribute__ format(printf, prefer __printf
3522 if ($realfile !~ m@\binclude/uapi/@ &&
3523 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
3524 if (WARN("PREFER_PRINTF",
3525 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
3526 $fix) {
3527 $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
3532 # Check for __attribute__ format(scanf, prefer __scanf
3533 if ($realfile !~ m@\binclude/uapi/@ &&
3534 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
3535 if (WARN("PREFER_SCANF",
3536 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
3537 $fix) {
3538 $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
3542 # check for sizeof(&)
3543 if ($line =~ /\bsizeof\s*\(\s*\&/) {
3544 WARN("SIZEOF_ADDRESS",
3545 "sizeof(& should be avoided\n" . $herecurr);
3548 # check for sizeof without parenthesis
3549 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
3550 if (WARN("SIZEOF_PARENTHESIS",
3551 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
3552 $fix) {
3553 $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
3557 # check for line continuations in quoted strings with odd counts of "
3558 if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3559 WARN("LINE_CONTINUATIONS",
3560 "Avoid line continuations in quoted strings\n" . $herecurr);
3563 # Check for misused memsets
3564 if ($^V && $^V ge 5.10.0 &&
3565 defined $stat &&
3566 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3568 my $ms_addr = $2;
3569 my $ms_val = $7;
3570 my $ms_size = $12;
3572 if ($ms_size =~ /^(0x|)0$/i) {
3573 ERROR("MEMSET",
3574 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3575 } elsif ($ms_size =~ /^(0x|)1$/i) {
3576 WARN("MEMSET",
3577 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3581 # typecasts on min/max could be min_t/max_t
3582 if ($^V && $^V ge 5.10.0 &&
3583 defined $stat &&
3584 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3585 if (defined $2 || defined $7) {
3586 my $call = $1;
3587 my $cast1 = deparenthesize($2);
3588 my $arg1 = $3;
3589 my $cast2 = deparenthesize($7);
3590 my $arg2 = $8;
3591 my $cast;
3593 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3594 $cast = "$cast1 or $cast2";
3595 } elsif ($cast1 ne "") {
3596 $cast = $cast1;
3597 } else {
3598 $cast = $cast2;
3600 WARN("MINMAX",
3601 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3605 # check for naked sscanf
3606 if ($^V && $^V ge 5.10.0 &&
3607 defined $stat &&
3608 $line =~ /\bsscanf\b/ &&
3609 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
3610 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
3611 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
3612 my $lc = $stat =~ tr@\n@@;
3613 $lc = $lc + $linenr;
3614 my $stat_real = raw_line($linenr, 0);
3615 for (my $count = $linenr + 1; $count <= $lc; $count++) {
3616 $stat_real = $stat_real . "\n" . raw_line($count, 0);
3618 WARN("NAKED_SSCANF",
3619 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
3622 # check for new externs in .h files.
3623 if ($realfile =~ /\.h$/ &&
3624 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
3625 if (CHK("AVOID_EXTERNS",
3626 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
3627 $fix) {
3628 $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
3632 # check for new externs in .c files.
3633 if ($realfile =~ /\.c$/ && defined $stat &&
3634 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
3636 my $function_name = $1;
3637 my $paren_space = $2;
3639 my $s = $stat;
3640 if (defined $cond) {
3641 substr($s, 0, length($cond), '');
3643 if ($s =~ /^\s*;/ &&
3644 $function_name ne 'uninitialized_var')
3646 WARN("AVOID_EXTERNS",
3647 "externs should be avoided in .c files\n" . $herecurr);
3650 if ($paren_space =~ /\n/) {
3651 WARN("FUNCTION_ARGUMENTS",
3652 "arguments for function declarations should follow identifier\n" . $herecurr);
3655 } elsif ($realfile =~ /\.c$/ && defined $stat &&
3656 $stat =~ /^.\s*extern\s+/)
3658 WARN("AVOID_EXTERNS",
3659 "externs should be avoided in .c files\n" . $herecurr);
3663 # check for multiple semicolons
3664 if ($line =~ /;\s*;\s*$/) {
3665 if (WARN("ONE_SEMICOLON",
3666 "Statements terminations use 1 semicolon\n" . $herecurr) &&
3667 $fix) {
3668 $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
3672 # check for case / default statements not preceeded by break/fallthrough/switch
3673 if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
3674 my $has_break = 0;
3675 my $has_statement = 0;
3676 my $count = 0;
3677 my $prevline = $linenr;
3678 while ($prevline > 1 && $count < 3 && !$has_break) {
3679 $prevline--;
3680 my $rline = $rawlines[$prevline - 1];
3681 my $fline = $lines[$prevline - 1];
3682 last if ($fline =~ /^\@\@/);
3683 next if ($fline =~ /^\-/);
3684 next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
3685 $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
3686 next if ($fline =~ /^.[\s$;]*$/);
3687 $has_statement = 1;
3688 $count++;
3689 $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
3691 if (!$has_break && $has_statement) {
3692 WARN("MISSING_BREAK",
3693 "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr);
3697 # check for switch/default statements without a break;
3698 if ($^V && $^V ge 5.10.0 &&
3699 defined $stat &&
3700 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
3701 my $ctx = '';
3702 my $herectx = $here . "\n";
3703 my $cnt = statement_rawlines($stat);
3704 for (my $n = 0; $n < $cnt; $n++) {
3705 $herectx .= raw_line($linenr, $n) . "\n";
3707 WARN("DEFAULT_NO_BREAK",
3708 "switch default: should use break\n" . $herectx);
3711 # check for gcc specific __FUNCTION__
3712 if ($line =~ /\b__FUNCTION__\b/) {
3713 if (WARN("USE_FUNC",
3714 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
3715 $fix) {
3716 $fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g;
3720 # check for comparisons against true and false
3721 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
3722 my $lead = $1;
3723 my $arg = $2;
3724 my $test = $3;
3725 my $otype = $4;
3726 my $trail = $5;
3727 my $op = "!";
3729 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
3731 my $type = lc($otype);
3732 if ($type =~ /^(?:true|false)$/) {
3733 if (("$test" eq "==" && "$type" eq "true") ||
3734 ("$test" eq "!=" && "$type" eq "false")) {
3735 $op = "";
3738 CHK("BOOL_COMPARISON",
3739 "Using comparison to $otype is error prone\n" . $herecurr);
3741 ## maybe suggesting a correct construct would better
3742 ## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
3747 # check for %L{u,d,i} in strings
3748 my $string;
3749 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
3750 $string = substr($rawline, $-[1], $+[1] - $-[1]);
3751 $string =~ s/%%/__/g;
3752 if ($string =~ /(?<!%)%L[udi]/) {
3753 WARN("PRINTF_L",
3754 "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
3755 last;
3759 # Mode permission misuses where it seems decimal should be octal
3760 # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
3761 if ($^V && $^V ge 5.10.0 &&
3762 $line =~ /$mode_perms_search/) {
3763 foreach my $entry (@mode_permission_funcs) {
3764 my $func = $entry->[0];
3765 my $arg_pos = $entry->[1];
3767 my $skip_args = "";
3768 if ($arg_pos > 1) {
3769 $arg_pos--;
3770 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
3772 my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
3773 if ($line =~ /$test/) {
3774 my $val = $1;
3775 $val = $6 if ($skip_args ne "");
3777 if ($val !~ /^0$/ &&
3778 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
3779 length($val) ne 4)) {
3780 ERROR("NON_OCTAL_PERMISSIONS",
3781 "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
3788 # If we have no input at all, then there is nothing to report on
3789 # so just keep quiet.
3790 if ($#rawlines == -1) {
3791 exit(0);
3794 # In mailback mode only produce a report in the negative, for
3795 # things that appear to be patches.
3796 if ($mailback && ($clean == 1 || !$is_patch)) {
3797 exit(0);
3800 # This is not a patch, and we are are in 'no-patch' mode so
3801 # just keep quiet.
3802 if (!$chk_patch && !$is_patch) {
3803 exit(0);
3806 if (!$is_patch) {
3807 ERROR("NOT_UNIFIED_DIFF",
3808 "Does not appear to be a unified-diff format patch\n");
3811 print report_dump();
3812 if ($summary && !($clean == 1 && $quiet == 1)) {
3813 print "$filename " if ($summary_file);
3814 print "total: $cnt_error errors, $cnt_warn warnings, " .
3815 (($check)? "$cnt_chk checks, " : "") .
3816 "$cnt_lines lines checked\n";
3817 print "\n" if ($quiet == 0);
3820 if ($quiet == 0) {
3822 if ($^V lt 5.10.0) {
3823 print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
3824 print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
3827 # If there were whitespace errors which cleanpatch can fix
3828 # then suggest that.
3829 if ($rpt_cleaners) {
3830 print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
3831 print " scripts/cleanfile\n\n";
3832 $rpt_cleaners = 0;
3836 hash_show_words(\%use_type, "Used");
3837 hash_show_words(\%ignore_type, "Ignored");
3839 if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
3840 my $newfile = $filename;
3841 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
3842 my $linecount = 0;
3843 my $f;
3845 open($f, '>', $newfile)
3846 or die "$P: Can't open $newfile for write\n";
3847 foreach my $fixed_line (@fixed) {
3848 $linecount++;
3849 if ($file) {
3850 if ($linecount > 3) {
3851 $fixed_line =~ s/^\+//;
3852 print $f $fixed_line. "\n";
3854 } else {
3855 print $f $fixed_line . "\n";
3858 close($f);
3860 if (!$quiet) {
3861 print << "EOM";
3862 Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
3864 Do _NOT_ trust the results written to this file.
3865 Do _NOT_ submit these changes without inspecting them for correctness.
3867 This EXPERIMENTAL file is simply a convenience to help rewrite patches.
3868 No warranties, expressed or implied...
3874 if ($clean == 1 && $quiet == 0) {
3875 print "$vname has no obvious style problems and is ready for submission.\n"
3877 if ($clean == 0 && $quiet == 0) {
3878 print << "EOM";
3879 $vname has style problems, please review.
3884 return $clean;