diff options
author | Andy Whitcroft <apw@shadowen.org> | 2007-10-18 06:05:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-18 17:37:21 -0400 |
commit | 6c72ffaab9851e3ee380c77169c0cfcba6b58d4c (patch) | |
tree | 98e4ec5d3336ecc3cf954a9c90d4a098ca28dc0a /scripts | |
parent | faf8c714f4508207a9c81cc94dafc76ed6680b44 (diff) |
update checkpatch.pl to version 0.11
This version brings a more cautious checkpatch.pl by default. The more
subjective checks are only applied with the --strict option. It also
brings the usual slew of corrections for false positives. Of note:
- new tree detection, the source tree will be found via the executable
- a major revamp of the unary detection to make it more parser like
- a new summary at the bottom of the report
- --strict option for subjective checks
- --file to enable checking on complete files
- support for use in emacs "compile" window
Andy Whitcroft (27):
Version: 0.11
fix up cat_vet for the case where there are no control characters
any cast to a pointer introduces a type
cpp unary operator detection needs to float
attributes are also valid in type definitions
sizeof may be a bareword and makes its argument unary
unary checks for #ifdef et al need to find end of line
add new --file mode to handle raw source files
add --strict/--subjective which enables the subjective tests
add some additional standard type suffixes
cpp #elif is also a unary prefix
case is not a function name
widen asm volatile exceptions
__kprobes is a type attribute
typeof is a unary operator
function open parenthesis checks should check all occurances
expand sizeof() binary exceptions
linux/irq.h should not be recommended
work harder to find the kernel root and add --root=
fix --emacs mode line numbers and string concatenation warnings
add a summary to the bottom of the main report
loosen assignment in if checks
update operator spacing to maintain tabs in output
revamp unary detection
corruption/line wrapped patches need only reporting once
revamp s/u/be/le 8/16/32/64 bit types
handle missing ,1 in uni-diff header
Mike D. Day (2):
Adds support to checkpatch.pl for running in the emacs compile window.
checkpatch: Fix line number reporting
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/checkpatch.pl | 514 |
1 files changed, 340 insertions, 174 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 59ad83caa210..cbb42580a81d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -9,7 +9,7 @@ use strict; | |||
9 | my $P = $0; | 9 | my $P = $0; |
10 | $P =~ s@.*/@@g; | 10 | $P =~ s@.*/@@g; |
11 | 11 | ||
12 | my $V = '0.10'; | 12 | my $V = '0.11'; |
13 | 13 | ||
14 | use Getopt::Long qw(:config no_auto_abbrev); | 14 | use Getopt::Long qw(:config no_auto_abbrev); |
15 | 15 | ||
@@ -18,12 +18,21 @@ my $tree = 1; | |||
18 | my $chk_signoff = 1; | 18 | my $chk_signoff = 1; |
19 | my $chk_patch = 1; | 19 | my $chk_patch = 1; |
20 | my $tst_type = 0; | 20 | my $tst_type = 0; |
21 | my $emacs = 0; | ||
22 | my $file = 0; | ||
23 | my $check = 0; | ||
24 | my $root; | ||
21 | GetOptions( | 25 | GetOptions( |
22 | 'q|quiet' => \$quiet, | 26 | 'q|quiet+' => \$quiet, |
23 | 'tree!' => \$tree, | 27 | 'tree!' => \$tree, |
24 | 'signoff!' => \$chk_signoff, | 28 | 'signoff!' => \$chk_signoff, |
25 | 'patch!' => \$chk_patch, | 29 | 'patch!' => \$chk_patch, |
26 | 'test-type!' => \$tst_type, | 30 | 'test-type!' => \$tst_type, |
31 | 'emacs!' => \$emacs, | ||
32 | 'file!' => \$file, | ||
33 | 'subjective!' => \$check, | ||
34 | 'strict!' => \$check, | ||
35 | 'root=s' => \$root, | ||
27 | ) or exit; | 36 | ) or exit; |
28 | 37 | ||
29 | my $exit = 0; | 38 | my $exit = 0; |
@@ -33,19 +42,110 @@ if ($#ARGV < 0) { | |||
33 | print "version: $V\n"; | 42 | print "version: $V\n"; |
34 | print "options: -q => quiet\n"; | 43 | print "options: -q => quiet\n"; |
35 | print " --no-tree => run without a kernel tree\n"; | 44 | print " --no-tree => run without a kernel tree\n"; |
45 | print " --emacs => emacs compile window format\n"; | ||
46 | print " --file => check a source file\n"; | ||
47 | print " --strict => enable more subjective tests\n"; | ||
48 | print " --root => path to the kernel tree root\n"; | ||
36 | exit(1); | 49 | exit(1); |
37 | } | 50 | } |
38 | 51 | ||
39 | if ($tree && !top_of_kernel_tree()) { | 52 | if ($tree) { |
40 | print "Must be run from the top-level dir. of a kernel tree\n"; | 53 | if (defined $root) { |
41 | exit(2); | 54 | if (!top_of_kernel_tree($root)) { |
55 | die "$P: $root: --root does not point at a valid tree\n"; | ||
56 | } | ||
57 | } else { | ||
58 | if (top_of_kernel_tree('.')) { | ||
59 | $root = '.'; | ||
60 | } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && | ||
61 | top_of_kernel_tree($1)) { | ||
62 | $root = $1; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | if (!defined $root) { | ||
67 | print "Must be run from the top-level dir. of a kernel tree\n"; | ||
68 | exit(2); | ||
69 | } | ||
42 | } | 70 | } |
43 | 71 | ||
72 | my $emitted_corrupt = 0; | ||
73 | |||
74 | our $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; | ||
75 | our $Storage = qr{extern|static|asmlinkage}; | ||
76 | our $Sparse = qr{ | ||
77 | __user| | ||
78 | __kernel| | ||
79 | __force| | ||
80 | __iomem| | ||
81 | __must_check| | ||
82 | __init_refok| | ||
83 | __kprobes| | ||
84 | fastcall | ||
85 | }x; | ||
86 | our $Attribute = qr{ | ||
87 | const| | ||
88 | __read_mostly| | ||
89 | __kprobes| | ||
90 | __(?:mem|cpu|dev|)(?:initdata|init) | ||
91 | }x; | ||
92 | our $Inline = qr{inline|__always_inline|noinline}; | ||
93 | our $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 | |||
122 | our $Type = qr{ | ||
123 | \b$NonptrType\b | ||
124 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | ||
125 | (?:\s+$Sparse|\s+$Attribute)* | ||
126 | }x; | ||
127 | our $Declare = qr{(?:$Storage\s+)?$Type}; | ||
128 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | ||
129 | our $Lval = qr{$Ident(?:$Member)*}; | ||
130 | |||
131 | our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; | ||
132 | our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; | ||
133 | our $Operators = qr{ | ||
134 | <=|>=|==|!=| | ||
135 | =>|->|<<|>>|<|>|!|~| | ||
136 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ | ||
137 | }x; | ||
138 | |||
139 | our $Bare = ''; | ||
140 | |||
141 | $chk_signoff = 0 if ($file); | ||
142 | |||
44 | my @dep_includes = (); | 143 | my @dep_includes = (); |
45 | my @dep_functions = (); | 144 | my @dep_functions = (); |
46 | my $removal = 'Documentation/feature-removal-schedule.txt'; | 145 | my $removal = "Documentation/feature-removal-schedule.txt"; |
47 | if ($tree && -f $removal) { | 146 | if ($tree && -f "$root/$removal") { |
48 | open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; | 147 | open(REMOVE, "<$root/$removal") || |
148 | die "$P: $removal: open failed - $!\n"; | ||
49 | while (<REMOVE>) { | 149 | while (<REMOVE>) { |
50 | if (/^Check:\s+(.*\S)/) { | 150 | if (/^Check:\s+(.*\S)/) { |
51 | for my $entry (split(/[, ]+/, $1)) { | 151 | for my $entry (split(/[, ]+/, $1)) { |
@@ -61,28 +161,42 @@ if ($tree && -f $removal) { | |||
61 | } | 161 | } |
62 | 162 | ||
63 | my @rawlines = (); | 163 | my @rawlines = (); |
64 | while (<>) { | 164 | for my $filename (@ARGV) { |
65 | chomp; | 165 | if ($file) { |
66 | push(@rawlines, $_); | 166 | open(FILE, "diff -u /dev/null $filename|") || |
67 | if (eof(ARGV)) { | 167 | die "$P: $filename: diff failed - $!\n"; |
68 | if (!process($ARGV, @rawlines)) { | 168 | } else { |
69 | $exit = 1; | 169 | open(FILE, "<$filename") || |
70 | } | 170 | die "$P: $filename: open failed - $!\n"; |
71 | @rawlines = (); | ||
72 | } | 171 | } |
172 | while (<FILE>) { | ||
173 | chomp; | ||
174 | push(@rawlines, $_); | ||
175 | } | ||
176 | close(FILE); | ||
177 | if (!process($filename, @rawlines)) { | ||
178 | $exit = 1; | ||
179 | } | ||
180 | @rawlines = (); | ||
73 | } | 181 | } |
74 | 182 | ||
75 | exit($exit); | 183 | exit($exit); |
76 | 184 | ||
77 | sub top_of_kernel_tree { | 185 | sub top_of_kernel_tree { |
78 | if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") && | 186 | my ($root) = @_; |
79 | (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") && | 187 | |
80 | (-d "Documentation") && (-d "arch") && (-d "include") && | 188 | my @tree_check = ( |
81 | (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") && | 189 | "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", |
82 | (-d "kernel") && (-d "lib") && (-d "scripts")) { | 190 | "README", "Documentation", "arch", "include", "drivers", |
83 | return 1; | 191 | "fs", "init", "ipc", "kernel", "lib", "scripts", |
192 | ); | ||
193 | |||
194 | foreach my $check (@tree_check) { | ||
195 | if (! -e $root . '/' . $check) { | ||
196 | return 0; | ||
197 | } | ||
84 | } | 198 | } |
85 | return 0; | 199 | return 1; |
86 | } | 200 | } |
87 | 201 | ||
88 | sub expand_tabs { | 202 | sub expand_tabs { |
@@ -105,6 +219,20 @@ sub expand_tabs { | |||
105 | 219 | ||
106 | return $res; | 220 | return $res; |
107 | } | 221 | } |
222 | sub copy_spacing { | ||
223 | my ($str) = @_; | ||
224 | |||
225 | my $res = ''; | ||
226 | for my $c (split(//, $str)) { | ||
227 | if ($c eq "\t") { | ||
228 | $res .= $c; | ||
229 | } else { | ||
230 | $res .= ' '; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | return $res; | ||
235 | } | ||
108 | 236 | ||
109 | sub line_stats { | 237 | sub line_stats { |
110 | my ($line) = @_; | 238 | my ($line) = @_; |
@@ -260,47 +388,138 @@ sub ctx_has_comment { | |||
260 | return ($cmt ne ''); | 388 | return ($cmt ne ''); |
261 | } | 389 | } |
262 | 390 | ||
263 | sub ctx_expr_before { | 391 | sub cat_vet { |
264 | my ($line) = @_; | 392 | my ($vet) = @_; |
265 | 393 | my ($res, $coded); | |
266 | ##print "CHECK<$line>\n"; | ||
267 | |||
268 | my $pos = length($line) - 1; | ||
269 | my $count = 0; | ||
270 | my $c; | ||
271 | 394 | ||
272 | for (; $pos >= 0; $pos--) { | 395 | $res = ''; |
273 | $c = substr($line, $pos, 1); | 396 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { |
274 | ##print "CHECK: c<$c> count<$count>\n"; | 397 | $res .= $1; |
275 | if ($c eq ')') { | 398 | if ($2 ne '') { |
276 | $count++; | 399 | $coded = sprintf("^%c", unpack('C', $2) + 64); |
277 | } elsif ($c eq '(') { | 400 | $res .= $coded; |
278 | last if (--$count == 0); | ||
279 | } | 401 | } |
280 | } | 402 | } |
403 | $res =~ s/$/\$/; | ||
281 | 404 | ||
282 | ##print "CHECK: result<" . substr($line, 0, $pos) . ">\n"; | 405 | return $res; |
283 | |||
284 | return substr($line, 0, $pos); | ||
285 | } | 406 | } |
286 | 407 | ||
287 | sub cat_vet { | 408 | sub annotate_values { |
288 | my ($vet) = @_; | 409 | my ($stream, $type) = @_; |
289 | my ($res, $coded); | ||
290 | 410 | ||
291 | $res = ''; | 411 | my $res; |
292 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) { | 412 | my $cur = $stream; |
293 | $coded = sprintf("^%c", unpack('C', $2) + 64); | 413 | |
294 | $res .= $1 . $coded; | 414 | my $debug = 0; |
415 | |||
416 | print "$stream\n" if ($debug); | ||
417 | |||
418 | ##my $type = 'N'; | ||
419 | my $pos = 0; | ||
420 | my $preprocessor = 0; | ||
421 | my $paren = 0; | ||
422 | my @paren_type; | ||
423 | |||
424 | # Include any user defined types we may have found as we went. | ||
425 | my $type_match = "(?:$Type$Bare)"; | ||
426 | |||
427 | while (length($cur)) { | ||
428 | print " <$type> " if ($debug); | ||
429 | if ($cur =~ /^(\s+)/o) { | ||
430 | print "WS($1)\n" if ($debug); | ||
431 | if ($1 =~ /\n/ && $preprocessor) { | ||
432 | $preprocessor = 0; | ||
433 | $type = 'N'; | ||
434 | } | ||
435 | |||
436 | } elsif ($cur =~ /^($type_match)/) { | ||
437 | print "DECLARE($1)\n" if ($debug); | ||
438 | $type = 'T'; | ||
439 | |||
440 | } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { | ||
441 | print "DEFINE($1)\n" if ($debug); | ||
442 | $preprocessor = 1; | ||
443 | $paren_type[$paren] = 'N'; | ||
444 | |||
445 | } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) { | ||
446 | print "PRE($1)\n" if ($debug); | ||
447 | $preprocessor = 1; | ||
448 | $type = 'N'; | ||
449 | |||
450 | } elsif ($cur =~ /^(\\\n)/o) { | ||
451 | print "PRECONT($1)\n" if ($debug); | ||
452 | |||
453 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { | ||
454 | print "SIZEOF($1)\n" if ($debug); | ||
455 | if (defined $2) { | ||
456 | $paren_type[$paren] = 'V'; | ||
457 | } | ||
458 | $type = 'N'; | ||
459 | |||
460 | } elsif ($cur =~ /^(if|while|typeof)\b/o) { | ||
461 | print "COND($1)\n" if ($debug); | ||
462 | $paren_type[$paren] = 'N'; | ||
463 | $type = 'N'; | ||
464 | |||
465 | } elsif ($cur =~/^(return|case|else)/o) { | ||
466 | print "KEYWORD($1)\n" if ($debug); | ||
467 | $type = 'N'; | ||
468 | |||
469 | } elsif ($cur =~ /^(\()/o) { | ||
470 | print "PAREN('$1')\n" if ($debug); | ||
471 | $paren++; | ||
472 | $type = 'N'; | ||
473 | |||
474 | } elsif ($cur =~ /^(\))/o) { | ||
475 | $paren-- if ($paren > 0); | ||
476 | if (defined $paren_type[$paren]) { | ||
477 | $type = $paren_type[$paren]; | ||
478 | undef $paren_type[$paren]; | ||
479 | print "PAREN('$1') -> $type\n" if ($debug); | ||
480 | } else { | ||
481 | print "PAREN('$1')\n" if ($debug); | ||
482 | } | ||
483 | |||
484 | } elsif ($cur =~ /^($Ident)\(/o) { | ||
485 | print "FUNC($1)\n" if ($debug); | ||
486 | $paren_type[$paren] = 'V'; | ||
487 | |||
488 | } elsif ($cur =~ /^($Ident|$Constant)/o) { | ||
489 | print "IDENT($1)\n" if ($debug); | ||
490 | $type = 'V'; | ||
491 | |||
492 | } elsif ($cur =~ /^($Assignment)/o) { | ||
493 | print "ASSIGN($1)\n" if ($debug); | ||
494 | $type = 'N'; | ||
495 | |||
496 | } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { | ||
497 | print "END($1)\n" if ($debug); | ||
498 | $type = 'N'; | ||
499 | |||
500 | } elsif ($cur =~ /^($Operators)/o) { | ||
501 | print "OP($1)\n" if ($debug); | ||
502 | if ($1 ne '++' && $1 ne '--') { | ||
503 | $type = 'N'; | ||
504 | } | ||
505 | |||
506 | } elsif ($cur =~ /(^.)/o) { | ||
507 | print "C($1)\n" if ($debug); | ||
508 | } | ||
509 | if (defined $1) { | ||
510 | $cur = substr($cur, length($1)); | ||
511 | $res .= $type x length($1); | ||
512 | } | ||
295 | } | 513 | } |
296 | $res =~ s/$/\$/; | ||
297 | 514 | ||
298 | return $res; | 515 | return $res; |
299 | } | 516 | } |
300 | 517 | ||
518 | my $prefix = ''; | ||
519 | |||
301 | my @report = (); | 520 | my @report = (); |
302 | sub report { | 521 | sub report { |
303 | push(@report, $_[0]); | 522 | push(@report, $prefix . $_[0]); |
304 | } | 523 | } |
305 | sub report_dump { | 524 | sub report_dump { |
306 | @report; | 525 | @report; |
@@ -308,14 +527,19 @@ sub report_dump { | |||
308 | sub ERROR { | 527 | sub ERROR { |
309 | report("ERROR: $_[0]\n"); | 528 | report("ERROR: $_[0]\n"); |
310 | our $clean = 0; | 529 | our $clean = 0; |
530 | our $cnt_error++; | ||
311 | } | 531 | } |
312 | sub WARN { | 532 | sub WARN { |
313 | report("WARNING: $_[0]\n"); | 533 | report("WARNING: $_[0]\n"); |
314 | our $clean = 0; | 534 | our $clean = 0; |
535 | our $cnt_warn++; | ||
315 | } | 536 | } |
316 | sub CHK { | 537 | sub CHK { |
317 | report("CHECK: $_[0]\n"); | 538 | if ($check) { |
318 | our $clean = 0; | 539 | report("CHECK: $_[0]\n"); |
540 | our $clean = 0; | ||
541 | our $cnt_chk++; | ||
542 | } | ||
319 | } | 543 | } |
320 | 544 | ||
321 | sub process { | 545 | sub process { |
@@ -335,6 +559,11 @@ sub process { | |||
335 | my $signoff = 0; | 559 | my $signoff = 0; |
336 | my $is_patch = 0; | 560 | my $is_patch = 0; |
337 | 561 | ||
562 | our $cnt_lines = 0; | ||
563 | our $cnt_error = 0; | ||
564 | our $cnt_warn = 0; | ||
565 | our $cnt_chk = 0; | ||
566 | |||
338 | # Trace the real file/line as we go. | 567 | # Trace the real file/line as we go. |
339 | my $realfile = ''; | 568 | my $realfile = ''; |
340 | my $realline = 0; | 569 | my $realline = 0; |
@@ -343,62 +572,10 @@ sub process { | |||
343 | my $in_comment = 0; | 572 | my $in_comment = 0; |
344 | my $first_line = 0; | 573 | my $first_line = 0; |
345 | 574 | ||
346 | my $Ident = qr{[A-Za-z\d_]+}; | 575 | my $prev_values = 'N'; |
347 | my $Storage = qr{extern|static|asmlinkage}; | ||
348 | my $Sparse = qr{ | ||
349 | __user| | ||
350 | __kernel| | ||
351 | __force| | ||
352 | __iomem| | ||
353 | __must_check| | ||
354 | __init_refok| | ||
355 | fastcall | ||
356 | }x; | ||
357 | my $Inline = qr{inline|__always_inline|noinline}; | ||
358 | my $NonptrType = qr{ | ||
359 | \b | ||
360 | (?:const\s+)? | ||
361 | (?:unsigned\s+)? | ||
362 | (?: | ||
363 | void| | ||
364 | char| | ||
365 | short| | ||
366 | int| | ||
367 | long| | ||
368 | unsigned| | ||
369 | float| | ||
370 | double| | ||
371 | bool| | ||
372 | long\s+int| | ||
373 | long\s+long| | ||
374 | long\s+long\s+int| | ||
375 | u8|u16|u32|u64| | ||
376 | s8|s16|s32|s64| | ||
377 | struct\s+$Ident| | ||
378 | union\s+$Ident| | ||
379 | enum\s+$Ident| | ||
380 | ${Ident}_t | ||
381 | ) | ||
382 | (?:\s+$Sparse)* | ||
383 | \b | ||
384 | }x; | ||
385 | my $Type = qr{ | ||
386 | \b$NonptrType\b | ||
387 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | ||
388 | (?:\s+$Sparse)* | ||
389 | }x; | ||
390 | my $Declare = qr{(?:$Storage\s+)?$Type}; | ||
391 | my $Attribute = qr{ | ||
392 | const| | ||
393 | __read_mostly| | ||
394 | __(?:mem|cpu|dev|)(?:initdata|init) | ||
395 | }x; | ||
396 | my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | ||
397 | my $Lval = qr{$Ident(?:$Member)*}; | ||
398 | 576 | ||
399 | # Possible bare types. | 577 | # Possible bare types. |
400 | my @bare = (); | 578 | my @bare = (); |
401 | my $Bare = $NonptrType; | ||
402 | 579 | ||
403 | # Pre-scan the patch looking for any __setup documentation. | 580 | # Pre-scan the patch looking for any __setup documentation. |
404 | my @setup_docs = (); | 581 | my @setup_docs = (); |
@@ -417,11 +594,14 @@ sub process { | |||
417 | } | 594 | } |
418 | } | 595 | } |
419 | 596 | ||
597 | $prefix = ''; | ||
598 | |||
420 | foreach my $line (@lines) { | 599 | foreach my $line (@lines) { |
421 | $linenr++; | 600 | $linenr++; |
422 | 601 | ||
423 | my $rawline = $line; | 602 | my $rawline = $line; |
424 | 603 | ||
604 | |||
425 | #extract the filename as it passes | 605 | #extract the filename as it passes |
426 | if ($line=~/^\+\+\+\s+(\S+)/) { | 606 | if ($line=~/^\+\+\+\s+(\S+)/) { |
427 | $realfile=$1; | 607 | $realfile=$1; |
@@ -430,7 +610,7 @@ sub process { | |||
430 | next; | 610 | next; |
431 | } | 611 | } |
432 | #extract the line range in the file after the patch is applied | 612 | #extract the line range in the file after the patch is applied |
433 | if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { | 613 | if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { |
434 | $is_patch = 1; | 614 | $is_patch = 1; |
435 | $first_line = $linenr + 1; | 615 | $first_line = $linenr + 1; |
436 | $in_comment = 0; | 616 | $in_comment = 0; |
@@ -440,6 +620,7 @@ sub process { | |||
440 | } else { | 620 | } else { |
441 | $realcnt=1+1; | 621 | $realcnt=1+1; |
442 | } | 622 | } |
623 | $prev_values = 'N'; | ||
443 | next; | 624 | next; |
444 | } | 625 | } |
445 | 626 | ||
@@ -473,18 +654,24 @@ sub process { | |||
473 | # Track the previous line. | 654 | # Track the previous line. |
474 | ($prevline, $stashline) = ($stashline, $line); | 655 | ($prevline, $stashline) = ($stashline, $line); |
475 | ($previndent, $stashindent) = ($stashindent, $indent); | 656 | ($previndent, $stashindent) = ($stashindent, $indent); |
657 | |||
476 | } elsif ($realcnt == 1) { | 658 | } elsif ($realcnt == 1) { |
477 | $realcnt--; | 659 | $realcnt--; |
478 | } | 660 | } |
479 | 661 | ||
480 | #make up the handle for any error we report on this line | 662 | #make up the handle for any error we report on this line |
481 | $here = "#$linenr: "; | 663 | $here = "#$linenr: " if (!$file); |
664 | $here = "#$realline: " if ($file); | ||
482 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); | 665 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
483 | 666 | ||
484 | my $hereline = "$here\n$line\n"; | 667 | my $hereline = "$here\n$line\n"; |
485 | my $herecurr = "$here\n$line\n"; | 668 | my $herecurr = "$here\n$line\n"; |
486 | my $hereprev = "$here\n$prevline\n$line\n"; | 669 | my $hereprev = "$here\n$prevline\n$line\n"; |
487 | 670 | ||
671 | $prefix = "$filename:$realline: " if ($emacs && $file); | ||
672 | $prefix = "$filename:$linenr: " if ($emacs && !$file); | ||
673 | $cnt_lines++ if ($realcnt != 0); | ||
674 | |||
488 | #check the patch for a signoff: | 675 | #check the patch for a signoff: |
489 | if ($line =~ /^\s*signed-off-by:/i) { | 676 | if ($line =~ /^\s*signed-off-by:/i) { |
490 | # This is a signoff, if ugly, so do not double report. | 677 | # This is a signoff, if ugly, so do not double report. |
@@ -502,7 +689,7 @@ sub process { | |||
502 | # Check for wrappage within a valid hunk of the file | 689 | # Check for wrappage within a valid hunk of the file |
503 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { | 690 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { |
504 | ERROR("patch seems to be corrupt (line wrapped?)\n" . | 691 | ERROR("patch seems to be corrupt (line wrapped?)\n" . |
505 | $herecurr); | 692 | $herecurr) if (!$emitted_corrupt++); |
506 | } | 693 | } |
507 | 694 | ||
508 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php | 695 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php |
@@ -568,8 +755,12 @@ sub process { | |||
568 | $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && | 755 | $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && |
569 | $line !~ /$Ident:\s*$/ && | 756 | $line !~ /$Ident:\s*$/ && |
570 | $line !~ /^.\s*$Ident\s*\(/ && | 757 | $line !~ /^.\s*$Ident\s*\(/ && |
758 | # definitions in global scope can only start with types | ||
571 | ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || | 759 | ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || |
572 | $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) { | 760 | # declarations always start with types |
761 | $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) || | ||
762 | # any (foo ... *) is a pointer cast, and foo is a type | ||
763 | $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) { | ||
573 | my $possible = $1; | 764 | my $possible = $1; |
574 | if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && | 765 | if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && |
575 | $possible ne 'goto' && $possible ne 'return' && | 766 | $possible ne 'goto' && $possible ne 'return' && |
@@ -579,7 +770,7 @@ sub process { | |||
579 | #print "POSSIBLE<$possible>\n"; | 770 | #print "POSSIBLE<$possible>\n"; |
580 | push(@bare, $possible); | 771 | push(@bare, $possible); |
581 | my $bare = join("|", @bare); | 772 | my $bare = join("|", @bare); |
582 | $Bare = qr{ | 773 | $Bare = '|' . qr{ |
583 | \b(?:$bare)\b | 774 | \b(?:$bare)\b |
584 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | 775 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? |
585 | (?:\s+$Sparse)* | 776 | (?:\s+$Sparse)* |
@@ -641,6 +832,14 @@ sub process { | |||
641 | } | 832 | } |
642 | } | 833 | } |
643 | 834 | ||
835 | # Track the 'values' across context and added lines. | ||
836 | my $opline = $line; $opline =~ s/^./ /; | ||
837 | my $curr_values = annotate_values($opline . "\n", $prev_values); | ||
838 | $curr_values = $prev_values . $curr_values; | ||
839 | #warn "--> $opline\n"; | ||
840 | #warn "--> $curr_values ($prev_values)\n"; | ||
841 | $prev_values = substr($curr_values, -1); | ||
842 | |||
644 | #ignore lines not being added | 843 | #ignore lines not being added |
645 | if ($line=~/^[^\+]/) {next;} | 844 | if ($line=~/^[^\+]/) {next;} |
646 | 845 | ||
@@ -678,6 +877,7 @@ sub process { | |||
678 | } | 877 | } |
679 | # Remove C99 comments. | 878 | # Remove C99 comments. |
680 | $line =~ s@//.*@@; | 879 | $line =~ s@//.*@@; |
880 | $opline =~ s@//.*@@; | ||
681 | 881 | ||
682 | #EXPORT_SYMBOL should immediately follow its function closing }. | 882 | #EXPORT_SYMBOL should immediately follow its function closing }. |
683 | if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || | 883 | if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || |
@@ -766,18 +966,13 @@ sub process { | |||
766 | } | 966 | } |
767 | 967 | ||
768 | # check for spaces between functions and their parentheses. | 968 | # check for spaces between functions and their parentheses. |
769 | if ($line =~ /($Ident)\s+\(/ && | 969 | while ($line =~ /($Ident)\s+\(/g) { |
770 | $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ && | 970 | if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ && |
771 | $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { | 971 | $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { |
772 | WARN("no space between function name and open parenthesis '('\n" . $herecurr); | 972 | WARN("no space between function name and open parenthesis '('\n" . $herecurr); |
973 | } | ||
773 | } | 974 | } |
774 | # Check operator spacing. | 975 | # Check operator spacing. |
775 | # Note we expand the line with the leading + as the real | ||
776 | # line will be displayed with the leading + and the tabs | ||
777 | # will therefore also expand that way. | ||
778 | my $opline = $line; | ||
779 | $opline = expand_tabs($opline); | ||
780 | $opline =~ s/^./ /; | ||
781 | if (!($line=~/\#\s*include/)) { | 976 | if (!($line=~/\#\s*include/)) { |
782 | my $ops = qr{ | 977 | my $ops = qr{ |
783 | <<=|>>=|<=|>=|==|!=| | 978 | <<=|>>=|<=|>=|==|!=| |
@@ -787,6 +982,9 @@ sub process { | |||
787 | }x; | 982 | }x; |
788 | my @elements = split(/($ops|;)/, $opline); | 983 | my @elements = split(/($ops|;)/, $opline); |
789 | my $off = 0; | 984 | my $off = 0; |
985 | |||
986 | my $blank = copy_spacing($opline); | ||
987 | |||
790 | for (my $n = 0; $n < $#elements; $n += 2) { | 988 | for (my $n = 0; $n < $#elements; $n += 2) { |
791 | $off += length($elements[$n]); | 989 | $off += length($elements[$n]); |
792 | 990 | ||
@@ -822,62 +1020,24 @@ sub process { | |||
822 | 1020 | ||
823 | my $at = "(ctx:$ctx)"; | 1021 | my $at = "(ctx:$ctx)"; |
824 | 1022 | ||
825 | my $ptr = (" " x $off) . "^"; | 1023 | my $ptr = substr($blank, 0, $off) . "^"; |
826 | my $hereptr = "$hereline$ptr\n"; | 1024 | my $hereptr = "$hereline$ptr\n"; |
827 | 1025 | ||
828 | # Classify operators into binary, unary, or | 1026 | # Classify operators into binary, unary, or |
829 | # definitions (* only) where they have more | 1027 | # definitions (* only) where they have more |
830 | # than one mode. | 1028 | # than one mode. |
831 | my $unary_ctx = $prevline . $ca; | 1029 | my $op_type = substr($curr_values, $off + 1, 1); |
832 | $unary_ctx =~ s/^./ /; | 1030 | my $op_left = substr($curr_values, $off, 1); |
833 | my $is_unary = 0; | 1031 | my $is_unary; |
834 | my $Unary = qr{ | 1032 | if ($op_type eq 'T') { |
835 | (?: | 1033 | $is_unary = 2; |
836 | ^|;|,|$ops|\(|\?|:| | 1034 | } elsif ($op_left eq 'V') { |
837 | \(\s*$Type\s*\)| | 1035 | $is_unary = 0; |
838 | $Type| | 1036 | } else { |
839 | return|case|else| | 1037 | $is_unary = 1; |
840 | \{|\}| | ||
841 | \[| | ||
842 | ^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?| | ||
843 | ^.\#\s*else| | ||
844 | ^.\#\s*endif| | ||
845 | ^.\#\s*(?:if|ifndef|ifdef)\b.* | ||
846 | )\s*(?:|\\)\s*$ | ||
847 | }x; | ||
848 | my $UnaryFalse = qr{ | ||
849 | sizeof\s*\(\s*$Type\s*\)\s*$ | ||
850 | }x; | ||
851 | my $UnaryDefine = qr{ | ||
852 | (?:$Type|$Bare)\s*| | ||
853 | (?:$Type|$Bare).*,\s*\** | ||
854 | }x; | ||
855 | if ($op eq '-' || $op eq '&' || $op eq '*') { | ||
856 | # An operator is binary if the left hand | ||
857 | # side is a value. Pick out the known | ||
858 | # non-values. | ||
859 | if ($unary_ctx =~ /$Unary$/s && | ||
860 | $unary_ctx !~ /$UnaryFalse$/s) { | ||
861 | $is_unary = 1; | ||
862 | |||
863 | # Special handling for ')' check if this | ||
864 | # brace represents a conditional, if so | ||
865 | # we are unary. | ||
866 | } elsif ($unary_ctx =~ /\)\s*$/) { | ||
867 | my $before = ctx_expr_before($unary_ctx); | ||
868 | if ($before =~ /(?:for|if|while)\s*$/) { | ||
869 | $is_unary = 1; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | # Check for type definition for of '*'. | ||
874 | if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) { | ||
875 | $is_unary = 2; | ||
876 | } | ||
877 | } | 1038 | } |
878 | |||
879 | #if ($op eq '-' || $op eq '&' || $op eq '*') { | 1039 | #if ($op eq '-' || $op eq '&' || $op eq '*') { |
880 | # print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; | 1040 | # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; |
881 | #} | 1041 | #} |
882 | 1042 | ||
883 | # ; should have either the end of line or a space or \ after it | 1043 | # ; should have either the end of line or a space or \ after it |
@@ -952,7 +1112,7 @@ sub process { | |||
952 | 1112 | ||
953 | # check for multiple assignments | 1113 | # check for multiple assignments |
954 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { | 1114 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { |
955 | WARN("multiple assignments should be avoided\n" . $herecurr); | 1115 | CHK("multiple assignments should be avoided\n" . $herecurr); |
956 | } | 1116 | } |
957 | 1117 | ||
958 | ## # check for multiple declarations, allowing for a function declaration | 1118 | ## # check for multiple declarations, allowing for a function declaration |
@@ -1012,7 +1172,7 @@ sub process { | |||
1012 | } | 1172 | } |
1013 | 1173 | ||
1014 | # Check for illegal assignment in if conditional. | 1174 | # Check for illegal assignment in if conditional. |
1015 | if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) { | 1175 | if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) { |
1016 | #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); | 1176 | #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); |
1017 | ERROR("do not use assignment in if condition\n" . $herecurr); | 1177 | ERROR("do not use assignment in if condition\n" . $herecurr); |
1018 | } | 1178 | } |
@@ -1038,8 +1198,8 @@ sub process { | |||
1038 | 1198 | ||
1039 | #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) | 1199 | #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) |
1040 | if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { | 1200 | if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { |
1041 | my $checkfile = "include/linux/$1.h"; | 1201 | my $checkfile = "$root/include/linux/$1.h"; |
1042 | if (-f $checkfile) { | 1202 | if (-f $checkfile && $1 ne 'irq.h') { |
1043 | CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . | 1203 | CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . |
1044 | $herecurr); | 1204 | $herecurr); |
1045 | } | 1205 | } |
@@ -1151,7 +1311,8 @@ sub process { | |||
1151 | } | 1311 | } |
1152 | 1312 | ||
1153 | # no volatiles please | 1313 | # no volatiles please |
1154 | if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { | 1314 | my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; |
1315 | if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { | ||
1155 | WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); | 1316 | WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); |
1156 | } | 1317 | } |
1157 | 1318 | ||
@@ -1240,6 +1401,11 @@ sub process { | |||
1240 | 1401 | ||
1241 | if ($clean == 0 && ($chk_patch || $is_patch)) { | 1402 | if ($clean == 0 && ($chk_patch || $is_patch)) { |
1242 | print report_dump(); | 1403 | print report_dump(); |
1404 | if ($quiet < 2) { | ||
1405 | print "total: $cnt_error errors, $cnt_warn warnings, " . | ||
1406 | (($check)? "$cnt_chk checks, " : "") . | ||
1407 | "$cnt_lines lines checked\n"; | ||
1408 | } | ||
1243 | } | 1409 | } |
1244 | if ($clean == 1 && $quiet == 0) { | 1410 | if ($clean == 1 && $quiet == 0) { |
1245 | print "Your patch has no obvious style problems and is ready for submission.\n" | 1411 | print "Your patch has no obvious style problems and is ready for submission.\n" |