aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/checkpatch.pl
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@shadowen.org>2007-11-28 19:21:06 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-29 12:24:51 -0500
commit8905a67c63ff3facadad10aa53a8bb159f3ace7b (patch)
tree5b2d6ff6aeb51098dc91edf90ae10c955f1a0016 /scripts/checkpatch.pl
parentbb0851ff9dc65dd9c9365fdb87895d98235ac463 (diff)
update checkpatch.pl to version 0.12
This version brings a new terse output mode as well as many improvements to the unary detection and bare type regcognition. It also brings the usual updates for false positives, though these seem to be slowing markedly now that the unary detector is no longer just putting its finger in the air and guessing. Of note: - new --terse mode producing a single line per report - loosening of the block brace checks - new checks for enum/union/struch brace placements - hugely expanded "bare type" detection - checks for inline usage - better handling of already open comment blocks - handle patches which introduce or remove lines without newlines Andy Whitcroft (19): Version: 0.12 style fixes as spotted by checkpatch add a --terse options of a single line of output per report block brace checks should only apply for single line blocks all new bare type detector check spacing for open braces with enum, union and struct check for LINUX_VERSION_CODE macros definition bracketing checks need to ignore -ve context clean up the mail-back mode, -q et al expand possible type matching to declarations allow const and sparse annotations on possible types handle possible types as regular types everywhere prefer plain inline over __inline__ and __inline all new open comment detection fix up conditional extraction for if assignment checks add const to the possible type matcher unary checks: a for loop is a conditional too possible types: detect function pointer definitions handle missind newlines at end of file, report addition Signed-off-by: Andy Whitcroft <apw@shadowen.org> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts/checkpatch.pl')
-rwxr-xr-xscripts/checkpatch.pl395
1 files changed, 287 insertions, 108 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index cbb42580a81d..579f50fa838c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@ use strict;
9my $P = $0; 9my $P = $0;
10$P =~ s@.*/@@g; 10$P =~ s@.*/@@g;
11 11
12my $V = '0.11'; 12my $V = '0.12';
13 13
14use Getopt::Long qw(:config no_auto_abbrev); 14use Getopt::Long qw(:config no_auto_abbrev);
15 15
@@ -19,8 +19,11 @@ my $chk_signoff = 1;
19my $chk_patch = 1; 19my $chk_patch = 1;
20my $tst_type = 0; 20my $tst_type = 0;
21my $emacs = 0; 21my $emacs = 0;
22my $terse = 0;
22my $file = 0; 23my $file = 0;
23my $check = 0; 24my $check = 0;
25my $summary = 1;
26my $mailback = 0;
24my $root; 27my $root;
25GetOptions( 28GetOptions(
26 'q|quiet+' => \$quiet, 29 'q|quiet+' => \$quiet,
@@ -29,10 +32,13 @@ GetOptions(
29 'patch!' => \$chk_patch, 32 'patch!' => \$chk_patch,
30 'test-type!' => \$tst_type, 33 'test-type!' => \$tst_type,
31 'emacs!' => \$emacs, 34 'emacs!' => \$emacs,
35 'terse!' => \$terse,
32 'file!' => \$file, 36 'file!' => \$file,
33 'subjective!' => \$check, 37 'subjective!' => \$check,
34 'strict!' => \$check, 38 'strict!' => \$check,
35 'root=s' => \$root, 39 'root=s' => \$root,
40 'summary!' => \$summary,
41 'mailback!' => \$mailback,
36) or exit; 42) or exit;
37 43
38my $exit = 0; 44my $exit = 0;
@@ -42,6 +48,7 @@ if ($#ARGV < 0) {
42 print "version: $V\n"; 48 print "version: $V\n";
43 print "options: -q => quiet\n"; 49 print "options: -q => quiet\n";
44 print " --no-tree => run without a kernel tree\n"; 50 print " --no-tree => run without a kernel tree\n";
51 print " --terse => one line per report\n";
45 print " --emacs => emacs compile window format\n"; 52 print " --emacs => emacs compile window format\n";
46 print " --file => check a source file\n"; 53 print " --file => check a source file\n";
47 print " --strict => enable more subjective tests\n"; 54 print " --strict => enable more subjective tests\n";
@@ -49,6 +56,11 @@ if ($#ARGV < 0) {
49 exit(1); 56 exit(1);
50} 57}
51 58
59if ($terse) {
60 $emacs = 1;
61 $quiet++;
62}
63
52if ($tree) { 64if ($tree) {
53 if (defined $root) { 65 if (defined $root) {
54 if (!top_of_kernel_tree($root)) { 66 if (!top_of_kernel_tree($root)) {
@@ -90,41 +102,6 @@ our $Attribute = qr{
90 __(?:mem|cpu|dev|)(?:initdata|init) 102 __(?:mem|cpu|dev|)(?:initdata|init)
91 }x; 103 }x;
92our $Inline = qr{inline|__always_inline|noinline}; 104our $Inline = qr{inline|__always_inline|noinline};
93our $NonptrType = qr{
94 \b
95 (?:const\s+)?
96 (?:unsigned\s+)?
97 (?:
98 void|
99 char|
100 short|
101 int|
102 long|
103 unsigned|
104 float|
105 double|
106 bool|
107 long\s+int|
108 long\s+long|
109 long\s+long\s+int|
110 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
111 struct\s+$Ident|
112 union\s+$Ident|
113 enum\s+$Ident|
114 ${Ident}_t|
115 ${Ident}_handler|
116 ${Ident}_handler_fn
117 )
118 (?:\s+$Sparse)*
119 \b
120 }x;
121
122our $Type = qr{
123 \b$NonptrType\b
124 (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
125 (?:\s+$Sparse|\s+$Attribute)*
126 }x;
127our $Declare = qr{(?:$Storage\s+)?$Type};
128our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 105our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
129our $Lval = qr{$Ident(?:$Member)*}; 106our $Lval = qr{$Ident(?:$Member)*};
130 107
@@ -136,7 +113,50 @@ our $Operators = qr{
136 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ 113 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
137 }x; 114 }x;
138 115
139our $Bare = ''; 116our $NonptrType;
117our $Type;
118our $Declare;
119
120our @typeList = (
121 qr{void},
122 qr{char},
123 qr{short},
124 qr{int},
125 qr{long},
126 qr{unsigned},
127 qr{float},
128 qr{double},
129 qr{bool},
130 qr{long\s+int},
131 qr{long\s+long},
132 qr{long\s+long\s+int},
133 qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
134 qr{struct\s+$Ident},
135 qr{union\s+$Ident},
136 qr{enum\s+$Ident},
137 qr{${Ident}_t},
138 qr{${Ident}_handler},
139 qr{${Ident}_handler_fn},
140);
141
142sub build_types {
143 my $all = "(?: \n" . join("|\n ", @typeList) . "\n)";
144 $NonptrType = qr{
145 \b
146 (?:const\s+)?
147 (?:unsigned\s+)?
148 $all
149 (?:\s+$Sparse|\s+const)*
150 \b
151 }x;
152 $Type = qr{
153 \b$NonptrType\b
154 (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
155 (?:\s+$Sparse|\s+$Attribute)*
156 }x;
157 $Declare = qr{(?:$Storage\s+)?$Type};
158}
159build_types();
140 160
141$chk_signoff = 0 if ($file); 161$chk_signoff = 0 if ($file);
142 162
@@ -278,6 +298,81 @@ sub sanitise_line {
278 return $res; 298 return $res;
279} 299}
280 300
301sub ctx_statement_block {
302 my ($linenr, $remain, $off) = @_;
303 my $line = $linenr - 1;
304 my $blk = '';
305 my $soff = $off;
306 my $coff = $off - 1;
307
308 my $type = '';
309 my $level = 0;
310 my $c;
311 my $len = 0;
312 while (1) {
313 #warn "CSB: blk<$blk>\n";
314 # If we are about to drop off the end, pull in more
315 # context.
316 if ($off >= $len) {
317 for (; $remain > 0; $line++) {
318 next if ($rawlines[$line] =~ /^-/);
319 $remain--;
320 $blk .= sanitise_line($rawlines[$line]) . "\n";
321 $len = length($blk);
322 $line++;
323 last;
324 }
325 # Bail if there is no further context.
326 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
327 if ($off == $len) {
328 last;
329 }
330 }
331 $c = substr($blk, $off, 1);
332
333 #warn "CSB: c<$c> type<$type> level<$level>\n";
334 # Statement ends at the ';' or a close '}' at the
335 # outermost level.
336 if ($level == 0 && $c eq ';') {
337 last;
338 }
339
340 if (($type eq '' || $type eq '(') && $c eq '(') {
341 $level++;
342 $type = '(';
343 }
344 if ($type eq '(' && $c eq ')') {
345 $level--;
346 $type = ($level != 0)? '(' : '';
347
348 if ($level == 0 && $coff < $soff) {
349 $coff = $off;
350 }
351 }
352 if (($type eq '' || $type eq '{') && $c eq '{') {
353 $level++;
354 $type = '{';
355 }
356 if ($type eq '{' && $c eq '}') {
357 $level--;
358 $type = ($level != 0)? '{' : '';
359
360 if ($level == 0) {
361 last;
362 }
363 }
364 $off++;
365 }
366
367 my $statement = substr($blk, $soff, $off - $soff + 1);
368 my $condition = substr($blk, $soff, $coff - $soff + 1);
369
370 #warn "STATEMENT<$statement>\n";
371 #warn "CONDITION<$condition>\n";
372
373 return ($statement, $condition);
374}
375
281sub ctx_block_get { 376sub ctx_block_get {
282 my ($linenr, $remain, $outer, $open, $close, $off) = @_; 377 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
283 my $line; 378 my $line;
@@ -421,9 +516,6 @@ sub annotate_values {
421 my $paren = 0; 516 my $paren = 0;
422 my @paren_type; 517 my @paren_type;
423 518
424 # Include any user defined types we may have found as we went.
425 my $type_match = "(?:$Type$Bare)";
426
427 while (length($cur)) { 519 while (length($cur)) {
428 print " <$type> " if ($debug); 520 print " <$type> " if ($debug);
429 if ($cur =~ /^(\s+)/o) { 521 if ($cur =~ /^(\s+)/o) {
@@ -433,7 +525,7 @@ sub annotate_values {
433 $type = 'N'; 525 $type = 'N';
434 } 526 }
435 527
436 } elsif ($cur =~ /^($type_match)/) { 528 } elsif ($cur =~ /^($Type)/) {
437 print "DECLARE($1)\n" if ($debug); 529 print "DECLARE($1)\n" if ($debug);
438 $type = 'T'; 530 $type = 'T';
439 531
@@ -457,7 +549,7 @@ sub annotate_values {
457 } 549 }
458 $type = 'N'; 550 $type = 'N';
459 551
460 } elsif ($cur =~ /^(if|while|typeof)\b/o) { 552 } elsif ($cur =~ /^(if|while|typeof|for)\b/o) {
461 print "COND($1)\n" if ($debug); 553 print "COND($1)\n" if ($debug);
462 $paren_type[$paren] = 'N'; 554 $paren_type[$paren] = 'N';
463 $type = 'N'; 555 $type = 'N';
@@ -515,11 +607,30 @@ sub annotate_values {
515 return $res; 607 return $res;
516} 608}
517 609
610sub possible {
611 my ($possible) = @_;
612
613 #print "CHECK<$possible>\n";
614 if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
615 $possible ne 'goto' && $possible ne 'return' &&
616 $possible ne 'struct' && $possible ne 'enum' &&
617 $possible ne 'case' && $possible ne 'else' &&
618 $possible ne 'typedef') {
619 #print "POSSIBLE<$possible>\n";
620 push(@typeList, $possible);
621 build_types();
622 }
623}
624
518my $prefix = ''; 625my $prefix = '';
519 626
520my @report = (); 627my @report = ();
521sub report { 628sub report {
522 push(@report, $prefix . $_[0]); 629 my $line = $prefix . $_[0];
630
631 $line = (split('\n', $line))[0] . "\n" if ($terse);
632
633 push(@report, $line);
523} 634}
524sub report_dump { 635sub report_dump {
525 @report; 636 @report;
@@ -574,9 +685,6 @@ sub process {
574 685
575 my $prev_values = 'N'; 686 my $prev_values = 'N';
576 687
577 # Possible bare types.
578 my @bare = ();
579
580 # Pre-scan the patch looking for any __setup documentation. 688 # Pre-scan the patch looking for any __setup documentation.
581 my @setup_docs = (); 689 my @setup_docs = ();
582 my $setup_docs = 0; 690 my $setup_docs = 0;
@@ -631,21 +739,35 @@ sub process {
631 $realline++; 739 $realline++;
632 $realcnt-- if ($realcnt != 0); 740 $realcnt-- if ($realcnt != 0);
633 741
634 # track any sort of multi-line comment. Obviously if 742 # Guestimate if this is a continuing comment. Run
635 # the added text or context do not include the whole 743 # the context looking for a comment "edge". If this
636 # comment we will not see it. Such is life. 744 # edge is a close comment then we must be in a comment
637 # 745 # at context start.
746 if ($linenr == $first_line) {
747 my $edge;
748 for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) {
749 ($edge) = ($lines[$ln - 1] =~ m@(/\*|\*/)@);
750 last if (defined $edge);
751 }
752 if (defined $edge && $edge eq '*/') {
753 $in_comment = 1;
754 }
755 }
756
638 # Guestimate if this is a continuing comment. If this 757 # Guestimate if this is a continuing comment. If this
639 # is the start of a diff block and this line starts 758 # is the start of a diff block and this line starts
640 # ' *' then it is very likely a comment. 759 # ' *' then it is very likely a comment.
641 if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 760 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
642 $in_comment = 1; 761 $in_comment = 1;
643 } 762 }
644 if ($line =~ m@/\*@) { 763
645 $in_comment = 1; 764 # Find the last comment edge on _this_ line.
646 } 765 while (($line =~ m@(/\*|\*/)@g)) {
647 if ($line =~ m@\*/@) { 766 if ($1 eq '/*') {
648 $in_comment = 0; 767 $in_comment = 1;
768 } else {
769 $in_comment = 0;
770 }
649 } 771 }
650 772
651 # Measure the line length and indent. 773 # Measure the line length and indent.
@@ -687,7 +809,7 @@ sub process {
687 } 809 }
688 810
689# Check for wrappage within a valid hunk of the file 811# Check for wrappage within a valid hunk of the file
690 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { 812 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
691 ERROR("patch seems to be corrupt (line wrapped?)\n" . 813 ERROR("patch seems to be corrupt (line wrapped?)\n" .
692 $herecurr) if (!$emitted_corrupt++); 814 $herecurr) if (!$emitted_corrupt++);
693 } 815 }
@@ -727,6 +849,11 @@ sub process {
727 WARN("line over 80 characters\n" . $herecurr); 849 WARN("line over 80 characters\n" . $herecurr);
728 } 850 }
729 851
852# check for adding lines without a newline.
853 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
854 WARN("adding a line without newline at end of file\n" . $herecurr);
855 }
856
730# check we are in a valid source file *.[hc] if not then ignore this hunk 857# check we are in a valid source file *.[hc] if not then ignore this hunk
731 next if ($realfile !~ /\.[hc]$/); 858 next if ($realfile !~ /\.[hc]$/);
732 859
@@ -752,30 +879,41 @@ sub process {
752 879
753# Check for potential 'bare' types 880# Check for potential 'bare' types
754 if ($realcnt && 881 if ($realcnt &&
755 $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ &&
756 $line !~ /$Ident:\s*$/ && 882 $line !~ /$Ident:\s*$/ &&
757 $line !~ /^.\s*$Ident\s*\(/ && 883 ($line =~ /^.\s*$Ident\s*\(\*+\s*$Ident\)\s*\(/ ||
758 # definitions in global scope can only start with types 884 $line !~ /^.\s*$Ident\s*\(/)) {
759 ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || 885 # definitions in global scope can only start with types
760 # declarations always start with types 886 if ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
761 $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) || 887 possible($1);
762 # any (foo ... *) is a pointer cast, and foo is a type 888
763 $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) { 889 # declarations always start with types
764 my $possible = $1; 890 } elsif ($prev_values eq 'N' && $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) {
765 if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && 891 possible($1);
766 $possible ne 'goto' && $possible ne 'return' && 892
767 $possible ne 'struct' && $possible ne 'enum' && 893 # any (foo ... *) is a pointer cast, and foo is a type
768 $possible ne 'case' && $possible ne 'else' && 894 } elsif ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
769 $possible ne 'typedef') { 895 possible($1);
770 #print "POSSIBLE<$possible>\n"; 896 }
771 push(@bare, $possible); 897
772 my $bare = join("|", @bare); 898 # Check for any sort of function declaration.
773 $Bare = '|' . qr{ 899 # int foo(something bar, other baz);
774 \b(?:$bare)\b 900 # void (*store_gdt)(x86_descr_ptr *);
775 (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? 901 if ($prev_values eq 'N' && $line =~ /^(.(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
776 (?:\s+$Sparse)* 902 my ($name_len) = length($1);
777 }x; 903 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len);
904 my $ctx = join("\n", @ctx);
905
906 $ctx =~ s/\n.//;
907 substr($ctx, 0, $name_len + 1) = '';
908 $ctx =~ s/\)[^\)]*$//;
909 for my $arg (split(/\s*,\s*/, $ctx)) {
910 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) {
911
912 possible($1);
913 }
914 }
778 } 915 }
916
779 } 917 }
780 918
781# 919#
@@ -935,6 +1073,10 @@ sub process {
935# $clean = 0; 1073# $clean = 0;
936# } 1074# }
937 1075
1076 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
1077 WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged" . $herecurr);
1078 }
1079
938# printk should use KERN_* levels. Note that follow on printk's on the 1080# printk should use KERN_* levels. Note that follow on printk's on the
939# same line do not need a level, so we use the current block context 1081# same line do not need a level, so we use the current block context
940# to try and find and validate the current printk. In summary the current 1082# to try and find and validate the current printk. In summary the current
@@ -965,6 +1107,12 @@ sub process {
965 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 1107 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr);
966 } 1108 }
967 1109
1110# open braces for enum, union and struct go on the same line.
1111 if ($line =~ /^.\s*{/ &&
1112 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
1113 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
1114 }
1115
968# check for spaces between functions and their parentheses. 1116# check for spaces between functions and their parentheses.
969 while ($line =~ /($Ident)\s+\(/g) { 1117 while ($line =~ /($Ident)\s+\(/g) {
970 if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ && 1118 if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ &&
@@ -1172,9 +1320,27 @@ sub process {
1172 } 1320 }
1173 1321
1174# Check for illegal assignment in if conditional. 1322# Check for illegal assignment in if conditional.
1175 if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) { 1323 if ($line =~ /\bif\s*\(/) {
1176 #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); 1324 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
1177 ERROR("do not use assignment in if condition\n" . $herecurr); 1325
1326 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
1327 ERROR("do not use assignment in if condition ($c)\n" . $herecurr);
1328 }
1329
1330 # Find out what is on the end of the line after the
1331 # conditional.
1332 substr($s, 0, length($c)) = '';
1333 $s =~ s/\n.*//g;
1334
1335 if (length($c) && $s !~ /^\s*({|;|\/\*.*\*\/)?\s*\\*\s*$/) {
1336 ERROR("trailing statements should be on next line\n" . $herecurr);
1337 }
1338 }
1339
1340# if and else should not have general statements after it
1341 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ &&
1342 $1 !~ /^\s*(?:\sif|{|\\|$)/) {
1343 ERROR("trailing statements should be on next line\n" . $herecurr);
1178 } 1344 }
1179 1345
1180 # Check for }<nl>else {, these must be at the same 1346 # Check for }<nl>else {, these must be at the same
@@ -1205,12 +1371,6 @@ sub process {
1205 } 1371 }
1206 } 1372 }
1207 1373
1208# if and else should not have general statements after it
1209 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/ &&
1210 $1 !~ /^\s*(?:\sif|{|\\|$)/) {
1211 ERROR("trailing statements should be on next line\n" . $herecurr);
1212 }
1213
1214# multi-statement macros should be enclosed in a do while loop, grab the 1374# multi-statement macros should be enclosed in a do while loop, grab the
1215# first statement and ensure its the whole macro if its not enclosed 1375# first statement and ensure its the whole macro if its not enclosed
1216# in a known goot container 1376# in a known goot container
@@ -1233,6 +1393,10 @@ sub process {
1233 $off = length($1); 1393 $off = length($1);
1234 $ln--; 1394 $ln--;
1235 $cnt++; 1395 $cnt++;
1396 while ($lines[$ln - 1] =~ /^-/) {
1397 $ln--;
1398 $cnt++;
1399 }
1236 } 1400 }
1237 my @ctx = ctx_statement($ln, $cnt, $off); 1401 my @ctx = ctx_statement($ln, $cnt, $off);
1238 my $ctx_ln = $ln + $#ctx + 1; 1402 my $ctx_ln = $ln + $#ctx + 1;
@@ -1268,25 +1432,23 @@ sub process {
1268 if ($lines[$nr - 1] =~ /{\s*$/) { 1432 if ($lines[$nr - 1] =~ /{\s*$/) {
1269 my ($lvl, @block) = ctx_block_level($nr, $cnt); 1433 my ($lvl, @block) = ctx_block_level($nr, $cnt);
1270 1434
1271 my $stmt = join(' ', @block); 1435 my $stmt = join("\n", @block);
1272 $stmt =~ s/(^[^{]*){//; 1436 # Drop the diff line leader.
1437 $stmt =~ s/\n./\n/g;
1438 # Drop the code outside the block.
1439 $stmt =~ s/(^[^{]*){\s*//;
1273 my $before = $1; 1440 my $before = $1;
1274 $stmt =~ s/}([^}]*$)//; 1441 $stmt =~ s/\s*}([^}]*$)//;
1275 my $after = $1; 1442 my $after = $1;
1276 1443
1277 #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; 1444 #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
1278 #print "stmt<$stmt>\n\n"; 1445 #print "stmt<$stmt>\n\n";
1279 1446
1280 # Count the ;'s if there is fewer than two 1447 # Count the newlines, if there is only one
1281 # then there can only be one statement, 1448 # then the block should not have {}'s.
1282 # if there is a brace inside we cannot 1449 my @lines = ($stmt =~ /\n/g);
1283 # trivially detect if its one statement. 1450 #print "lines<" . scalar(@lines) . ">\n";
1284 # Also nested if's often require braces to 1451 if ($lvl == 0 && scalar(@lines) == 0 &&
1285 # disambiguate the else binding so shhh there.
1286 my @semi = ($stmt =~ /;/g);
1287 push(@semi, "/**/") if ($stmt =~ m@/\*@);
1288 ##print "semi<" . scalar(@semi) . ">\n";
1289 if ($lvl == 0 && scalar(@semi) < 2 &&
1290 $stmt !~ /{/ && $stmt !~ /\bif\b/ && 1452 $stmt !~ /{/ && $stmt !~ /\bif\b/ &&
1291 $before !~ /}/ && $after !~ /{/) { 1453 $before !~ /}/ && $after !~ /{/) {
1292 my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; 1454 my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
@@ -1372,6 +1534,11 @@ sub process {
1372 ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 1534 ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
1373 } 1535 }
1374 1536
1537# Check for __inline__ and __inline, prefer inline
1538 if ($line =~ /\b(__inline__|__inline)\b/) {
1539 WARN("plain inline is preferred over $1\n" . $herecurr);
1540 }
1541
1375# check for new externs in .c files. 1542# check for new externs in .c files.
1376 if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) { 1543 if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) {
1377 WARN("externs should be avoided in .c files\n" . $herecurr); 1544 WARN("externs should be avoided in .c files\n" . $herecurr);
@@ -1392,21 +1559,33 @@ sub process {
1392 } 1559 }
1393 } 1560 }
1394 1561
1395 if ($chk_patch && !$is_patch) { 1562 # In mailback mode only produce a report in the negative, for
1563 # things that appear to be patches.
1564 if ($mailback && ($clean == 1 || !$is_patch)) {
1565 exit(0);
1566 }
1567
1568 # This is not a patch, and we are are in 'no-patch' mode so
1569 # just keep quiet.
1570 if (!$chk_patch && !$is_patch) {
1571 exit(0);
1572 }
1573
1574 if (!$is_patch) {
1396 ERROR("Does not appear to be a unified-diff format patch\n"); 1575 ERROR("Does not appear to be a unified-diff format patch\n");
1397 } 1576 }
1398 if ($is_patch && $chk_signoff && $signoff == 0) { 1577 if ($is_patch && $chk_signoff && $signoff == 0) {
1399 ERROR("Missing Signed-off-by: line(s)\n"); 1578 ERROR("Missing Signed-off-by: line(s)\n");
1400 } 1579 }
1401 1580
1402 if ($clean == 0 && ($chk_patch || $is_patch)) { 1581 print report_dump();
1403 print report_dump(); 1582 if ($summary) {
1404 if ($quiet < 2) { 1583 print "total: $cnt_error errors, $cnt_warn warnings, " .
1405 print "total: $cnt_error errors, $cnt_warn warnings, " . 1584 (($check)? "$cnt_chk checks, " : "") .
1406 (($check)? "$cnt_chk checks, " : "") . 1585 "$cnt_lines lines checked\n";
1407 "$cnt_lines lines checked\n"; 1586 print "\n" if ($quiet == 0);
1408 }
1409 } 1587 }
1588
1410 if ($clean == 1 && $quiet == 0) { 1589 if ($clean == 1 && $quiet == 0) {
1411 print "Your patch has no obvious style problems and is ready for submission.\n" 1590 print "Your patch has no obvious style problems and is ready for submission.\n"
1412 } 1591 }