Include screen.h in dialog.h for definition of WScreen
[wmaker-crm.git] / checkpatch.pl
blobeee8d6ee38e3a0114df72bdc54e5df6980d70cd2
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*$balanced_parens\s*\{/ &&
2423 $line !~ /\#\s*define\b.*do\s*\{/ &&
2424 $line !~ /}/) {
2426 ERROR("OPEN_BRACE",
2427 "open brace '{' following function declarations go on the next line\n" . $herecurr);
2430 # open braces for enum, union and struct go on the same line.
2431 if ($line =~ /^.\s*{/ &&
2432 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2433 ERROR("OPEN_BRACE",
2434 "open brace '{' following $1 go on the same line\n" . $hereprev);
2437 # missing space after union, struct or enum definition
2438 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
2439 if (WARN("SPACING",
2440 "missing space after $1 definition\n" . $herecurr) &&
2441 $fix) {
2442 $fixed[$linenr - 1] =~
2443 s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
2447 # Function pointer declarations
2448 # check spacing between type, funcptr, and args
2449 # canonical declaration is "type (*funcptr)(args...)"
2450 if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
2451 my $declare = $1;
2452 my $pre_pointer_space = $2;
2453 my $post_pointer_space = $3;
2454 my $funcname = $4;
2455 my $post_funcname_space = $5;
2456 my $pre_args_space = $6;
2458 # the $Declare variable will capture all spaces after the type
2459 # so check it for a missing trailing missing space but pointer return types
2460 # don't need a space so don't warn for those.
2461 my $post_declare_space = "";
2462 if ($declare =~ /(\s+)$/) {
2463 $post_declare_space = $1;
2464 $declare = rtrim($declare);
2466 if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
2467 WARN("SPACING",
2468 "missing space after return type\n" . $herecurr);
2469 $post_declare_space = " ";
2472 # unnecessary space "type (*funcptr)(args...)"
2473 # This test is not currently implemented because these declarations are
2474 # equivalent to
2475 # int foo(int bar, ...)
2476 # and this is form shouldn't/doesn't generate a checkpatch warning.
2478 # elsif ($declare =~ /\s{2,}$/) {
2479 # WARN("SPACING",
2480 # "Multiple spaces after return type\n" . $herecurr);
2483 # unnecessary space "type ( *funcptr)(args...)"
2484 if (defined $pre_pointer_space &&
2485 $pre_pointer_space =~ /^\s/) {
2486 WARN("SPACING",
2487 "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
2490 # unnecessary space "type (* funcptr)(args...)"
2491 if (defined $post_pointer_space &&
2492 $post_pointer_space =~ /^\s/) {
2493 WARN("SPACING",
2494 "Unnecessary space before function pointer name\n" . $herecurr);
2497 # unnecessary space "type (*funcptr )(args...)"
2498 if (defined $post_funcname_space &&
2499 $post_funcname_space =~ /^\s/) {
2500 WARN("SPACING",
2501 "Unnecessary space after function pointer name\n" . $herecurr);
2504 # unnecessary space "type (*funcptr) (args...)"
2505 if (defined $pre_args_space &&
2506 $pre_args_space =~ /^\s/) {
2507 WARN("SPACING",
2508 "Unnecessary space before function pointer arguments\n" . $herecurr);
2511 if (show_type("SPACING") && $fix) {
2512 $fixed[$linenr - 1] =~
2513 s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
2517 # check for spacing round square brackets; allowed:
2518 # 1. with a type on the left -- int [] a;
2519 # 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2520 # 3. inside a curly brace -- = { [0...10] = 5 }
2521 while ($line =~ /(.*?\s)\[/g) {
2522 my ($where, $prefix) = ($-[1], $1);
2523 if ($prefix !~ /$Type\s+$/ &&
2524 ($where != 0 || $prefix !~ /^.\s+$/) &&
2525 $prefix !~ /[{,]\s+$/) {
2526 if (ERROR("BRACKET_SPACE",
2527 "space prohibited before open square bracket '['\n" . $herecurr) &&
2528 $fix) {
2529 $fixed[$linenr - 1] =~
2530 s/^(\+.*?)\s+\[/$1\[/;
2535 # check for spaces between functions and their parentheses.
2536 while ($line =~ /($Ident)\s+\(/g) {
2537 my $name = $1;
2538 my $ctx_before = substr($line, 0, $-[1]);
2539 my $ctx = "$ctx_before$name";
2541 # Ignore those directives where spaces _are_ permitted.
2542 if ($name =~ /^(?:
2543 if|for|while|switch|return|case|
2544 volatile|__volatile__|
2545 __attribute__|format|__extension__|
2546 asm|__asm__)$/x)
2548 # cpp #define statements have non-optional spaces, ie
2549 # if there is a space between the name and the open
2550 # parenthesis it is simply not a parameter group.
2551 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
2553 # cpp #elif statement condition may start with a (
2554 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
2556 # If this whole things ends with a type its most
2557 # likely a typedef for a function.
2558 } elsif ($ctx =~ /$Type$/) {
2560 } else {
2561 if (WARN("SPACING",
2562 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
2563 $fix) {
2564 $fixed[$linenr - 1] =~
2565 s/\b$name\s+\(/$name\(/;
2570 # Check operator spacing.
2571 if (!($line=~/\#\s*include/)) {
2572 my $fixed_line = "";
2573 my $line_fixed = 0;
2575 my $ops = qr{
2576 <<=|>>=|<=|>=|==|!=|
2577 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
2578 =>|->|<<|>>|<|>|=|!|~|
2579 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
2580 \?:|\?|:
2582 my @elements = split(/($ops|;)/, $opline);
2584 my @fix_elements = ();
2585 my $off = 0;
2587 foreach my $el (@elements) {
2588 push(@fix_elements, substr($rawline, $off, length($el)));
2589 $off += length($el);
2592 $off = 0;
2594 my $blank = copy_spacing($opline);
2595 my $last_after = -1;
2597 for (my $n = 0; $n < $#elements; $n += 2) {
2599 my $good = $fix_elements[$n] . $fix_elements[$n + 1];
2601 ## print("n: <$n> good: <$good>\n");
2603 $off += length($elements[$n]);
2605 # Pick up the preceding and succeeding characters.
2606 my $ca = substr($opline, 0, $off);
2607 my $cc = '';
2608 if (length($opline) >= ($off + length($elements[$n + 1]))) {
2609 $cc = substr($opline, $off + length($elements[$n + 1]));
2611 my $cb = "$ca$;$cc";
2613 my $a = '';
2614 $a = 'V' if ($elements[$n] ne '');
2615 $a = 'W' if ($elements[$n] =~ /\s$/);
2616 $a = 'C' if ($elements[$n] =~ /$;$/);
2617 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
2618 $a = 'O' if ($elements[$n] eq '');
2619 $a = 'E' if ($ca =~ /^\s*$/);
2621 my $op = $elements[$n + 1];
2623 my $c = '';
2624 if (defined $elements[$n + 2]) {
2625 $c = 'V' if ($elements[$n + 2] ne '');
2626 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
2627 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
2628 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
2629 $c = 'O' if ($elements[$n + 2] eq '');
2630 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
2631 } else {
2632 $c = 'E';
2635 my $ctx = "${a}x${c}";
2637 my $at = "(ctx:$ctx)";
2639 my $ptr = substr($blank, 0, $off) . "^";
2640 my $hereptr = "$hereline$ptr\n";
2642 # Pull out the value of this operator.
2643 my $op_type = substr($curr_values, $off + 1, 1);
2645 # Get the full operator variant.
2646 my $opv = $op . substr($curr_vars, $off, 1);
2648 # Ignore operators passed as parameters.
2649 if ($op_type ne 'V' &&
2650 $ca =~ /\s$/ && $cc =~ /^\s*,/) {
2652 # # Ignore comments
2653 # } elsif ($op =~ /^$;+$/) {
2655 # ; should have either the end of line or a space or \ after it
2656 } elsif ($op eq ';') {
2657 if ($ctx !~ /.x[WEBC]/ &&
2658 $cc !~ /^\\/ && $cc !~ /^;/) {
2659 if (ERROR("SPACING",
2660 "space required after that '$op' $at\n" . $hereptr)) {
2661 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2662 $line_fixed = 1;
2666 # // is a comment
2667 } elsif ($op eq '//') {
2669 # : when part of a bitfield
2670 } elsif ($opv eq ':B') {
2671 # skip the bitfield test for now
2673 # No spaces for:
2674 # ->
2675 } elsif ($op eq '->') {
2676 if ($ctx =~ /Wx.|.xW/) {
2677 if (ERROR("SPACING",
2678 "spaces prohibited around that '$op' $at\n" . $hereptr)) {
2679 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2680 if (defined $fix_elements[$n + 2]) {
2681 $fix_elements[$n + 2] =~ s/^\s+//;
2683 $line_fixed = 1;
2687 # , must have a space on the right.
2688 } elsif ($op eq ',') {
2689 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
2690 if (ERROR("SPACING",
2691 "space required after that '$op' $at\n" . $hereptr)) {
2692 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2693 $line_fixed = 1;
2694 $last_after = $n;
2698 # '*' as part of a type definition -- reported already.
2699 } elsif ($opv eq '*_') {
2700 #warn "'*' is part of type\n";
2702 # unary operators should have a space before and
2703 # none after. May be left adjacent to another
2704 # unary operator, or a cast
2705 } elsif ($op eq '!' || $op eq '~' ||
2706 $opv eq '*U' || $opv eq '-U' ||
2707 $opv eq '&U' || $opv eq '&&U') {
2708 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
2709 if (ERROR("SPACING",
2710 "space required before that '$op' $at\n" . $hereptr)) {
2711 if ($n != $last_after + 2) {
2712 $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
2713 $line_fixed = 1;
2717 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2718 # A unary '*' may be const
2720 } elsif ($ctx =~ /.xW/) {
2721 if (ERROR("SPACING",
2722 "space prohibited after that '$op' $at\n" . $hereptr)) {
2723 $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
2724 if (defined $fix_elements[$n + 2]) {
2725 $fix_elements[$n + 2] =~ s/^\s+//;
2727 $line_fixed = 1;
2731 # unary ++ and unary -- are allowed no space on one side.
2732 } elsif ($op eq '++' or $op eq '--') {
2733 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
2734 if (ERROR("SPACING",
2735 "space required one side of that '$op' $at\n" . $hereptr)) {
2736 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2737 $line_fixed = 1;
2740 if ($ctx =~ /Wx[BE]/ ||
2741 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
2742 if (ERROR("SPACING",
2743 "space prohibited before that '$op' $at\n" . $hereptr)) {
2744 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2745 $line_fixed = 1;
2748 if ($ctx =~ /ExW/) {
2749 if (ERROR("SPACING",
2750 "space prohibited after that '$op' $at\n" . $hereptr)) {
2751 $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
2752 if (defined $fix_elements[$n + 2]) {
2753 $fix_elements[$n + 2] =~ s/^\s+//;
2755 $line_fixed = 1;
2759 # << and >> may either have or not have spaces both sides
2760 } elsif ($op eq '<<' or $op eq '>>' or
2761 $op eq '&' or $op eq '^' or $op eq '|' or
2762 $op eq '+' or $op eq '-' or
2763 $op eq '*' or $op eq '/' or
2764 $op eq '%')
2766 if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
2767 if (ERROR("SPACING",
2768 "need consistent spacing around '$op' $at\n" . $hereptr)) {
2769 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2770 if (defined $fix_elements[$n + 2]) {
2771 $fix_elements[$n + 2] =~ s/^\s+//;
2773 $line_fixed = 1;
2777 # A colon needs no spaces before when it is
2778 # terminating a case value or a label.
2779 } elsif ($opv eq ':C' || $opv eq ':L') {
2780 if ($ctx =~ /Wx./) {
2781 if (ERROR("SPACING",
2782 "space prohibited before that '$op' $at\n" . $hereptr)) {
2783 $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2784 $line_fixed = 1;
2788 # All the others need spaces both sides.
2789 } elsif ($ctx !~ /[EWC]x[CWE]/) {
2790 my $ok = 0;
2792 # Ignore email addresses <foo@bar>
2793 if (($op eq '<' &&
2794 $cc =~ /^\S+\@\S+>/) ||
2795 ($op eq '>' &&
2796 $ca =~ /<\S+\@\S+$/))
2798 $ok = 1;
2801 # messages are ERROR, but ?: are CHK
2802 if ($ok == 0) {
2803 my $msg_type = \&ERROR;
2804 $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
2806 if (&{$msg_type}("SPACING",
2807 "spaces required around that '$op' $at\n" . $hereptr)) {
2808 $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2809 if (defined $fix_elements[$n + 2]) {
2810 $fix_elements[$n + 2] =~ s/^\s+//;
2812 $line_fixed = 1;
2816 $off += length($elements[$n + 1]);
2818 ## print("n: <$n> GOOD: <$good>\n");
2820 $fixed_line = $fixed_line . $good;
2823 if (($#elements % 2) == 0) {
2824 $fixed_line = $fixed_line . $fix_elements[$#elements];
2827 if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
2828 $fixed[$linenr - 1] = $fixed_line;
2834 # check for whitespace before a non-naked semicolon
2835 if ($line =~ /^\+.*\S\s+;\s*$/) {
2836 if (WARN("SPACING",
2837 "space prohibited before semicolon\n" . $herecurr) &&
2838 $fix) {
2839 1 while $fixed[$linenr - 1] =~
2840 s/^(\+.*\S)\s+;/$1;/;
2844 # check for multiple assignments
2845 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
2846 CHK("MULTIPLE_ASSIGNMENTS",
2847 "multiple assignments should be avoided\n" . $herecurr);
2851 #need space before brace following if, while, etc
2852 if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
2853 $line =~ /\b(?:else|do)\{/) {
2854 if (ERROR("SPACING",
2855 "space required before the open brace '{'\n" . $herecurr) &&
2856 $fix) {
2857 $fixed[$linenr - 1] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
2861 # closing brace should have a space following it when it has anything
2862 # on the line
2863 if ($line =~ /}(?!(?:,|;|\)))\S/) {
2864 if (ERROR("SPACING",
2865 "space required after that close brace '}'\n" . $herecurr) &&
2866 $fix) {
2867 $fixed[$linenr - 1] =~
2868 s/}((?!(?:,|;|\)))\S)/} $1/;
2872 # check spacing on square brackets
2873 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
2874 if (ERROR("SPACING",
2875 "space prohibited after that open square bracket '['\n" . $herecurr) &&
2876 $fix) {
2877 $fixed[$linenr - 1] =~
2878 s/\[\s+/\[/;
2881 if ($line =~ /\s\]/) {
2882 if (ERROR("SPACING",
2883 "space prohibited before that close square bracket ']'\n" . $herecurr) &&
2884 $fix) {
2885 $fixed[$linenr - 1] =~
2886 s/\s+\]/\]/;
2890 # check spacing on parentheses
2891 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
2892 $line !~ /for\s*\(\s+;/) {
2893 if (ERROR("SPACING",
2894 "space prohibited after that open parenthesis '('\n" . $herecurr) &&
2895 $fix) {
2896 $fixed[$linenr - 1] =~
2897 s/\(\s+/\(/;
2900 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
2901 $line !~ /for\s*\(.*;\s+\)/ &&
2902 $line !~ /:\s+\)/) {
2903 if (ERROR("SPACING",
2904 "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
2905 $fix) {
2906 $fixed[$linenr - 1] =~
2907 s/\s+\)/\)/;
2911 #goto labels aren't indented, allow a single space however
2912 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
2913 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
2914 if (WARN("INDENTED_LABEL",
2915 "labels should not be indented\n" . $herecurr) &&
2916 $fix) {
2917 $fixed[$linenr - 1] =~
2918 s/^(.)\s+/$1/;
2922 # return is not a function
2923 if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
2924 my $spacing = $1;
2925 if ($^V && $^V ge 5.10.0 &&
2926 $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
2927 my $value = $1;
2928 $value = deparenthesize($value);
2929 if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
2930 ERROR("RETURN_PARENTHESES",
2931 "return is not a function, parentheses are not required\n" . $herecurr);
2933 } elsif ($spacing !~ /\s+/) {
2934 ERROR("SPACING",
2935 "space required before the open parenthesis '('\n" . $herecurr);
2939 # if statements using unnecessary parentheses - ie: if ((foo == bar))
2940 if ($^V && $^V ge 5.10.0 &&
2941 $line =~ /\bif\s*((?:\(\s*){2,})/) {
2942 my $openparens = $1;
2943 my $count = $openparens =~ tr@\(@\(@;
2944 my $msg = "";
2945 if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
2946 my $comp = $4; #Not $1 because of $LvalOrFunc
2947 $msg = " - maybe == should be = ?" if ($comp eq "==");
2948 WARN("UNNECESSARY_PARENTHESES",
2949 "Unnecessary parentheses$msg\n" . $herecurr);
2953 # Return of what appears to be an errno should normally be -'ve
2954 if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
2955 my $name = $1;
2956 if ($name ne 'EOF' && $name ne 'ERROR') {
2957 WARN("USE_NEGATIVE_ERRNO",
2958 "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
2962 # Need a space before open parenthesis after if, while etc
2963 if ($line =~ /\b(if|while|for|switch)\(/) {
2964 if (ERROR("SPACING",
2965 "space required before the open parenthesis '('\n" . $herecurr) &&
2966 $fix) {
2967 $fixed[$linenr - 1] =~
2968 s/\b(if|while|for|switch)\(/$1 \(/;
2972 # Check for illegal assignment in if conditional -- and check for trailing
2973 # statements after the conditional.
2974 if ($line =~ /do\s*(?!{)/) {
2975 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2976 ctx_statement_block($linenr, $realcnt, 0)
2977 if (!defined $stat);
2978 my ($stat_next) = ctx_statement_block($line_nr_next,
2979 $remain_next, $off_next);
2980 $stat_next =~ s/\n./\n /g;
2981 ##print "stat<$stat> stat_next<$stat_next>\n";
2983 if ($stat_next =~ /^\s*while\b/) {
2984 # If the statement carries leading newlines,
2985 # then count those as offsets.
2986 my ($whitespace) =
2987 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
2988 my $offset =
2989 statement_rawlines($whitespace) - 1;
2991 $suppress_whiletrailers{$line_nr_next +
2992 $offset} = 1;
2995 if (!defined $suppress_whiletrailers{$linenr} &&
2996 defined($stat) && defined($cond) &&
2997 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
2998 my ($s, $c) = ($stat, $cond);
3000 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
3001 ERROR("ASSIGN_IN_IF",
3002 "do not use assignment in if condition\n" . $herecurr);
3005 # Find out what is on the end of the line after the
3006 # conditional.
3007 substr($s, 0, length($c), '');
3008 $s =~ s/\n.*//g;
3009 $s =~ s/$;//g; # Remove any comments
3010 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
3011 $c !~ /}\s*while\s*/)
3013 # Find out how long the conditional actually is.
3014 my @newlines = ($c =~ /\n/gs);
3015 my $cond_lines = 1 + $#newlines;
3016 my $stat_real = '';
3018 $stat_real = raw_line($linenr, $cond_lines)
3019 . "\n" if ($cond_lines);
3020 if (defined($stat_real) && $cond_lines > 1) {
3021 $stat_real = "[...]\n$stat_real";
3024 ERROR("TRAILING_STATEMENTS",
3025 "trailing statements should be on next line\n" . $herecurr . $stat_real);
3029 # Check for bitwise tests written as boolean
3030 if ($line =~ /
3032 (?:\[|\(|\&\&|\|\|)
3033 \s*0[xX][0-9]+\s*
3034 (?:\&\&|\|\|)
3036 (?:\&\&|\|\|)
3037 \s*0[xX][0-9]+\s*
3038 (?:\&\&|\|\||\)|\])
3039 )/x)
3041 WARN("HEXADECIMAL_BOOLEAN_TEST",
3042 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
3045 # if and else should not have general statements after it
3046 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
3047 my $s = $1;
3048 $s =~ s/$;//g; # Remove any comments
3049 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3050 ERROR("TRAILING_STATEMENTS",
3051 "trailing statements should be on next line\n" . $herecurr);
3054 # if should not continue a brace
3055 if ($line =~ /}\s*if\b/) {
3056 ERROR("TRAILING_STATEMENTS",
3057 "trailing statements should be on next line\n" .
3058 $herecurr);
3060 # case and default should not have general statements after them
3061 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3062 $line !~ /\G(?:
3063 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3064 \s*return\s+
3065 )/xg)
3067 ERROR("TRAILING_STATEMENTS",
3068 "trailing statements should be on next line\n" . $herecurr);
3071 # Check for }<nl>else {, these must be at the same
3072 # indent level to be relevant to each other.
3073 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
3074 $previndent == $indent) {
3075 ERROR("ELSE_AFTER_BRACE",
3076 "else should follow close brace '}'\n" . $hereprev);
3079 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3080 $previndent == $indent) {
3081 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3083 # Find out what is on the end of the line after the
3084 # conditional.
3085 substr($s, 0, length($c), '');
3086 $s =~ s/\n.*//g;
3088 if ($s =~ /^\s*;/) {
3089 ERROR("WHILE_AFTER_BRACE",
3090 "while should follow close brace '}'\n" . $hereprev);
3094 #Specific variable tests
3095 while ($line =~ m{($Constant|$Lval)}g) {
3096 my $var = $1;
3098 #gcc binary extension
3099 if ($var =~ /^$Binary$/) {
3100 if (WARN("GCC_BINARY_CONSTANT",
3101 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
3102 $fix) {
3103 my $hexval = sprintf("0x%x", oct($var));
3104 $fixed[$linenr - 1] =~
3105 s/\b$var\b/$hexval/;
3109 #CamelCase
3110 if ($var !~ /^$Constant$/ &&
3111 $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
3112 #Ignore Page<foo> variants
3113 $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
3114 #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
3115 $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
3116 while ($var =~ m{($Ident)}g) {
3117 my $word = $1;
3118 next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
3119 if ($check) {
3120 seed_camelcase_includes();
3121 if (!$file && !$camelcase_file_seeded) {
3122 seed_camelcase_file($realfile);
3123 $camelcase_file_seeded = 1;
3126 if (!defined $camelcase{$word}) {
3127 $camelcase{$word} = 1;
3128 CHK("CAMELCASE",
3129 "Avoid CamelCase: <$word>\n" . $herecurr);
3135 #no spaces allowed after \ in define
3136 if ($line =~ /\#\s*define.*\\\s+$/) {
3137 if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3138 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
3139 $fix) {
3140 $fixed[$linenr - 1] =~ s/\s+$//;
3144 # multi-statement macros should be enclosed in a do while loop, grab the
3145 # first statement and ensure its the whole macro if its not enclosed
3146 # in a known good container
3147 if ($realfile !~ m@/vmlinux.lds.h$@ &&
3148 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3149 my $ln = $linenr;
3150 my $cnt = $realcnt;
3151 my ($off, $dstat, $dcond, $rest);
3152 my $ctx = '';
3153 ($dstat, $dcond, $ln, $cnt, $off) =
3154 ctx_statement_block($linenr, $realcnt, 0);
3155 $ctx = $dstat;
3156 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3157 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3159 $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3160 $dstat =~ s/$;//g;
3161 $dstat =~ s/\\\n.//g;
3162 $dstat =~ s/^\s*//s;
3163 $dstat =~ s/\s*$//s;
3165 # Flatten any parentheses and braces
3166 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3167 $dstat =~ s/\{[^\{\}]*\}/1/ ||
3168 $dstat =~ s/\[[^\[\]]*\]/1/)
3172 # Flatten any obvious string concatentation.
3173 while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3174 $dstat =~ s/$Ident\s*("X*")/$1/)
3178 my $exceptions = qr{
3179 $Declare|
3180 module_param_named|
3181 MODULE_PARM_DESC|
3182 DECLARE_PER_CPU|
3183 DEFINE_PER_CPU|
3184 __typeof__\(|
3185 union|
3186 struct|
3187 \.$Ident\s*=\s*|
3188 ^\"|\"$
3190 #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3191 if ($dstat ne '' &&
3192 $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
3193 $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
3194 $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3195 $dstat !~ /^'X'$/ && # character constants
3196 $dstat !~ /$exceptions/ &&
3197 $dstat !~ /^\.$Ident\s*=/ && # .foo =
3198 $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
3199 $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
3200 $dstat !~ /^for\s*$Constant$/ && # for (...)
3201 $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
3202 $dstat !~ /^do\s*{/ && # do {...
3203 $dstat !~ /^\(\{/ && # ({...
3204 $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
3206 $ctx =~ s/\n*$//;
3207 my $herectx = $here . "\n";
3208 my $cnt = statement_rawlines($ctx);
3210 for (my $n = 0; $n < $cnt; $n++) {
3211 $herectx .= raw_line($linenr, $n) . "\n";
3214 if ($dstat =~ /;/) {
3215 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3216 "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3217 } else {
3218 ERROR("COMPLEX_MACRO",
3219 "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3223 # check for line continuations outside of #defines, preprocessor #, and asm
3225 } else {
3226 if ($prevline !~ /^..*\\$/ &&
3227 $line !~ /^\+\s*\#.*\\$/ && # preprocessor
3228 $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
3229 $line =~ /^\+.*\\$/) {
3230 WARN("LINE_CONTINUATIONS",
3231 "Avoid unnecessary line continuations\n" . $herecurr);
3235 # do {} while (0) macro tests:
3236 # single-statement macros do not need to be enclosed in do while (0) loop,
3237 # macro should not end with a semicolon
3238 if ($^V && $^V ge 5.10.0 &&
3239 $realfile !~ m@/vmlinux.lds.h$@ &&
3240 $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3241 my $ln = $linenr;
3242 my $cnt = $realcnt;
3243 my ($off, $dstat, $dcond, $rest);
3244 my $ctx = '';
3245 ($dstat, $dcond, $ln, $cnt, $off) =
3246 ctx_statement_block($linenr, $realcnt, 0);
3247 $ctx = $dstat;
3249 $dstat =~ s/\\\n.//g;
3251 if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3252 my $stmts = $2;
3253 my $semis = $3;
3255 $ctx =~ s/\n*$//;
3256 my $cnt = statement_rawlines($ctx);
3257 my $herectx = $here . "\n";
3259 for (my $n = 0; $n < $cnt; $n++) {
3260 $herectx .= raw_line($linenr, $n) . "\n";
3263 if (($stmts =~ tr/;/;/) == 1 &&
3264 $stmts !~ /^\s*(if|while|for|switch)\b/) {
3265 WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3266 "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3268 if (defined $semis && $semis ne "") {
3269 WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3270 "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3275 # check for redundant bracing round if etc
3276 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
3277 my ($level, $endln, @chunks) =
3278 ctx_statement_full($linenr, $realcnt, 1);
3279 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3280 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3281 if ($#chunks > 0 && $level == 0) {
3282 my @allowed = ();
3283 my $allow = 0;
3284 my $seen = 0;
3285 my $herectx = $here . "\n";
3286 my $ln = $linenr - 1;
3287 for my $chunk (@chunks) {
3288 my ($cond, $block) = @{$chunk};
3290 # If the condition carries leading newlines, then count those as offsets.
3291 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3292 my $offset = statement_rawlines($whitespace) - 1;
3294 $allowed[$allow] = 0;
3295 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3297 # We have looked at and allowed this specific line.
3298 $suppress_ifbraces{$ln + $offset} = 1;
3300 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3301 $ln += statement_rawlines($block) - 1;
3303 substr($block, 0, length($cond), '');
3305 $seen++ if ($block =~ /^\s*{/);
3307 #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3308 if (statement_lines($cond) > 1) {
3309 #print "APW: ALLOWED: cond<$cond>\n";
3310 $allowed[$allow] = 1;
3312 if ($block =~/\b(?:if|for|while)\b/) {
3313 #print "APW: ALLOWED: block<$block>\n";
3314 $allowed[$allow] = 1;
3316 if (statement_block_size($block) > 1) {
3317 #print "APW: ALLOWED: lines block<$block>\n";
3318 $allowed[$allow] = 1;
3320 $allow++;
3322 if ($seen) {
3323 my $sum_allowed = 0;
3324 foreach (@allowed) {
3325 $sum_allowed += $_;
3327 if ($sum_allowed == 0) {
3328 WARN("BRACES",
3329 "braces {} are not necessary for any arm of this statement\n" . $herectx);
3330 } elsif ($sum_allowed != $allow &&
3331 $seen != $allow) {
3332 CHK("BRACES",
3333 "braces {} should be used on all arms of this statement\n" . $herectx);
3338 if (!defined $suppress_ifbraces{$linenr - 1} &&
3339 $line =~ /\b(if|while|for|else)\b/) {
3340 my $allowed = 0;
3342 # Check the pre-context.
3343 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3344 #print "APW: ALLOWED: pre<$1>\n";
3345 $allowed = 1;
3348 my ($level, $endln, @chunks) =
3349 ctx_statement_full($linenr, $realcnt, $-[0]);
3351 # Check the condition.
3352 my ($cond, $block) = @{$chunks[0]};
3353 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3354 if (defined $cond) {
3355 substr($block, 0, length($cond), '');
3357 if (statement_lines($cond) > 1) {
3358 #print "APW: ALLOWED: cond<$cond>\n";
3359 $allowed = 1;
3361 if ($block =~/\b(?:if|for|while)\b/) {
3362 #print "APW: ALLOWED: block<$block>\n";
3363 $allowed = 1;
3365 if (statement_block_size($block) > 1) {
3366 #print "APW: ALLOWED: lines block<$block>\n";
3367 $allowed = 1;
3369 # Check the post-context.
3370 if (defined $chunks[1]) {
3371 my ($cond, $block) = @{$chunks[1]};
3372 if (defined $cond) {
3373 substr($block, 0, length($cond), '');
3375 if ($block =~ /^\s*\{/) {
3376 #print "APW: ALLOWED: chunk-1 block<$block>\n";
3377 $allowed = 1;
3380 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
3381 my $herectx = $here . "\n";
3382 my $cnt = statement_rawlines($block);
3384 for (my $n = 0; $n < $cnt; $n++) {
3385 $herectx .= raw_line($linenr, $n) . "\n";
3388 WARN("BRACES",
3389 "braces {} are not necessary for single statement blocks\n" . $herectx);
3393 # check for unnecessary blank lines around braces
3394 if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
3395 CHK("BRACES",
3396 "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
3398 if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
3399 CHK("BRACES",
3400 "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
3403 # warn about #if 0
3404 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3405 CHK("REDUNDANT_CODE",
3406 "if this code is redundant consider removing it\n" .
3407 $herecurr);
3410 # check for needless "if (<foo>) fn(<foo>)" uses
3411 if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
3412 my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
3413 if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
3414 WARN('NEEDLESS_IF',
3415 "$1(NULL) is safe this check is probably not required\n" . $hereprev);
3419 # check for bad placement of section $InitAttribute (e.g.: __initdata)
3420 if ($line =~ /(\b$InitAttribute\b)/) {
3421 my $attr = $1;
3422 if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
3423 my $ptr = $1;
3424 my $var = $2;
3425 if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
3426 ERROR("MISPLACED_INIT",
3427 "$attr should be placed after $var\n" . $herecurr)) ||
3428 ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
3429 WARN("MISPLACED_INIT",
3430 "$attr should be placed after $var\n" . $herecurr))) &&
3431 $fix) {
3432 $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;
3437 # check for $InitAttributeData (ie: __initdata) with const
3438 if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
3439 my $attr = $1;
3440 $attr =~ /($InitAttributePrefix)(.*)/;
3441 my $attr_prefix = $1;
3442 my $attr_type = $2;
3443 if (ERROR("INIT_ATTRIBUTE",
3444 "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
3445 $fix) {
3446 $fixed[$linenr - 1] =~
3447 s/$InitAttributeData/${attr_prefix}initconst/;
3451 # check for $InitAttributeConst (ie: __initconst) without const
3452 if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
3453 my $attr = $1;
3454 if (ERROR("INIT_ATTRIBUTE",
3455 "Use of $attr requires a separate use of const\n" . $herecurr) &&
3456 $fix) {
3457 my $lead = $fixed[$linenr - 1] =~
3458 /(^\+\s*(?:static\s+))/;
3459 $lead = rtrim($1);
3460 $lead = "$lead " if ($lead !~ /^\+$/);
3461 $lead = "${lead}const ";
3462 $fixed[$linenr - 1] =~ s/(^\+\s*(?:static\s+))/$lead/;
3466 # warn about #ifdefs in C files
3467 # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
3468 # print "#ifdef in C files should be avoided\n";
3469 # print "$herecurr";
3470 # $clean = 0;
3473 # warn about spacing in #ifdefs
3474 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
3475 if (ERROR("SPACING",
3476 "exactly one space required after that #$1\n" . $herecurr) &&
3477 $fix) {
3478 $fixed[$linenr - 1] =~
3479 s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
3484 # Check that the storage class is at the beginning of a declaration
3485 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3486 WARN("STORAGE_CLASS",
3487 "storage class should be at the beginning of the declaration\n" . $herecurr)
3490 # check the location of the inline attribute, that it is between
3491 # storage class and type.
3492 if ($line =~ /\b$Type\s+$Inline\b/ ||
3493 $line =~ /\b$Inline\s+$Storage\b/) {
3494 ERROR("INLINE_LOCATION",
3495 "inline keyword should sit between storage class and type\n" . $herecurr);
3498 # Check for __inline__ and __inline, prefer inline
3499 if ($realfile !~ m@\binclude/uapi/@ &&
3500 $line =~ /\b(__inline__|__inline)\b/) {
3501 if (WARN("INLINE",
3502 "plain inline is preferred over $1\n" . $herecurr) &&
3503 $fix) {
3504 $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
3509 # Check for __attribute__ packed, prefer __packed
3510 if ($realfile !~ m@\binclude/uapi/@ &&
3511 $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3512 WARN("PREFER_PACKED",
3513 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
3516 # Check for __attribute__ aligned, prefer __aligned
3517 if ($realfile !~ m@\binclude/uapi/@ &&
3518 $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3519 WARN("PREFER_ALIGNED",
3520 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
3523 # Check for __attribute__ format(printf, prefer __printf
3524 if ($realfile !~ m@\binclude/uapi/@ &&
3525 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
3526 if (WARN("PREFER_PRINTF",
3527 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
3528 $fix) {
3529 $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
3534 # Check for __attribute__ format(scanf, prefer __scanf
3535 if ($realfile !~ m@\binclude/uapi/@ &&
3536 $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
3537 if (WARN("PREFER_SCANF",
3538 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
3539 $fix) {
3540 $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
3544 # check for sizeof(&)
3545 if ($line =~ /\bsizeof\s*\(\s*\&/) {
3546 WARN("SIZEOF_ADDRESS",
3547 "sizeof(& should be avoided\n" . $herecurr);
3550 # check for sizeof without parenthesis
3551 if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
3552 if (WARN("SIZEOF_PARENTHESIS",
3553 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
3554 $fix) {
3555 $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
3559 # check for line continuations in quoted strings with odd counts of "
3560 if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3561 WARN("LINE_CONTINUATIONS",
3562 "Avoid line continuations in quoted strings\n" . $herecurr);
3565 # Check for misused memsets
3566 if ($^V && $^V ge 5.10.0 &&
3567 defined $stat &&
3568 $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3570 my $ms_addr = $2;
3571 my $ms_val = $7;
3572 my $ms_size = $12;
3574 if ($ms_size =~ /^(0x|)0$/i) {
3575 ERROR("MEMSET",
3576 "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3577 } elsif ($ms_size =~ /^(0x|)1$/i) {
3578 WARN("MEMSET",
3579 "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3583 # typecasts on min/max could be min_t/max_t
3584 if ($^V && $^V ge 5.10.0 &&
3585 defined $stat &&
3586 $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3587 if (defined $2 || defined $7) {
3588 my $call = $1;
3589 my $cast1 = deparenthesize($2);
3590 my $arg1 = $3;
3591 my $cast2 = deparenthesize($7);
3592 my $arg2 = $8;
3593 my $cast;
3595 if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3596 $cast = "$cast1 or $cast2";
3597 } elsif ($cast1 ne "") {
3598 $cast = $cast1;
3599 } else {
3600 $cast = $cast2;
3602 WARN("MINMAX",
3603 "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3607 # check for naked sscanf
3608 if ($^V && $^V ge 5.10.0 &&
3609 defined $stat &&
3610 $line =~ /\bsscanf\b/ &&
3611 ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
3612 $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
3613 $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
3614 my $lc = $stat =~ tr@\n@@;
3615 $lc = $lc + $linenr;
3616 my $stat_real = raw_line($linenr, 0);
3617 for (my $count = $linenr + 1; $count <= $lc; $count++) {
3618 $stat_real = $stat_real . "\n" . raw_line($count, 0);
3620 WARN("NAKED_SSCANF",
3621 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
3624 # check for new externs in .h files.
3625 if ($realfile =~ /\.h$/ &&
3626 $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
3627 if (CHK("AVOID_EXTERNS",
3628 "extern prototypes should be avoided in .h files\n" . $herecurr) &&
3629 $fix) {
3630 $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
3634 # check for new externs in .c files.
3635 if ($realfile =~ /\.c$/ && defined $stat &&
3636 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
3638 my $function_name = $1;
3639 my $paren_space = $2;
3641 my $s = $stat;
3642 if (defined $cond) {
3643 substr($s, 0, length($cond), '');
3645 if ($s =~ /^\s*;/ &&
3646 $function_name ne 'uninitialized_var')
3648 WARN("AVOID_EXTERNS",
3649 "externs should be avoided in .c files\n" . $herecurr);
3652 if ($paren_space =~ /\n/) {
3653 WARN("FUNCTION_ARGUMENTS",
3654 "arguments for function declarations should follow identifier\n" . $herecurr);
3657 } elsif ($realfile =~ /\.c$/ && defined $stat &&
3658 $stat =~ /^.\s*extern\s+/)
3660 WARN("AVOID_EXTERNS",
3661 "externs should be avoided in .c files\n" . $herecurr);
3665 # check for multiple semicolons
3666 if ($line =~ /;\s*;\s*$/) {
3667 if (WARN("ONE_SEMICOLON",
3668 "Statements terminations use 1 semicolon\n" . $herecurr) &&
3669 $fix) {
3670 $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
3674 # check for case / default statements not preceeded by break/fallthrough/switch
3675 if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
3676 my $has_break = 0;
3677 my $has_statement = 0;
3678 my $count = 0;
3679 my $prevline = $linenr;
3680 while ($prevline > 1 && $count < 3 && !$has_break) {
3681 $prevline--;
3682 my $rline = $rawlines[$prevline - 1];
3683 my $fline = $lines[$prevline - 1];
3684 last if ($fline =~ /^\@\@/);
3685 next if ($fline =~ /^\-/);
3686 next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
3687 $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
3688 next if ($fline =~ /^.[\s$;]*$/);
3689 $has_statement = 1;
3690 $count++;
3691 $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
3693 if (!$has_break && $has_statement) {
3694 WARN("MISSING_BREAK",
3695 "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr);
3699 # check for switch/default statements without a break;
3700 if ($^V && $^V ge 5.10.0 &&
3701 defined $stat &&
3702 $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
3703 my $ctx = '';
3704 my $herectx = $here . "\n";
3705 my $cnt = statement_rawlines($stat);
3706 for (my $n = 0; $n < $cnt; $n++) {
3707 $herectx .= raw_line($linenr, $n) . "\n";
3709 WARN("DEFAULT_NO_BREAK",
3710 "switch default: should use break\n" . $herectx);
3713 # check for gcc specific __FUNCTION__
3714 if ($line =~ /\b__FUNCTION__\b/) {
3715 if (WARN("USE_FUNC",
3716 "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
3717 $fix) {
3718 $fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g;
3722 # check for comparisons against true and false
3723 if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
3724 my $lead = $1;
3725 my $arg = $2;
3726 my $test = $3;
3727 my $otype = $4;
3728 my $trail = $5;
3729 my $op = "!";
3731 ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
3733 my $type = lc($otype);
3734 if ($type =~ /^(?:true|false)$/) {
3735 if (("$test" eq "==" && "$type" eq "true") ||
3736 ("$test" eq "!=" && "$type" eq "false")) {
3737 $op = "";
3740 CHK("BOOL_COMPARISON",
3741 "Using comparison to $otype is error prone\n" . $herecurr);
3743 ## maybe suggesting a correct construct would better
3744 ## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
3749 # check for %L{u,d,i} in strings
3750 my $string;
3751 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
3752 $string = substr($rawline, $-[1], $+[1] - $-[1]);
3753 $string =~ s/%%/__/g;
3754 if ($string =~ /(?<!%)%L[udi]/) {
3755 WARN("PRINTF_L",
3756 "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
3757 last;
3761 # Mode permission misuses where it seems decimal should be octal
3762 # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
3763 if ($^V && $^V ge 5.10.0 &&
3764 $line =~ /$mode_perms_search/) {
3765 foreach my $entry (@mode_permission_funcs) {
3766 my $func = $entry->[0];
3767 my $arg_pos = $entry->[1];
3769 my $skip_args = "";
3770 if ($arg_pos > 1) {
3771 $arg_pos--;
3772 $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
3774 my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
3775 if ($line =~ /$test/) {
3776 my $val = $1;
3777 $val = $6 if ($skip_args ne "");
3779 if ($val !~ /^0$/ &&
3780 (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
3781 length($val) ne 4)) {
3782 ERROR("NON_OCTAL_PERMISSIONS",
3783 "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
3790 # If we have no input at all, then there is nothing to report on
3791 # so just keep quiet.
3792 if ($#rawlines == -1) {
3793 exit(0);
3796 # In mailback mode only produce a report in the negative, for
3797 # things that appear to be patches.
3798 if ($mailback && ($clean == 1 || !$is_patch)) {
3799 exit(0);
3802 # This is not a patch, and we are are in 'no-patch' mode so
3803 # just keep quiet.
3804 if (!$chk_patch && !$is_patch) {
3805 exit(0);
3808 if (!$is_patch) {
3809 ERROR("NOT_UNIFIED_DIFF",
3810 "Does not appear to be a unified-diff format patch\n");
3813 print report_dump();
3814 if ($summary && !($clean == 1 && $quiet == 1)) {
3815 print "$filename " if ($summary_file);
3816 print "total: $cnt_error errors, $cnt_warn warnings, " .
3817 (($check)? "$cnt_chk checks, " : "") .
3818 "$cnt_lines lines checked\n";
3819 print "\n" if ($quiet == 0);
3822 if ($quiet == 0) {
3824 if ($^V lt 5.10.0) {
3825 print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
3826 print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
3829 # If there were whitespace errors which cleanpatch can fix
3830 # then suggest that.
3831 if ($rpt_cleaners) {
3832 print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
3833 print " scripts/cleanfile\n\n";
3834 $rpt_cleaners = 0;
3838 hash_show_words(\%use_type, "Used");
3839 hash_show_words(\%ignore_type, "Ignored");
3841 if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
3842 my $newfile = $filename;
3843 $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
3844 my $linecount = 0;
3845 my $f;
3847 open($f, '>', $newfile)
3848 or die "$P: Can't open $newfile for write\n";
3849 foreach my $fixed_line (@fixed) {
3850 $linecount++;
3851 if ($file) {
3852 if ($linecount > 3) {
3853 $fixed_line =~ s/^\+//;
3854 print $f $fixed_line. "\n";
3856 } else {
3857 print $f $fixed_line . "\n";
3860 close($f);
3862 if (!$quiet) {
3863 print << "EOM";
3864 Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
3866 Do _NOT_ trust the results written to this file.
3867 Do _NOT_ submit these changes without inspecting them for correctness.
3869 This EXPERIMENTAL file is simply a convenience to help rewrite patches.
3870 No warranties, expressed or implied...
3876 if ($clean == 1 && $quiet == 0) {
3877 print "$vname has no obvious style problems and is ready for submission.\n"
3879 if ($clean == 0 && $quiet == 0) {
3880 print << "EOM";
3881 $vname has style problems, please review.
3886 return $clean;