aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/checkpatch.pl514
-rwxr-xr-xscripts/checkstack.pl2
2 files changed, 341 insertions, 175 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;
9my $P = $0; 9my $P = $0;
10$P =~ s@.*/@@g; 10$P =~ s@.*/@@g;
11 11
12my $V = '0.10'; 12my $V = '0.11';
13 13
14use Getopt::Long qw(:config no_auto_abbrev); 14use Getopt::Long qw(:config no_auto_abbrev);
15 15
@@ -18,12 +18,21 @@ my $tree = 1;
18my $chk_signoff = 1; 18my $chk_signoff = 1;
19my $chk_patch = 1; 19my $chk_patch = 1;
20my $tst_type = 0; 20my $tst_type = 0;
21my $emacs = 0;
22my $file = 0;
23my $check = 0;
24my $root;
21GetOptions( 25GetOptions(
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
29my $exit = 0; 38my $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
39if ($tree && !top_of_kernel_tree()) { 52if ($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
72my $emitted_corrupt = 0;
73
74our $Ident = qr{[A-Za-z_][A-Za-z\d_]*};
75our $Storage = qr{extern|static|asmlinkage};
76our $Sparse = qr{
77 __user|
78 __kernel|
79 __force|
80 __iomem|
81 __must_check|
82 __init_refok|
83 __kprobes|
84 fastcall
85 }x;
86our $Attribute = qr{
87 const|
88 __read_mostly|
89 __kprobes|
90 __(?:mem|cpu|dev|)(?:initdata|init)
91 }x;
92our $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|\[[^]]*\]};
129our $Lval = qr{$Ident(?:$Member)*};
130
131our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
132our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
133our $Operators = qr{
134 <=|>=|==|!=|
135 =>|->|<<|>>|<|>|!|~|
136 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
137 }x;
138
139our $Bare = '';
140
141$chk_signoff = 0 if ($file);
142
44my @dep_includes = (); 143my @dep_includes = ();
45my @dep_functions = (); 144my @dep_functions = ();
46my $removal = 'Documentation/feature-removal-schedule.txt'; 145my $removal = "Documentation/feature-removal-schedule.txt";
47if ($tree && -f $removal) { 146if ($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
63my @rawlines = (); 163my @rawlines = ();
64while (<>) { 164for 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
75exit($exit); 183exit($exit);
76 184
77sub top_of_kernel_tree { 185sub 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
88sub expand_tabs { 202sub expand_tabs {
@@ -105,6 +219,20 @@ sub expand_tabs {
105 219
106 return $res; 220 return $res;
107} 221}
222sub 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
109sub line_stats { 237sub 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
263sub ctx_expr_before { 391sub 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
287sub cat_vet { 408sub 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
518my $prefix = '';
519
301my @report = (); 520my @report = ();
302sub report { 521sub report {
303 push(@report, $_[0]); 522 push(@report, $prefix . $_[0]);
304} 523}
305sub report_dump { 524sub report_dump {
306 @report; 525 @report;
@@ -308,14 +527,19 @@ sub report_dump {
308sub ERROR { 527sub 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}
312sub WARN { 532sub 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}
316sub CHK { 537sub 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
321sub process { 545sub 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"
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index b458e2acb4ac..28e480c8100f 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -15,7 +15,7 @@
15# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com> 15# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
16# 16#
17# Usage: 17# Usage:
18# objdump -d vmlinux | stackcheck.pl [arch] 18# objdump -d vmlinux | scripts/checkstack.pl [arch]
19# 19#
20# TODO : Port to all architectures (one regex per arch) 20# TODO : Port to all architectures (one regex per arch)
21 21