blob: 2086a856400a9c7258958b96fe0f3d53d3d70ff8 [file] [log] [blame]
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001#!/usr/bin/perl -w
2# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
Andy Whitcroft00df3442007-06-08 13:47:06 -07003# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
Andy Whitcroft0a920b52007-06-01 00:46:48 -07004# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
5# Licensed under the terms of the GNU GPL License version 2
6
7use strict;
8
9my $P = $0;
Andy Whitcroft00df3442007-06-08 13:47:06 -070010$P =~ s@.*/@@g;
Andy Whitcroft0a920b52007-06-01 00:46:48 -070011
Andy Whitcroft13214ad2008-02-08 04:22:03 -080012my $V = '0.14';
Andy Whitcroft0a920b52007-06-01 00:46:48 -070013
14use Getopt::Long qw(:config no_auto_abbrev);
15
16my $quiet = 0;
17my $tree = 1;
18my $chk_signoff = 1;
19my $chk_patch = 1;
Andy Whitcroft653d4872007-06-23 17:16:34 -070020my $tst_type = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070021my $emacs = 0;
Andy Whitcroft8905a672007-11-28 16:21:06 -080022my $terse = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070023my $file = 0;
24my $check = 0;
Andy Whitcroft8905a672007-11-28 16:21:06 -080025my $summary = 1;
26my $mailback = 0;
Andy Whitcroft13214ad2008-02-08 04:22:03 -080027my $summary_file = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070028my $root;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -080029my %debug;
Andy Whitcroft0a920b52007-06-01 00:46:48 -070030GetOptions(
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070031 'q|quiet+' => \$quiet,
Andy Whitcroft0a920b52007-06-01 00:46:48 -070032 'tree!' => \$tree,
33 'signoff!' => \$chk_signoff,
34 'patch!' => \$chk_patch,
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070035 'emacs!' => \$emacs,
Andy Whitcroft8905a672007-11-28 16:21:06 -080036 'terse!' => \$terse,
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070037 'file!' => \$file,
38 'subjective!' => \$check,
39 'strict!' => \$check,
40 'root=s' => \$root,
Andy Whitcroft8905a672007-11-28 16:21:06 -080041 'summary!' => \$summary,
42 'mailback!' => \$mailback,
Andy Whitcroft13214ad2008-02-08 04:22:03 -080043 'summary-file!' => \$summary_file,
44
Andy Whitcroftc2fdda02008-02-08 04:20:54 -080045 'debug=s' => \%debug,
Andy Whitcroft13214ad2008-02-08 04:22:03 -080046 'test-type!' => \$tst_type,
Andy Whitcroft0a920b52007-06-01 00:46:48 -070047) or exit;
48
49my $exit = 0;
50
51if ($#ARGV < 0) {
Andy Whitcroft00df3442007-06-08 13:47:06 -070052 print "usage: $P [options] patchfile\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -070053 print "version: $V\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -080054 print "options: -q => quiet\n";
55 print " --no-tree => run without a kernel tree\n";
56 print " --terse => one line per report\n";
57 print " --emacs => emacs compile window format\n";
58 print " --file => check a source file\n";
59 print " --strict => enable more subjective tests\n";
60 print " --root => path to the kernel tree root\n";
61 print " --no-summary => suppress the per-file summary\n";
62 print " --summary-file => include the filename in summary\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -070063 exit(1);
64}
65
Andy Whitcroftc2fdda02008-02-08 04:20:54 -080066my $dbg_values = 0;
67my $dbg_possible = 0;
68for my $key (keys %debug) {
69 eval "\${dbg_$key} = '$debug{$key}';"
70}
71
Andy Whitcroft8905a672007-11-28 16:21:06 -080072if ($terse) {
73 $emacs = 1;
74 $quiet++;
75}
76
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070077if ($tree) {
78 if (defined $root) {
79 if (!top_of_kernel_tree($root)) {
80 die "$P: $root: --root does not point at a valid tree\n";
81 }
82 } else {
83 if (top_of_kernel_tree('.')) {
84 $root = '.';
85 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
86 top_of_kernel_tree($1)) {
87 $root = $1;
88 }
89 }
90
91 if (!defined $root) {
92 print "Must be run from the top-level dir. of a kernel tree\n";
93 exit(2);
94 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -070095}
96
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -070097my $emitted_corrupt = 0;
98
99our $Ident = qr{[A-Za-z_][A-Za-z\d_]*};
100our $Storage = qr{extern|static|asmlinkage};
101our $Sparse = qr{
102 __user|
103 __kernel|
104 __force|
105 __iomem|
106 __must_check|
107 __init_refok|
108 __kprobes|
109 fastcall
110 }x;
111our $Attribute = qr{
112 const|
113 __read_mostly|
114 __kprobes|
115 __(?:mem|cpu|dev|)(?:initdata|init)
116 }x;
117our $Inline = qr{inline|__always_inline|noinline};
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700118our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
119our $Lval = qr{$Ident(?:$Member)*};
120
121our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
122our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
123our $Operators = qr{
124 <=|>=|==|!=|
125 =>|->|<<|>>|<|>|!|~|
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800126 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700127 }x;
128
Andy Whitcroft8905a672007-11-28 16:21:06 -0800129our $NonptrType;
130our $Type;
131our $Declare;
132
133our @typeList = (
134 qr{void},
135 qr{char},
136 qr{short},
137 qr{int},
138 qr{long},
139 qr{unsigned},
140 qr{float},
141 qr{double},
142 qr{bool},
143 qr{long\s+int},
144 qr{long\s+long},
145 qr{long\s+long\s+int},
146 qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
147 qr{struct\s+$Ident},
148 qr{union\s+$Ident},
149 qr{enum\s+$Ident},
150 qr{${Ident}_t},
151 qr{${Ident}_handler},
152 qr{${Ident}_handler_fn},
153);
154
155sub build_types {
156 my $all = "(?: \n" . join("|\n ", @typeList) . "\n)";
157 $NonptrType = qr{
158 \b
159 (?:const\s+)?
160 (?:unsigned\s+)?
161 $all
162 (?:\s+$Sparse|\s+const)*
163 \b
164 }x;
165 $Type = qr{
166 \b$NonptrType\b
167 (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800168 (?:\s+$Inline|\s+$Sparse|\s+$Attribute)*
Andy Whitcroft8905a672007-11-28 16:21:06 -0800169 }x;
170 $Declare = qr{(?:$Storage\s+)?$Type};
171}
172build_types();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700173
174$chk_signoff = 0 if ($file);
175
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700176my @dep_includes = ();
177my @dep_functions = ();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700178my $removal = "Documentation/feature-removal-schedule.txt";
179if ($tree && -f "$root/$removal") {
180 open(REMOVE, "<$root/$removal") ||
181 die "$P: $removal: open failed - $!\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700182 while (<REMOVE>) {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700183 if (/^Check:\s+(.*\S)/) {
184 for my $entry (split(/[, ]+/, $1)) {
185 if ($entry =~ m@include/(.*)@) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700186 push(@dep_includes, $1);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700187
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700188 } elsif ($entry !~ m@/@) {
189 push(@dep_functions, $entry);
190 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700191 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700192 }
193 }
194}
195
Andy Whitcroft00df3442007-06-08 13:47:06 -0700196my @rawlines = ();
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800197my @lines = ();
198my $vname;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700199for my $filename (@ARGV) {
200 if ($file) {
201 open(FILE, "diff -u /dev/null $filename|") ||
202 die "$P: $filename: diff failed - $!\n";
203 } else {
204 open(FILE, "<$filename") ||
205 die "$P: $filename: open failed - $!\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700206 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800207 if ($filename eq '-') {
208 $vname = 'Your patch';
209 } else {
210 $vname = $filename;
211 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700212 while (<FILE>) {
213 chomp;
214 push(@rawlines, $_);
215 }
216 close(FILE);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800217 if (!process($filename)) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700218 $exit = 1;
219 }
220 @rawlines = ();
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800221 @lines = ();
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700222}
223
224exit($exit);
225
226sub top_of_kernel_tree {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700227 my ($root) = @_;
228
229 my @tree_check = (
230 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
231 "README", "Documentation", "arch", "include", "drivers",
232 "fs", "init", "ipc", "kernel", "lib", "scripts",
233 );
234
235 foreach my $check (@tree_check) {
236 if (! -e $root . '/' . $check) {
237 return 0;
238 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700239 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700240 return 1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700241}
242
243sub expand_tabs {
244 my ($str) = @_;
245
246 my $res = '';
247 my $n = 0;
248 for my $c (split(//, $str)) {
249 if ($c eq "\t") {
250 $res .= ' ';
251 $n++;
252 for (; ($n % 8) != 0; $n++) {
253 $res .= ' ';
254 }
255 next;
256 }
257 $res .= $c;
258 $n++;
259 }
260
261 return $res;
262}
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700263sub copy_spacing {
264 my ($str) = @_;
265
266 my $res = '';
267 for my $c (split(//, $str)) {
268 if ($c eq "\t") {
269 $res .= $c;
270 } else {
271 $res .= ' ';
272 }
273 }
274
275 return $res;
276}
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700277
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700278sub line_stats {
279 my ($line) = @_;
280
281 # Drop the diff line leader and expand tabs
282 $line =~ s/^.//;
283 $line = expand_tabs($line);
284
285 # Pick the indent from the front of the line.
286 my ($white) = ($line =~ /^(\s*)/);
287
288 return (length($line), length($white));
289}
290
Andy Whitcroft00df3442007-06-08 13:47:06 -0700291sub sanitise_line {
292 my ($line) = @_;
293
294 my $res = '';
295 my $l = '';
296
297 my $quote = '';
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800298 my $qlen = 0;
Andy Whitcroft00df3442007-06-08 13:47:06 -0700299
300 foreach my $c (split(//, $line)) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800301 # The second backslash of a pair is not a "quote".
302 if ($l eq "\\" && $c eq "\\") {
303 $c = 'X';
304 }
Andy Whitcroft00df3442007-06-08 13:47:06 -0700305 if ($l ne "\\" && ($c eq "'" || $c eq '"')) {
306 if ($quote eq '') {
307 $quote = $c;
308 $res .= $c;
309 $l = $c;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800310 $qlen = 0;
Andy Whitcroft00df3442007-06-08 13:47:06 -0700311 next;
312 } elsif ($quote eq $c) {
313 $quote = '';
314 }
315 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800316 if ($quote eq "'" && $qlen > 1) {
317 $quote = '';
318 }
Andy Whitcroft00df3442007-06-08 13:47:06 -0700319 if ($quote && $c ne "\t") {
320 $res .= "X";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800321 $qlen++;
Andy Whitcroft00df3442007-06-08 13:47:06 -0700322 } else {
323 $res .= $c;
324 }
325
326 $l = $c;
327 }
328
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800329 # Clear out the comments.
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800330 while ($res =~ m@(/\*.*?\*/)@g) {
331 substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800332 }
333 if ($res =~ m@(/\*.*)@) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800334 substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800335 }
336 if ($res =~ m@^.(.*\*/)@) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800337 substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800338 }
339
340 # The pathname on a #include may be surrounded by '<' and '>'.
341 if ($res =~ /^.#\s*include\s+\<(.*)\>/) {
342 my $clean = 'X' x length($1);
343 $res =~ s@\<.*\>@<$clean>@;
344
345 # The whole of a #error is a string.
346 } elsif ($res =~ /^.#\s*(?:error|warning)\s+(.*)\b/) {
347 my $clean = 'X' x length($1);
348 $res =~ s@(#\s*(?:error|warning)\s+).*@$1$clean@;
349 }
350
Andy Whitcroft00df3442007-06-08 13:47:06 -0700351 return $res;
352}
353
Andy Whitcroft8905a672007-11-28 16:21:06 -0800354sub ctx_statement_block {
355 my ($linenr, $remain, $off) = @_;
356 my $line = $linenr - 1;
357 my $blk = '';
358 my $soff = $off;
359 my $coff = $off - 1;
360
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800361 my $loff = 0;
362
Andy Whitcroft8905a672007-11-28 16:21:06 -0800363 my $type = '';
364 my $level = 0;
365 my $c;
366 my $len = 0;
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800367
368 my $remainder;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800369 while (1) {
370 #warn "CSB: blk<$blk>\n";
371 # If we are about to drop off the end, pull in more
372 # context.
373 if ($off >= $len) {
374 for (; $remain > 0; $line++) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800375 next if ($lines[$line] =~ /^-/);
Andy Whitcroft8905a672007-11-28 16:21:06 -0800376 $remain--;
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800377 $loff = $len;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800378 $blk .= $lines[$line] . "\n";
Andy Whitcroft8905a672007-11-28 16:21:06 -0800379 $len = length($blk);
380 $line++;
381 last;
382 }
383 # Bail if there is no further context.
384 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800385 if ($off >= $len) {
Andy Whitcroft8905a672007-11-28 16:21:06 -0800386 last;
387 }
388 }
389 $c = substr($blk, $off, 1);
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800390 $remainder = substr($blk, $off);
Andy Whitcroft8905a672007-11-28 16:21:06 -0800391
392 #warn "CSB: c<$c> type<$type> level<$level>\n";
393 # Statement ends at the ';' or a close '}' at the
394 # outermost level.
395 if ($level == 0 && $c eq ';') {
396 last;
397 }
398
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800399 # An else is really a conditional as long as its not else if
400 if ($level == 0 && $remainder =~ /(\s+else)(?:\s|{)/ &&
401 $remainder !~ /\s+else\s+if\b/) {
402 $coff = $off + length($1);
403 }
404
Andy Whitcroft8905a672007-11-28 16:21:06 -0800405 if (($type eq '' || $type eq '(') && $c eq '(') {
406 $level++;
407 $type = '(';
408 }
409 if ($type eq '(' && $c eq ')') {
410 $level--;
411 $type = ($level != 0)? '(' : '';
412
413 if ($level == 0 && $coff < $soff) {
414 $coff = $off;
415 }
416 }
417 if (($type eq '' || $type eq '{') && $c eq '{') {
418 $level++;
419 $type = '{';
420 }
421 if ($type eq '{' && $c eq '}') {
422 $level--;
423 $type = ($level != 0)? '{' : '';
424
425 if ($level == 0) {
426 last;
427 }
428 }
429 $off++;
430 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800431 if ($off == $len) {
432 $line++;
433 $remain--;
434 }
Andy Whitcroft8905a672007-11-28 16:21:06 -0800435
436 my $statement = substr($blk, $soff, $off - $soff + 1);
437 my $condition = substr($blk, $soff, $coff - $soff + 1);
438
439 #warn "STATEMENT<$statement>\n";
440 #warn "CONDITION<$condition>\n";
441
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800442 #print "off<$off> loff<$loff>\n";
443
444 return ($statement, $condition,
445 $line, $remain + 1, $off - $loff + 1, $level);
446}
447
448sub ctx_statement_full {
449 my ($linenr, $remain, $off) = @_;
450 my ($statement, $condition, $level);
451
452 my (@chunks);
453
454 ($statement, $condition, $linenr, $remain, $off, $level) =
455 ctx_statement_block($linenr, $remain, $off);
456 #print "F: c<$condition> s<$statement>\n";
457 for (;;) {
458 push(@chunks, [ $condition, $statement ]);
459 last if (!($remain > 0 && $condition =~ /^.\s*(?:if|else|do)/));
460 ($statement, $condition, $linenr, $remain, $off, $level) =
461 ctx_statement_block($linenr, $remain, $off);
462 #print "C: c<$condition> s<$statement>\n";
463 }
464
465 return ($level, $linenr, @chunks);
Andy Whitcroft8905a672007-11-28 16:21:06 -0800466}
467
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700468sub ctx_block_get {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700469 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700470 my $line;
471 my $start = $linenr - 1;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700472 my $blk = '';
473 my @o;
474 my @c;
475 my @res = ();
476
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700477 my $level = 0;
Andy Whitcroft00df3442007-06-08 13:47:06 -0700478 for ($line = $start; $remain > 0; $line++) {
479 next if ($rawlines[$line] =~ /^-/);
480 $remain--;
481
482 $blk .= $rawlines[$line];
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700483 foreach my $c (split(//, $rawlines[$line])) {
484 ##print "C<$c>L<$level><$open$close>O<$off>\n";
485 if ($off > 0) {
486 $off--;
487 next;
488 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700489
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700490 if ($c eq $close && $level > 0) {
491 $level--;
492 last if ($level == 0);
493 } elsif ($c eq $open) {
494 $level++;
495 }
496 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700497
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700498 if (!$outer || $level <= 1) {
Andy Whitcroft00df3442007-06-08 13:47:06 -0700499 push(@res, $rawlines[$line]);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700500 }
501
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700502 last if ($level == 0);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700503 }
504
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700505 return ($level, @res);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700506}
507sub ctx_block_outer {
508 my ($linenr, $remain) = @_;
509
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700510 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
511 return @r;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700512}
513sub ctx_block {
514 my ($linenr, $remain) = @_;
515
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700516 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
517 return @r;
Andy Whitcroft653d4872007-06-23 17:16:34 -0700518}
519sub ctx_statement {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700520 my ($linenr, $remain, $off) = @_;
521
522 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
523 return @r;
524}
525sub ctx_block_level {
Andy Whitcroft653d4872007-06-23 17:16:34 -0700526 my ($linenr, $remain) = @_;
527
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700528 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700529}
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700530sub ctx_statement_level {
531 my ($linenr, $remain, $off) = @_;
532
533 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
534}
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700535
536sub ctx_locate_comment {
537 my ($first_line, $end_line) = @_;
538
539 # Catch a comment on the end of the line itself.
Andy Whitcroft00df3442007-06-08 13:47:06 -0700540 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700541 return $current_comment if (defined $current_comment);
542
543 # Look through the context and try and figure out if there is a
544 # comment.
545 my $in_comment = 0;
546 $current_comment = '';
547 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
Andy Whitcroft00df3442007-06-08 13:47:06 -0700548 my $line = $rawlines[$linenr - 1];
549 #warn " $line\n";
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700550 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
551 $in_comment = 1;
552 }
553 if ($line =~ m@/\*@) {
554 $in_comment = 1;
555 }
556 if (!$in_comment && $current_comment ne '') {
557 $current_comment = '';
558 }
559 $current_comment .= $line . "\n" if ($in_comment);
560 if ($line =~ m@\*/@) {
561 $in_comment = 0;
562 }
563 }
564
565 chomp($current_comment);
566 return($current_comment);
567}
568sub ctx_has_comment {
569 my ($first_line, $end_line) = @_;
570 my $cmt = ctx_locate_comment($first_line, $end_line);
571
Andy Whitcroft00df3442007-06-08 13:47:06 -0700572 ##print "LINE: $rawlines[$end_line - 1 ]\n";
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700573 ##print "CMMT: $cmt\n";
574
575 return ($cmt ne '');
576}
577
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700578sub cat_vet {
579 my ($vet) = @_;
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700580 my ($res, $coded);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700581
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700582 $res = '';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700583 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
584 $res .= $1;
585 if ($2 ne '') {
586 $coded = sprintf("^%c", unpack('C', $2) + 64);
587 $res .= $coded;
588 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700589 }
590 $res =~ s/$/\$/;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700591
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700592 return $res;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700593}
594
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800595my $av_preprocessor = 0;
596my $av_paren = 0;
597my @av_paren_type;
598
599sub annotate_reset {
600 $av_preprocessor = 0;
601 $av_paren = 0;
602 @av_paren_type = ();
603}
604
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700605sub annotate_values {
606 my ($stream, $type) = @_;
607
608 my $res;
609 my $cur = $stream;
610
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800611 print "$stream\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700612
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700613 while (length($cur)) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800614 print " <$type> " if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700615 if ($cur =~ /^(\s+)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800616 print "WS($1)\n" if ($dbg_values > 1);
617 if ($1 =~ /\n/ && $av_preprocessor) {
618 $av_preprocessor = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700619 $type = 'N';
620 }
621
Andy Whitcroft8905a672007-11-28 16:21:06 -0800622 } elsif ($cur =~ /^($Type)/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800623 print "DECLARE($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700624 $type = 'T';
625
626 } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800627 print "DEFINE($1)\n" if ($dbg_values > 1);
628 $av_preprocessor = 1;
629 $av_paren_type[$av_paren] = 'N';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700630
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800631 } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) {
632 print "PRE($1)\n" if ($dbg_values > 1);
633 $av_preprocessor = 1;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700634 $type = 'N';
635
636 } elsif ($cur =~ /^(\\\n)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800637 print "PRECONT($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700638
639 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800640 print "SIZEOF($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700641 if (defined $2) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800642 $av_paren_type[$av_paren] = 'V';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700643 }
644 $type = 'N';
645
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800646 } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800647 print "COND($1)\n" if ($dbg_values > 1);
648 $av_paren_type[$av_paren] = 'N';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700649 $type = 'N';
650
651 } elsif ($cur =~/^(return|case|else)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800652 print "KEYWORD($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700653 $type = 'N';
654
655 } elsif ($cur =~ /^(\()/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800656 print "PAREN('$1')\n" if ($dbg_values > 1);
657 $av_paren++;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700658 $type = 'N';
659
660 } elsif ($cur =~ /^(\))/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800661 $av_paren-- if ($av_paren > 0);
662 if (defined $av_paren_type[$av_paren]) {
663 $type = $av_paren_type[$av_paren];
664 undef $av_paren_type[$av_paren];
665 print "PAREN('$1') -> $type\n"
666 if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700667 } else {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800668 print "PAREN('$1')\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700669 }
670
671 } elsif ($cur =~ /^($Ident)\(/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800672 print "FUNC($1)\n" if ($dbg_values > 1);
673 $av_paren_type[$av_paren] = 'V';
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700674
675 } elsif ($cur =~ /^($Ident|$Constant)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800676 print "IDENT($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700677 $type = 'V';
678
679 } elsif ($cur =~ /^($Assignment)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800680 print "ASSIGN($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700681 $type = 'N';
682
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800683 } elsif ($cur =~/^(;)/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800684 print "END($1)\n" if ($dbg_values > 1);
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800685 $type = 'E';
686
687 } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
688 print "CLOSE($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700689 $type = 'N';
690
691 } elsif ($cur =~ /^($Operators)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800692 print "OP($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700693 if ($1 ne '++' && $1 ne '--') {
694 $type = 'N';
695 }
696
697 } elsif ($cur =~ /(^.)/o) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800698 print "C($1)\n" if ($dbg_values > 1);
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700699 }
700 if (defined $1) {
701 $cur = substr($cur, length($1));
702 $res .= $type x length($1);
703 }
704 }
705
706 return $res;
707}
708
Andy Whitcroft8905a672007-11-28 16:21:06 -0800709sub possible {
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800710 my ($possible, $line) = @_;
Andy Whitcroft8905a672007-11-28 16:21:06 -0800711
712 #print "CHECK<$possible>\n";
713 if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
714 $possible ne 'goto' && $possible ne 'return' &&
715 $possible ne 'struct' && $possible ne 'enum' &&
716 $possible ne 'case' && $possible ne 'else' &&
717 $possible ne 'typedef') {
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800718 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
Andy Whitcroft8905a672007-11-28 16:21:06 -0800719 push(@typeList, $possible);
720 build_types();
721 }
722}
723
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700724my $prefix = '';
725
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700726sub report {
Andy Whitcroft8905a672007-11-28 16:21:06 -0800727 my $line = $prefix . $_[0];
728
729 $line = (split('\n', $line))[0] . "\n" if ($terse);
730
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800731 push(our @report, $line);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700732}
733sub report_dump {
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800734 our @report;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700735}
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700736sub ERROR {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700737 report("ERROR: $_[0]\n");
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700738 our $clean = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700739 our $cnt_error++;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700740}
741sub WARN {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -0700742 report("WARNING: $_[0]\n");
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700743 our $clean = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700744 our $cnt_warn++;
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700745}
746sub CHK {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700747 if ($check) {
748 report("CHECK: $_[0]\n");
749 our $clean = 0;
750 our $cnt_chk++;
751 }
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700752}
753
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700754sub process {
755 my $filename = shift;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700756
757 my $linenr=0;
758 my $prevline="";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800759 my $prevrawline="";
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700760 my $stashline="";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800761 my $stashrawline="";
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700762
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700763 my $length;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700764 my $indent;
765 my $previndent=0;
766 my $stashindent=0;
767
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700768 our $clean = 1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700769 my $signoff = 0;
770 my $is_patch = 0;
771
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800772 our @report = ();
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700773 our $cnt_lines = 0;
774 our $cnt_error = 0;
775 our $cnt_warn = 0;
776 our $cnt_chk = 0;
777
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700778 # Trace the real file/line as we go.
779 my $realfile = '';
780 my $realline = 0;
781 my $realcnt = 0;
782 my $here = '';
783 my $in_comment = 0;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800784 my $comment_edge = 0;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700785 my $first_line = 0;
786
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800787 my $prev_values = 'E';
788
789 # suppression flags
790 my $suppress_ifbraces = 0;
Andy Whitcroft653d4872007-06-23 17:16:34 -0700791
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800792 # Pre-scan the patch sanitizing the lines.
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700793 # Pre-scan the patch looking for any __setup documentation.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800794 #
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700795 my @setup_docs = ();
796 my $setup_docs = 0;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800797 my $line;
798 foreach my $rawline (@rawlines) {
799 # Standardise the strings and chars within the input to
800 # simplify matching.
801 $line = sanitise_line($rawline);
802 push(@lines, $line);
803
804 ##print "==>$rawline\n";
805 ##print "-->$line\n";
806
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700807 if ($line=~/^\+\+\+\s+(\S+)/) {
808 $setup_docs = 0;
809 if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
810 $setup_docs = 1;
811 }
812 next;
813 }
814
815 if ($setup_docs && $line =~ /^\+/) {
816 push(@setup_docs, $line);
817 }
818 }
819
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700820 $prefix = '';
821
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700822 foreach my $line (@lines) {
823 $linenr++;
824
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800825 my $rawline = $rawlines[$linenr - 1];
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700826
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700827#extract the filename as it passes
828 if ($line=~/^\+\+\+\s+(\S+)/) {
829 $realfile=$1;
Andy Whitcroft00df3442007-06-08 13:47:06 -0700830 $realfile =~ s@^[^/]*/@@;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700831 $in_comment = 0;
832 next;
833 }
834#extract the line range in the file after the patch is applied
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700835 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700836 $is_patch = 1;
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700837 $first_line = $linenr + 1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700838 $in_comment = 0;
839 $realline=$1-1;
840 if (defined $2) {
841 $realcnt=$3+1;
842 } else {
843 $realcnt=1+1;
844 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800845 annotate_reset();
Andy Whitcroft13214ad2008-02-08 04:22:03 -0800846 $prev_values = 'E';
847
848 $suppress_ifbraces = $linenr - 1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700849 next;
850 }
851
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700852# track the line number as we move through the hunk, note that
853# new versions of GNU diff omit the leading space on completely
854# blank context lines so we need to count that too.
855 if ($line =~ /^( |\+|$)/) {
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700856 $realline++;
Andy Whitcroftd8aaf122007-06-23 17:16:44 -0700857 $realcnt-- if ($realcnt != 0);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700858
Andy Whitcroft8905a672007-11-28 16:21:06 -0800859 # Guestimate if this is a continuing comment. Run
860 # the context looking for a comment "edge". If this
861 # edge is a close comment then we must be in a comment
862 # at context start.
863 if ($linenr == $first_line) {
864 my $edge;
865 for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800866 ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
Andy Whitcroft8905a672007-11-28 16:21:06 -0800867 last if (defined $edge);
868 }
869 if (defined $edge && $edge eq '*/') {
870 $in_comment = 1;
871 }
872 }
873
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700874 # Guestimate if this is a continuing comment. If this
875 # is the start of a diff block and this line starts
876 # ' *' then it is very likely a comment.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800877 if ($linenr == $first_line and $rawline =~ m@^.\s* \*(?:\s|$)@) {
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700878 $in_comment = 1;
879 }
Andy Whitcroft8905a672007-11-28 16:21:06 -0800880
881 # Find the last comment edge on _this_ line.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800882 $comment_edge = 0;
883 while (($rawline =~ m@(/\*|\*/)@g)) {
Andy Whitcroft8905a672007-11-28 16:21:06 -0800884 if ($1 eq '/*') {
885 $in_comment = 1;
886 } else {
887 $in_comment = 0;
888 }
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800889 $comment_edge = 1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700890 }
891
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700892 # Measure the line length and indent.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800893 ($length, $indent) = line_stats($rawline);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700894
895 # Track the previous line.
896 ($prevline, $stashline) = ($stashline, $line);
897 ($previndent, $stashindent) = ($stashindent, $indent);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800898 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
899
900 #warn "ic<$in_comment> ce<$comment_edge> line<$line>\n";
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700901
Andy Whitcroftd8aaf122007-06-23 17:16:44 -0700902 } elsif ($realcnt == 1) {
903 $realcnt--;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700904 }
905
906#make up the handle for any error we report on this line
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700907 $here = "#$linenr: " if (!$file);
908 $here = "#$realline: " if ($file);
Randy Dunlap389834b2007-06-08 13:47:03 -0700909 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700910
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800911 my $hereline = "$here\n$rawline\n";
912 my $herecurr = "$here\n$rawline\n";
913 my $hereprev = "$here\n$prevrawline\n$rawline\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700914
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700915 $prefix = "$filename:$realline: " if ($emacs && $file);
916 $prefix = "$filename:$linenr: " if ($emacs && !$file);
917 $cnt_lines++ if ($realcnt != 0);
918
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700919#check the patch for a signoff:
Andy Whitcroftd8aaf122007-06-23 17:16:44 -0700920 if ($line =~ /^\s*signed-off-by:/i) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -0700921 # This is a signoff, if ugly, so do not double report.
922 $signoff++;
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700923 if (!($line =~ /^\s*Signed-off-by:/)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700924 WARN("Signed-off-by: is the preferred form\n" .
925 $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700926 }
927 if ($line =~ /^\s*signed-off-by:\S/i) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700928 WARN("need space after Signed-off-by:\n" .
929 $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700930 }
931 }
932
Andy Whitcroft00df3442007-06-08 13:47:06 -0700933# Check for wrappage within a valid hunk of the file
Andy Whitcroft8905a672007-11-28 16:21:06 -0800934 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700935 ERROR("patch seems to be corrupt (line wrapped?)\n" .
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -0700936 $herecurr) if (!$emitted_corrupt++);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700937 }
938
939# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
940 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800941 !($rawline =~ m/^(
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700942 [\x09\x0A\x0D\x20-\x7E] # ASCII
943 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
944 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
945 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
946 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
947 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
948 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
949 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
950 )*$/x )) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800951 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $herecurr);
Andy Whitcroft00df3442007-06-08 13:47:06 -0700952 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700953
Andy Whitcroft00df3442007-06-08 13:47:06 -0700954#ignore lines being removed
955 if ($line=~/^-/) {next;}
956
957# check we are in a valid source file if not then ignore this hunk
958 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700959
960#trailing whitespace
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700961 if ($line =~ /^\+.*\015/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800962 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -0700963 ERROR("DOS line endings\n" . $herevet);
964
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800965 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
966 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700967 ERROR("trailing whitespace\n" . $herevet);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700968 }
969#80 column limit
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800970 if ($line =~ /^\+/ && !($prevrawline=~/\/\*\*/) && $length > 80) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700971 WARN("line over 80 characters\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700972 }
973
Andy Whitcroft8905a672007-11-28 16:21:06 -0800974# check for adding lines without a newline.
975 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
976 WARN("adding a line without newline at end of file\n" . $herecurr);
977 }
978
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700979# check we are in a valid source file *.[hc] if not then ignore this hunk
980 next if ($realfile !~ /\.[hc]$/);
981
982# at the beginning of a line any tabs must come first and anything
983# more than 8 must use tabs.
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800984 if ($rawline =~ /^\+\s* \t\s*\S/ ||
985 $rawline =~ /^\+\s* \s*/) {
986 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
Andy Whitcroftde7d4f02007-07-15 23:37:22 -0700987 ERROR("use tabs not spaces\n" . $herevet);
Andy Whitcroft0a920b52007-06-01 00:46:48 -0700988 }
989
Andy Whitcroftc2fdda02008-02-08 04:20:54 -0800990# check for RCS/CVS revision markers
991 if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) {
992 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
993 }
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -0700994
995# The rest of our checks refer specifically to C style
996# only apply those _outside_ comments. Only skip
997# lines in the middle of comments.
998 next if (!$comment_edge && $in_comment);
Andy Whitcroft00df3442007-06-08 13:47:06 -0700999
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001000# Check for potential 'bare' types
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001001 if ($realcnt) {
1002 # Ignore goto labels.
1003 if ($line =~ /$Ident:\*$/) {
1004
1005 # Ignore functions being called
1006 } elsif ($line =~ /^.\s*$Ident\s*\(/) {
1007
Andy Whitcroft8905a672007-11-28 16:21:06 -08001008 # definitions in global scope can only start with types
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001009 } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001010 possible($1, $line);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001011
1012 # declarations always start with types
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001013 } elsif ($prev_values eq 'E' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08001014 possible($1);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001015 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001016
1017 # any (foo ... *) is a pointer cast, and foo is a type
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001018 while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) {
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001019 possible($1, $line);
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001020 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001021
1022 # Check for any sort of function declaration.
1023 # int foo(something bar, other baz);
1024 # void (*store_gdt)(x86_descr_ptr *);
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001025 if ($prev_values eq 'E' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08001026 my ($name_len) = length($1);
1027 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len);
1028 my $ctx = join("\n", @ctx);
1029
1030 $ctx =~ s/\n.//;
1031 substr($ctx, 0, $name_len + 1) = '';
1032 $ctx =~ s/\)[^\)]*$//;
1033 for my $arg (split(/\s*,\s*/, $ctx)) {
1034 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) {
1035
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001036 possible($1, $line);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001037 }
1038 }
1039 }
1040
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001041 }
1042
Andy Whitcroft653d4872007-06-23 17:16:34 -07001043#
1044# Checks which may be anchored in the context.
1045#
1046
1047# Check for switch () and associated case and default
1048# statements should be at the same indent.
Andy Whitcroft00df3442007-06-08 13:47:06 -07001049 if ($line=~/\bswitch\s*\(.*\)/) {
1050 my $err = '';
1051 my $sep = '';
1052 my @ctx = ctx_block_outer($linenr, $realcnt);
1053 shift(@ctx);
1054 for my $ctx (@ctx) {
1055 my ($clen, $cindent) = line_stats($ctx);
1056 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
1057 $indent != $cindent) {
1058 $err .= "$sep$ctx\n";
1059 $sep = '';
1060 } else {
1061 $sep = "[...]\n";
1062 }
1063 }
1064 if ($err ne '') {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001065 ERROR("switch and case should be at the same indent\n$hereline$err");
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001066 }
1067 }
1068
1069# if/while/etc brace do not go on next line, unless defining a do while loop,
1070# or if that brace on the next line is for something else
1071 if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001072 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001073 my $ctx_ln = $linenr + $#ctx + 1;
1074 my $ctx_cnt = $realcnt - $#ctx - 1;
1075 my $ctx = join("\n", @ctx);
1076
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001077 # Skip over any removed lines in the context following statement.
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001078 while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) {
1079 $ctx_ln++;
1080 $ctx_cnt--;
1081 }
1082 ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>";
1083
1084 if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001085 ERROR("That open brace { should be on the previous line\n" .
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001086 "$here\n$ctx\n$lines[$ctx_ln - 1]");
Andy Whitcroft00df3442007-06-08 13:47:06 -07001087 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001088 if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) {
1089 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
1090 if ($nindent > $indent) {
1091 WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" .
1092 "$here\n$ctx\n$lines[$ctx_ln - 1]");
1093 }
1094 }
Andy Whitcroft00df3442007-06-08 13:47:06 -07001095 }
1096
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001097 # Track the 'values' across context and added lines.
1098 my $opline = $line; $opline =~ s/^./ /;
1099 my $curr_values = annotate_values($opline . "\n", $prev_values);
1100 $curr_values = $prev_values . $curr_values;
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001101 if ($dbg_values) {
1102 my $outline = $opline; $outline =~ s/\t/ /g;
1103 warn "--> .$outline\n";
1104 warn "--> $curr_values\n";
1105 }
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001106 $prev_values = substr($curr_values, -1);
1107
Andy Whitcroft00df3442007-06-08 13:47:06 -07001108#ignore lines not being added
1109 if ($line=~/^[^\+]/) {next;}
1110
Andy Whitcroft653d4872007-06-23 17:16:34 -07001111# TEST: allow direct testing of the type matcher.
1112 if ($tst_type && $line =~ /^.$Declare$/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001113 ERROR("TEST: is type $Declare\n" . $herecurr);
Andy Whitcroft653d4872007-06-23 17:16:34 -07001114 next;
1115 }
1116
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001117# check for initialisation to aggregates open brace on the next line
1118 if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
1119 $line =~ /^.\s*{/) {
1120 ERROR("That open brace { should be on the previous line\n" . $hereprev);
1121 }
1122
Andy Whitcroft653d4872007-06-23 17:16:34 -07001123#
1124# Checks which are anchored on the added line.
1125#
1126
1127# check for malformed paths in #include statements (uses RAW line)
1128 if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) {
1129 my $path = $1;
1130 if ($path =~ m{//}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001131 ERROR("malformed #include filename\n" .
1132 $herecurr);
Andy Whitcroft653d4872007-06-23 17:16:34 -07001133 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001134 }
Andy Whitcroft00df3442007-06-08 13:47:06 -07001135
1136# no C99 // comments
1137 if ($line =~ m{//}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001138 ERROR("do not use C99 // comments\n" . $herecurr);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001139 }
1140 # Remove C99 comments.
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001141 $line =~ s@//.*@@;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001142 $opline =~ s@//.*@@;
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001143
1144#EXPORT_SYMBOL should immediately follow its function closing }.
Andy Whitcroft653d4872007-06-23 17:16:34 -07001145 if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
1146 ($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1147 my $name = $1;
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001148 if (($prevline !~ /^}/) &&
1149 ($prevline !~ /^\+}/) &&
Andy Whitcroft653d4872007-06-23 17:16:34 -07001150 ($prevline !~ /^ }/) &&
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001151 ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001152 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001153 }
1154 }
1155
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001156# check for external initialisers.
1157 if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL);/) {
1158 ERROR("do not initialise externals to 0 or NULL\n" .
1159 $herecurr);
1160 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001161# check for static initialisers.
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001162 if ($line =~ /\s*static\s.*=\s*(0|NULL);/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001163 ERROR("do not initialise statics to 0 or NULL\n" .
1164 $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001165 }
1166
Andy Whitcroft653d4872007-06-23 17:16:34 -07001167# check for new typedefs, only function parameters and sparse annotations
1168# make sense.
1169 if ($line =~ /\btypedef\s/ &&
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001170 $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
Andy Whitcroft653d4872007-06-23 17:16:34 -07001171 $line !~ /\b__bitwise(?:__|)\b/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001172 WARN("do not add new typedefs\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001173 }
1174
1175# * goes on variable not on type
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001176 if ($line =~ m{\($NonptrType(\*+)(?:\s+const)?\)}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001177 ERROR("\"(foo$1)\" should be \"(foo $1)\"\n" .
1178 $herecurr);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001179
1180 } elsif ($line =~ m{\($NonptrType\s+(\*+)(?!\s+const)\s+\)}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001181 ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" .
1182 $herecurr);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001183
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001184 } elsif ($line =~ m{$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001185 ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" .
1186 $herecurr);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001187
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001188 } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001189 ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" .
1190 $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001191 }
1192
1193# # no BUG() or BUG_ON()
1194# if ($line =~ /\b(BUG|BUG_ON)\b/) {
1195# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
1196# print "$herecurr";
1197# $clean = 0;
1198# }
1199
Andy Whitcroft8905a672007-11-28 16:21:06 -08001200 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001201 WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001202 }
1203
Andy Whitcroft00df3442007-06-08 13:47:06 -07001204# printk should use KERN_* levels. Note that follow on printk's on the
1205# same line do not need a level, so we use the current block context
1206# to try and find and validate the current printk. In summary the current
1207# printk includes all preceeding printk's which have no newline on the end.
1208# we assume the first bad printk is the one to report.
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001209 if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
Andy Whitcroft00df3442007-06-08 13:47:06 -07001210 my $ok = 0;
1211 for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
1212 #print "CHECK<$lines[$ln - 1]\n";
1213 # we have a preceeding printk if it ends
1214 # with "\n" ignore it, else it is to blame
1215 if ($lines[$ln - 1] =~ m{\bprintk\(}) {
1216 if ($rawlines[$ln - 1] !~ m{\\n"}) {
1217 $ok = 1;
1218 }
1219 last;
1220 }
1221 }
1222 if ($ok == 0) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001223 WARN("printk() should include KERN_ facility level\n" . $herecurr);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001224 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001225 }
1226
Andy Whitcroft653d4872007-06-23 17:16:34 -07001227# function brace can't be on same line, except for #defines of do while,
1228# or if closed on same line
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001229 if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).*\s{/) and
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001230 !($line=~/\#define.*do\s{/) and !($line=~/}/)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001231 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001232 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001233
Andy Whitcroft8905a672007-11-28 16:21:06 -08001234# open braces for enum, union and struct go on the same line.
1235 if ($line =~ /^.\s*{/ &&
1236 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
1237 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
1238 }
1239
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001240# check for spaces between functions and their parentheses.
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001241 while ($line =~ /($Ident)\s+\(/g) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001242 my $name = $1;
1243 my $ctx = substr($line, 0, $-[1]);
1244
1245 # Ignore those directives where spaces _are_ permitted.
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001246 if ($name =~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case|__asm__)$/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001247
1248 # cpp #define statements have non-optional spaces, ie
1249 # if there is a space between the name and the open
1250 # parenthesis it is simply not a parameter group.
1251 } elsif ($ctx =~ /^.\#\s*define\s*$/) {
1252
1253 # If this whole things ends with a type its most
1254 # likely a typedef for a function.
1255 } elsif ("$ctx$name" =~ /$Type$/) {
1256
1257 } else {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001258 WARN("no space between function name and open parenthesis '('\n" . $herecurr);
1259 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001260 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001261# Check operator spacing.
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001262 if (!($line=~/\#\s*include/)) {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001263 my $ops = qr{
1264 <<=|>>=|<=|>=|==|!=|
1265 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
1266 =>|->|<<|>>|<|>|=|!|~|
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001267 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001268 }x;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001269 my @elements = split(/($;+|$ops|;)/, $opline);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001270 my $off = 0;
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001271
1272 my $blank = copy_spacing($opline);
1273
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001274 for (my $n = 0; $n < $#elements; $n += 2) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001275 $off += length($elements[$n]);
1276
1277 my $a = '';
1278 $a = 'V' if ($elements[$n] ne '');
1279 $a = 'W' if ($elements[$n] =~ /\s$/);
1280 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
1281 $a = 'O' if ($elements[$n] eq '');
1282 $a = 'E' if ($elements[$n] eq '' && $n == 0);
1283
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001284 my $op = $elements[$n + 1];
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001285
1286 my $c = '';
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001287 if (defined $elements[$n + 2]) {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001288 $c = 'V' if ($elements[$n + 2] ne '');
1289 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
1290 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
1291 $c = 'O' if ($elements[$n + 2] eq '');
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001292 $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001293 } else {
1294 $c = 'E';
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001295 }
1296
Andy Whitcroft00df3442007-06-08 13:47:06 -07001297 # Pick up the preceeding and succeeding characters.
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001298 my $ca = substr($opline, 0, $off);
Andy Whitcroft00df3442007-06-08 13:47:06 -07001299 my $cc = '';
Andy Whitcroft653d4872007-06-23 17:16:34 -07001300 if (length($opline) >= ($off + length($elements[$n + 1]))) {
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001301 $cc = substr($opline, $off + length($elements[$n + 1]));
Andy Whitcroft00df3442007-06-08 13:47:06 -07001302 }
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001303 my $cb = "$ca$;$cc";
Andy Whitcroft00df3442007-06-08 13:47:06 -07001304
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001305 my $ctx = "${a}x${c}";
1306
1307 my $at = "(ctx:$ctx)";
1308
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001309 my $ptr = substr($blank, 0, $off) . "^";
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001310 my $hereptr = "$hereline$ptr\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001311
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001312 # Classify operators into binary, unary, or
1313 # definitions (* only) where they have more
1314 # than one mode.
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001315 my $op_type = substr($curr_values, $off + 1, 1);
1316 my $op_left = substr($curr_values, $off, 1);
1317 my $is_unary;
1318 if ($op_type eq 'T') {
1319 $is_unary = 2;
1320 } elsif ($op_left eq 'V') {
1321 $is_unary = 0;
1322 } else {
1323 $is_unary = 1;
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001324 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001325 #if ($op eq '-' || $op eq '&' || $op eq '*') {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001326 # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001327 #}
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001328
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001329 # Ignore operators passed as parameters.
1330 if ($op_type ne 'V' &&
1331 $ca =~ /\s$/ && $cc =~ /^\s*,/) {
1332
1333 # Ignore comments
1334 } elsif ($op =~ /^$;+$/) {
1335
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001336 # ; should have either the end of line or a space or \ after it
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001337 } elsif ($op eq ';') {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001338 if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ &&
1339 $cc !~ /^;/) {
1340 ERROR("need space after that '$op' $at\n" . $hereptr);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001341 }
1342
1343 # // is a comment
1344 } elsif ($op eq '//') {
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001345
1346 # -> should have no spaces
1347 } elsif ($op eq '->') {
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001348 if ($ctx =~ /Wx.|.xW/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001349 ERROR("no spaces around that '$op' $at\n" . $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001350 }
1351
1352 # , must have a space on the right.
1353 } elsif ($op eq ',') {
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001354 if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001355 ERROR("need space after that '$op' $at\n" . $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001356 }
1357
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001358 # '*' as part of a type definition -- reported already.
1359 } elsif ($op eq '*' && $is_unary == 2) {
1360 #warn "'*' is part of type\n";
1361
1362 # unary operators should have a space before and
1363 # none after. May be left adjacent to another
1364 # unary operator, or a cast
1365 } elsif ($op eq '!' || $op eq '~' ||
1366 ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) {
1367 if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001368 ERROR("need space before that '$op' $at\n" . $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001369 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001370 if ($ctx =~ /.xW/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001371 ERROR("no space after that '$op' $at\n" . $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001372 }
1373
1374 # unary ++ and unary -- are allowed no space on one side.
1375 } elsif ($op eq '++' or $op eq '--') {
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001376 if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001377 ERROR("need space one side of that '$op' $at\n" . $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001378 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001379 if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001380 ERROR("no space before that '$op' $at\n" . $hereptr);
Andy Whitcroft653d4872007-06-23 17:16:34 -07001381 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001382
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001383 # << and >> may either have or not have spaces both sides
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001384 } elsif ($op eq '<<' or $op eq '>>' or
1385 $op eq '&' or $op eq '^' or $op eq '|' or
1386 $op eq '+' or $op eq '-' or
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001387 $op eq '*' or $op eq '/' or
1388 $op eq '%')
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001389 {
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001390 if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001391 ERROR("need consistent spacing around '$op' $at\n" .
1392 $hereptr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001393 }
1394
1395 # All the others need spaces both sides.
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001396 } elsif ($ctx !~ /[EW]x[WE]/) {
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001397 # Ignore email addresses <foo@bar>
1398 if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) &&
1399 !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) {
1400 ERROR("need spaces around that '$op' $at\n" . $hereptr);
1401 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001402 }
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001403 $off += length($elements[$n + 1]);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001404 }
1405 }
1406
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001407# check for multiple assignments
1408 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001409 CHK("multiple assignments should be avoided\n" . $herecurr);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001410 }
1411
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001412## # check for multiple declarations, allowing for a function declaration
1413## # continuation.
1414## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
1415## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
1416##
1417## # Remove any bracketed sections to ensure we do not
1418## # falsly report the parameters of functions.
1419## my $ln = $line;
1420## while ($ln =~ s/\([^\(\)]*\)//g) {
1421## }
1422## if ($ln =~ /,/) {
1423## WARN("declaring multiple variables together should be avoided\n" . $herecurr);
1424## }
1425## }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001426
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001427#need space before brace following if, while, etc
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001428 if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
1429 $line =~ /do{/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001430 ERROR("need a space before the open brace '{'\n" . $herecurr);
1431 }
1432
1433# closing brace should have a space following it when it has anything
1434# on the line
1435 if ($line =~ /}(?!(?:,|;|\)))\S/) {
1436 ERROR("need a space after that close brace '}'\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001437 }
1438
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001439# check spacing on square brackets
1440 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
1441 ERROR("no space after that open square bracket '['\n" . $herecurr);
1442 }
1443 if ($line =~ /\s\]/) {
1444 ERROR("no space before that close square bracket ']'\n" . $herecurr);
1445 }
1446
1447# check spacing on paretheses
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001448 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
1449 $line !~ /for\s*\(\s+;/) {
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001450 ERROR("no space after that open parenthesis '('\n" . $herecurr);
1451 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001452 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001453 $line !~ /for\s*\(.*;\s+\)/) {
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001454 ERROR("no space before that close parenthesis ')'\n" . $herecurr);
1455 }
1456
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001457#goto labels aren't indented, allow a single space however
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001458 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001459 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001460 WARN("labels should not be indented\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001461 }
1462
1463# Need a space before open parenthesis after if, while etc
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001464 if ($line=~/\b(if|while|for|switch)\(/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001465 ERROR("need a space before the open parenthesis '('\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001466 }
1467
1468# Check for illegal assignment in if conditional.
Andy Whitcroft8905a672007-11-28 16:21:06 -08001469 if ($line =~ /\bif\s*\(/) {
1470 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
1471
1472 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001473 ERROR("do not use assignment in if condition\n" . $herecurr);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001474 }
1475
1476 # Find out what is on the end of the line after the
1477 # conditional.
1478 substr($s, 0, length($c)) = '';
1479 $s =~ s/\n.*//g;
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001480 $s =~ s/$;//g; # Remove any comments
1481 if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/) {
Andy Whitcroft8905a672007-11-28 16:21:06 -08001482 ERROR("trailing statements should be on next line\n" . $herecurr);
1483 }
1484 }
1485
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001486# Check for bitwise tests written as boolean
1487 if ($line =~ /
1488 (?:
1489 (?:\[|\(|\&\&|\|\|)
1490 \s*0[xX][0-9]+\s*
1491 (?:\&\&|\|\|)
1492 |
1493 (?:\&\&|\|\|)
1494 \s*0[xX][0-9]+\s*
1495 (?:\&\&|\|\||\)|\])
1496 )/x)
1497 {
1498 WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
1499 }
1500
Andy Whitcroft8905a672007-11-28 16:21:06 -08001501# if and else should not have general statements after it
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001502 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
1503 my $s = $1;
1504 $s =~ s/$;//g; # Remove any comments
1505 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
1506 ERROR("trailing statements should be on next line\n" . $herecurr);
1507 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001508 }
1509
1510 # Check for }<nl>else {, these must be at the same
1511 # indent level to be relevant to each other.
1512 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
1513 $previndent == $indent) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001514 ERROR("else should follow close brace '}'\n" . $hereprev);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001515 }
1516
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001517 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
1518 $previndent == $indent) {
1519 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
1520
1521 # Find out what is on the end of the line after the
1522 # conditional.
1523 substr($s, 0, length($c)) = '';
1524 $s =~ s/\n.*//g;
1525
1526 if ($s =~ /^\s*;/) {
1527 ERROR("while should follow close brace '}'\n" . $hereprev);
1528 }
1529 }
1530
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001531#studly caps, commented out until figure out how to distinguish between use of existing and adding new
1532# if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
1533# print "No studly caps, use _\n";
1534# print "$herecurr";
1535# $clean = 0;
1536# }
1537
1538#no spaces allowed after \ in define
1539 if ($line=~/\#define.*\\\s$/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001540 WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001541 }
1542
Andy Whitcroft653d4872007-06-23 17:16:34 -07001543#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
1544 if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001545 my $checkfile = "$root/include/linux/$1.h";
1546 if (-f $checkfile && $1 ne 'irq.h') {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001547 CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
1548 $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001549 }
1550 }
1551
Andy Whitcroft653d4872007-06-23 17:16:34 -07001552# multi-statement macros should be enclosed in a do while loop, grab the
1553# first statement and ensure its the whole macro if its not enclosed
1554# in a known goot container
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001555 if ($prevline =~ /\#define.*\\/ &&
1556 $prevline !~/(?:do\s+{|\(\{|\{)/ &&
1557 $line !~ /(?:do\s+{|\(\{|\{)/ &&
1558 $line !~ /^.\s*$Declare\s/) {
Andy Whitcroft653d4872007-06-23 17:16:34 -07001559 # Grab the first statement, if that is the entire macro
1560 # its ok. This may start either on the #define line
1561 # or the one below.
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001562 my $ln = $linenr;
1563 my $cnt = $realcnt;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001564 my $off = 0;
Andy Whitcroft653d4872007-06-23 17:16:34 -07001565
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001566 # If the macro starts on the define line start
1567 # grabbing the statement after the identifier
1568 $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$};
1569 ##print "1<$1> 2<$2>\n";
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001570 if (defined $2 && $2 ne '') {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001571 $off = length($1);
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001572 $ln--;
1573 $cnt++;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001574 while ($lines[$ln - 1] =~ /^-/) {
1575 $ln--;
1576 $cnt++;
1577 }
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001578 }
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001579 my @ctx = ctx_statement($ln, $cnt, $off);
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001580 my $ctx_ln = $ln + $#ctx + 1;
1581 my $ctx = join("\n", @ctx);
1582
1583 # Pull in any empty extension lines.
1584 while ($ctx =~ /\\$/ &&
1585 $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) {
1586 $ctx .= $lines[$ctx_ln - 1];
1587 $ctx_ln++;
1588 }
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001589
1590 if ($ctx =~ /\\$/) {
1591 if ($ctx =~ /;/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001592 ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001593 } else {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001594 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
Andy Whitcroftd8aaf122007-06-23 17:16:44 -07001595 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001596 }
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001597 }
1598
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001599# check for redundant bracing round if etc
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001600 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
1601 my ($level, $endln, @chunks) =
1602 ctx_statement_full($linenr, $realcnt, 0);
1603 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
1604 if ($#chunks > 1 && $level == 0) {
1605 my $allowed = 0;
1606 my $seen = 0;
1607 for my $chunk (@chunks) {
1608 my ($cond, $block) = @{$chunk};
1609
1610 substr($block, 0, length($cond)) = '';
1611
1612 $seen++ if ($block =~ /^\s*{/);
1613
1614 $block =~ s/(^|\n)./$1/g;
1615 $block =~ s/^\s*{//;
1616 $block =~ s/}\s*$//;
1617 $block =~ s/^\s*//;
1618 $block =~ s/\s*$//;
1619
1620 my @lines = ($block =~ /\n/g);
1621 my @statements = ($block =~ /;/g);
1622
1623 #print "cond<$cond> block<$block> lines<" . scalar(@lines) . "> statements<" . scalar(@statements) . "> seen<$seen> allowed<$allowed>\n";
1624 if (scalar(@lines) != 0) {
1625 $allowed = 1;
1626 }
1627 if ($block =~/\b(?:if|for|while)\b/) {
1628 $allowed = 1;
1629 }
1630 if (scalar(@statements) > 1) {
1631 $allowed = 1;
1632 }
1633 }
1634 if ($seen && !$allowed) {
1635 WARN("braces {} are not necessary for any arm of this statement\n" . $herecurr);
1636 $suppress_ifbraces = $endln;
1637 }
1638 }
1639 }
1640 if ($linenr > $suppress_ifbraces &&
1641 $line =~ /\b(if|while|for|else)\b/) {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001642 # Locate the end of the opening statement.
1643 my @control = ctx_statement($linenr, $realcnt, 0);
1644 my $nr = $linenr + (scalar(@control) - 1);
1645 my $cnt = $realcnt - (scalar(@control) - 1);
1646
1647 my $off = $realcnt - $cnt;
1648 #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n";
1649
1650 # If this is is a braced statement group check it
1651 if ($lines[$nr - 1] =~ /{\s*$/) {
1652 my ($lvl, @block) = ctx_block_level($nr, $cnt);
1653
Andy Whitcroft8905a672007-11-28 16:21:06 -08001654 my $stmt = join("\n", @block);
1655 # Drop the diff line leader.
1656 $stmt =~ s/\n./\n/g;
1657 # Drop the code outside the block.
1658 $stmt =~ s/(^[^{]*){\s*//;
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001659 my $before = $1;
Andy Whitcroft8905a672007-11-28 16:21:06 -08001660 $stmt =~ s/\s*}([^}]*$)//;
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001661 my $after = $1;
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001662
1663 #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001664 #print "before<$before> stmt<$stmt> after<$after>\n\n";
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001665
Andy Whitcroft8905a672007-11-28 16:21:06 -08001666 # Count the newlines, if there is only one
1667 # then the block should not have {}'s.
1668 my @lines = ($stmt =~ /\n/g);
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001669 my @statements = ($stmt =~ /;/g);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001670 #print "lines<" . scalar(@lines) . ">\n";
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001671 #print "statements<" . scalar(@statements) . ">\n";
Andy Whitcroft8905a672007-11-28 16:21:06 -08001672 if ($lvl == 0 && scalar(@lines) == 0 &&
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001673 scalar(@statements) < 2 &&
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001674 $stmt !~ /{/ && $stmt !~ /\bif\b/ &&
1675 $before !~ /}/ && $after !~ /{/) {
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001676 my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
1677 shift(@block);
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001678 WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001679 }
1680 }
1681 }
1682
Andy Whitcroft653d4872007-06-23 17:16:34 -07001683# don't include deprecated include files (uses RAW line)
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001684 for my $inc (@dep_includes) {
Andy Whitcroft653d4872007-06-23 17:16:34 -07001685 if ($rawline =~ m@\#\s*include\s*\<$inc>@) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001686 ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001687 }
1688 }
1689
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001690# don't use deprecated functions
1691 for my $func (@dep_functions) {
Andy Whitcroft00df3442007-06-08 13:47:06 -07001692 if ($line =~ /\b$func\b/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001693 ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001694 }
1695 }
1696
1697# no volatiles please
Andy Whitcroft6c72ffa2007-10-18 03:05:08 -07001698 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
1699 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001700 WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001701 }
1702
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001703# SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated
1704 if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) {
1705 ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr);
1706 }
1707
Andy Whitcroft00df3442007-06-08 13:47:06 -07001708# warn about #if 0
1709 if ($line =~ /^.#\s*if\s+0\b/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001710 CHK("if this code is redundant consider removing it\n" .
1711 $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001712 }
1713
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001714# check for needless kfree() checks
1715 if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
1716 my $expr = $1;
1717 if ($line =~ /\bkfree\(\Q$expr\E\);/) {
1718 WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev);
1719 }
1720 }
1721
Andy Whitcroft00df3442007-06-08 13:47:06 -07001722# warn about #ifdefs in C files
1723# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
1724# print "#ifdef in C files should be avoided\n";
1725# print "$herecurr";
1726# $clean = 0;
1727# }
1728
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001729# warn about spacing in #ifdefs
1730 if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) {
1731 ERROR("exactly one space required after that #$1\n" . $herecurr);
1732 }
1733
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001734# check for spinlock_t definitions without a comment.
1735 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) {
1736 my $which = $1;
1737 if (!ctx_has_comment($first_line, $linenr)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001738 CHK("$1 definition without comment\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001739 }
1740 }
1741# check for memory barriers without a comment.
1742 if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
1743 if (!ctx_has_comment($first_line, $linenr)) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001744 CHK("memory barrier without comment\n" . $herecurr);
Andy Whitcroft4a0df2e2007-06-08 13:46:39 -07001745 }
1746 }
1747# check of hardware specific defines
Andy Whitcroft22f2a2e2007-08-10 13:01:03 -07001748 if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001749 CHK("architecture specific defines should be avoided\n" . $herecurr);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001750 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001751
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001752# check the location of the inline attribute, that it is between
1753# storage class and type.
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001754 if ($line =~ /\b$Type\s+$Inline\b/ ||
1755 $line =~ /\b$Inline\s+$Storage\b/) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001756 ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
1757 }
1758
Andy Whitcroft8905a672007-11-28 16:21:06 -08001759# Check for __inline__ and __inline, prefer inline
1760 if ($line =~ /\b(__inline__|__inline)\b/) {
1761 WARN("plain inline is preferred over $1\n" . $herecurr);
1762 }
1763
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001764# check for new externs in .c files.
1765 if ($line =~ /^.\s*extern\s/ && ($realfile =~ /\.c$/)) {
1766 WARN("externs should be avoided in .c files\n" . $herecurr);
1767 }
1768
1769# checks for new __setup's
1770 if ($rawline =~ /\b__setup\("([^"]*)"/) {
1771 my $name = $1;
1772
1773 if (!grep(/$name/, @setup_docs)) {
1774 CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
1775 }
Andy Whitcroft653d4872007-06-23 17:16:34 -07001776 }
Andy Whitcroft9c0ca6f2007-10-16 23:29:38 -07001777
1778# check for pointless casting of kmalloc return
1779 if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) {
1780 WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
1781 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001782
1783# check for gcc specific __FUNCTION__
1784 if ($line =~ /__FUNCTION__/) {
1785 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
1786 }
1787 }
1788
1789 # If we have no input at all, then there is nothing to report on
1790 # so just keep quiet.
1791 if ($#rawlines == -1) {
1792 exit(0);
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001793 }
1794
Andy Whitcroft8905a672007-11-28 16:21:06 -08001795 # In mailback mode only produce a report in the negative, for
1796 # things that appear to be patches.
1797 if ($mailback && ($clean == 1 || !$is_patch)) {
1798 exit(0);
1799 }
1800
1801 # This is not a patch, and we are are in 'no-patch' mode so
1802 # just keep quiet.
1803 if (!$chk_patch && !$is_patch) {
1804 exit(0);
1805 }
1806
1807 if (!$is_patch) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001808 ERROR("Does not appear to be a unified-diff format patch\n");
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001809 }
1810 if ($is_patch && $chk_signoff && $signoff == 0) {
Andy Whitcroftde7d4f02007-07-15 23:37:22 -07001811 ERROR("Missing Signed-off-by: line(s)\n");
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001812 }
1813
Andy Whitcroft8905a672007-11-28 16:21:06 -08001814 print report_dump();
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001815 if ($summary && !($clean == 1 && $quiet == 1)) {
1816 print "$filename " if ($summary_file);
Andy Whitcroft8905a672007-11-28 16:21:06 -08001817 print "total: $cnt_error errors, $cnt_warn warnings, " .
1818 (($check)? "$cnt_chk checks, " : "") .
1819 "$cnt_lines lines checked\n";
1820 print "\n" if ($quiet == 0);
Andy Whitcroftf0a594c2007-07-19 01:48:34 -07001821 }
Andy Whitcroft8905a672007-11-28 16:21:06 -08001822
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001823 if ($clean == 1 && $quiet == 0) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001824 print "$vname has no obvious style problems and is ready for submission.\n"
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001825 }
1826 if ($clean == 0 && $quiet == 0) {
Andy Whitcroftc2fdda02008-02-08 04:20:54 -08001827 print "$vname has style problems, please review. If any of these errors\n";
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001828 print "are false positives report them to the maintainer, see\n";
1829 print "CHECKPATCH in MAINTAINERS.\n";
1830 }
Andy Whitcroft13214ad2008-02-08 04:22:03 -08001831 print <<EOL if ($file == 1 && $quiet == 0);
1832
1833WARNING: Using --file mode. Please do not send patches to linux-kernel
1834that change whole existing files if you did not significantly change most
1835of the the file for other reasons anyways or just wrote the file newly
1836from scratch. Pure code style patches have a significant cost in a
1837quickly changing code base like Linux because they cause rejects
1838with other changes.
1839EOL
1840
Andy Whitcroft0a920b52007-06-01 00:46:48 -07001841 return $clean;
1842}