checkpatch.pl 60.4 KB
Newer Older
1
2
#!/usr/bin/perl -w
# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
3
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4
5
6
7
8
9
# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
# Licensed under the terms of the GNU GPL License version 2

use strict;

my $P = $0;
10
$P =~ s@.*/@@g;
11

Andy Whitcroft's avatar
Andy Whitcroft committed
12
my $V = '0.20';
13
14
15
16
17
18
19

use Getopt::Long qw(:config no_auto_abbrev);

my $quiet = 0;
my $tree = 1;
my $chk_signoff = 1;
my $chk_patch = 1;
20
my $tst_only;
21
my $emacs = 0;
22
my $terse = 0;
23
24
my $file = 0;
my $check = 0;
25
26
my $summary = 1;
my $mailback = 0;
27
my $summary_file = 0;
28
my $root;
29
my %debug;
30
GetOptions(
31
	'q|quiet+'	=> \$quiet,
32
33
34
	'tree!'		=> \$tree,
	'signoff!'	=> \$chk_signoff,
	'patch!'	=> \$chk_patch,
35
	'emacs!'	=> \$emacs,
36
	'terse!'	=> \$terse,
37
38
39
40
	'file!'		=> \$file,
	'subjective!'	=> \$check,
	'strict!'	=> \$check,
	'root=s'	=> \$root,
41
42
	'summary!'	=> \$summary,
	'mailback!'	=> \$mailback,
43
44
	'summary-file!'	=> \$summary_file,

45
	'debug=s'	=> \%debug,
46
	'test-only=s'	=> \$tst_only,
47
48
49
50
51
) or exit;

my $exit = 0;

if ($#ARGV < 0) {
52
	print "usage: $P [options] patchfile\n";
53
	print "version: $V\n";
54
55
56
57
58
59
60
61
62
	print "options: -q               => quiet\n";
	print "         --no-tree        => run without a kernel tree\n";
	print "         --terse          => one line per report\n";
	print "         --emacs          => emacs compile window format\n";
	print "         --file           => check a source file\n";
	print "         --strict         => enable more subjective tests\n";
	print "         --root           => path to the kernel tree root\n";
	print "         --no-summary     => suppress the per-file summary\n";
	print "         --summary-file   => include the filename in summary\n";
63
64
65
	exit(1);
}

66
67
my $dbg_values = 0;
my $dbg_possible = 0;
68
my $dbg_type = 0;
69
70
71
72
for my $key (keys %debug) {
	eval "\${dbg_$key} = '$debug{$key}';"
}

73
74
75
76
77
if ($terse) {
	$emacs = 1;
	$quiet++;
}

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
if ($tree) {
	if (defined $root) {
		if (!top_of_kernel_tree($root)) {
			die "$P: $root: --root does not point at a valid tree\n";
		}
	} else {
		if (top_of_kernel_tree('.')) {
			$root = '.';
		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
						top_of_kernel_tree($1)) {
			$root = $1;
		}
	}

	if (!defined $root) {
		print "Must be run from the top-level dir. of a kernel tree\n";
		exit(2);
	}
96
97
}

98
99
100
101
102
103
104
105
106
107
108
my $emitted_corrupt = 0;

our $Ident       = qr{[A-Za-z_][A-Za-z\d_]*};
our $Storage	= qr{extern|static|asmlinkage};
our $Sparse	= qr{
			__user|
			__kernel|
			__force|
			__iomem|
			__must_check|
			__init_refok|
109
			__kprobes
110
111
112
113
114
115
116
		}x;
our $Attribute	= qr{
			const|
			__read_mostly|
			__kprobes|
			__(?:mem|cpu|dev|)(?:initdata|init)
		  }x;
117
our $Modifier;
118
119
120
121
122
123
124
125
126
our $Inline	= qr{inline|__always_inline|noinline};
our $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
our $Lval	= qr{$Ident(?:$Member)*};

our $Constant	= qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
our $Assignment	= qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
our $Operators	= qr{
			<=|>=|==|!=|
			=>|->|<<|>>|<|>|!|~|
127
			&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
128
129
		  }x;

130
131
132
133
our $NonptrType;
our $Type;
our $Declare;

134
135
136
137
138
139
140
141
142
143
144
our $UTF8	= qr {
	[\x09\x0A\x0D\x20-\x7E]              # ASCII
	| [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
}x;

145
146
our @typeList = (
	qr{void},
147
148
149
150
151
152
153
	qr{(?:unsigned\s+)?char},
	qr{(?:unsigned\s+)?short},
	qr{(?:unsigned\s+)?int},
	qr{(?:unsigned\s+)?long},
	qr{(?:unsigned\s+)?long\s+int},
	qr{(?:unsigned\s+)?long\s+long},
	qr{(?:unsigned\s+)?long\s+long\s+int},
154
155
156
157
158
159
160
161
162
163
164
165
	qr{unsigned},
	qr{float},
	qr{double},
	qr{bool},
	qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
	qr{struct\s+$Ident},
	qr{union\s+$Ident},
	qr{enum\s+$Ident},
	qr{${Ident}_t},
	qr{${Ident}_handler},
	qr{${Ident}_handler_fn},
);
166
167
168
our @modifierList = (
	qr{fastcall},
);
169
170

sub build_types {
171
	my $mods = "(?:  \n" . join("|\n  ", @modifierList) . "\n)";
172
	my $all = "(?:  \n" . join("|\n  ", @typeList) . "\n)";
173
	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
174
175
	$NonptrType	= qr{
			(?:const\s+)?
176
			(?:$mods\s+)?
177
			(?:
178
179
				(?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
				(?:${all}\b)
180
			)
181
			(?:\s+$Modifier|\s+const)*
182
183
		  }x;
	$Type	= qr{
184
			$NonptrType
185
			(?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
186
			(?:\s+$Inline|\s+$Modifier)*
187
188
189
190
		  }x;
	$Declare	= qr{(?:$Storage\s+)?$Type};
}
build_types();
191
192
193

$chk_signoff = 0 if ($file);

194
195
my @dep_includes = ();
my @dep_functions = ();
196
197
198
199
my $removal = "Documentation/feature-removal-schedule.txt";
if ($tree && -f "$root/$removal") {
	open(REMOVE, "<$root/$removal") ||
				die "$P: $removal: open failed - $!\n";
200
	while (<REMOVE>) {
201
202
203
		if (/^Check:\s+(.*\S)/) {
			for my $entry (split(/[, ]+/, $1)) {
				if ($entry =~ m@include/(.*)@) {
204
205
					push(@dep_includes, $1);

206
207
208
				} elsif ($entry !~ m@/@) {
					push(@dep_functions, $entry);
				}
209
			}
210
211
212
213
		}
	}
}

214
my @rawlines = ();
215
216
my @lines = ();
my $vname;
217
218
219
220
221
222
223
for my $filename (@ARGV) {
	if ($file) {
		open(FILE, "diff -u /dev/null $filename|") ||
			die "$P: $filename: diff failed - $!\n";
	} else {
		open(FILE, "<$filename") ||
			die "$P: $filename: open failed - $!\n";
224
	}
225
226
227
228
229
	if ($filename eq '-') {
		$vname = 'Your patch';
	} else {
		$vname = $filename;
	}
230
231
232
233
234
	while (<FILE>) {
		chomp;
		push(@rawlines, $_);
	}
	close(FILE);
235
	if (!process($filename)) {
236
237
238
		$exit = 1;
	}
	@rawlines = ();
239
	@lines = ();
240
241
242
243
244
}

exit($exit);

sub top_of_kernel_tree {
245
246
247
248
249
250
251
252
253
254
255
256
	my ($root) = @_;

	my @tree_check = (
		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
		"README", "Documentation", "arch", "include", "drivers",
		"fs", "init", "ipc", "kernel", "lib", "scripts",
	);

	foreach my $check (@tree_check) {
		if (! -e $root . '/' . $check) {
			return 0;
		}
257
	}
258
	return 1;
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
}

sub expand_tabs {
	my ($str) = @_;

	my $res = '';
	my $n = 0;
	for my $c (split(//, $str)) {
		if ($c eq "\t") {
			$res .= ' ';
			$n++;
			for (; ($n % 8) != 0; $n++) {
				$res .= ' ';
			}
			next;
		}
		$res .= $c;
		$n++;
	}

	return $res;
}
281
sub copy_spacing {
282
	(my $res = shift) =~ tr/\t/ /c;
283
284
	return $res;
}
285

286
287
288
289
290
291
292
293
294
295
296
297
298
sub line_stats {
	my ($line) = @_;

	# Drop the diff line leader and expand tabs
	$line =~ s/^.//;
	$line = expand_tabs($line);

	# Pick the indent from the front of the line.
	my ($white) = ($line =~ /^(\s*)/);

	return (length($line), length($white));
}

299
300
301
302
303
304
305
306
307
308
309
my $sanitise_quote = '';

sub sanitise_line_reset {
	my ($in_comment) = @_;

	if ($in_comment) {
		$sanitise_quote = '*/';
	} else {
		$sanitise_quote = '';
	}
}
310
311
312
313
314
315
sub sanitise_line {
	my ($line) = @_;

	my $res = '';
	my $l = '';

316
	my $qlen = 0;
317
318
	my $off = 0;
	my $c;
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
	# Always copy over the diff marker.
	$res = substr($line, 0, 1);

	for ($off = 1; $off < length($line); $off++) {
		$c = substr($line, $off, 1);

		# Comments we are wacking completly including the begin
		# and end, all to $;.
		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
			$sanitise_quote = '*/';

			substr($res, $off, 2, "$;$;");
			$off++;
			next;
334
		}
335
		if (substr($line, $off, 2) eq '*/') {
336
337
338
339
			$sanitise_quote = '';
			substr($res, $off, 2, "$;$;");
			$off++;
			next;
340
		}
341
342
343
344
345
346
347

		# A \ in a string means ignore the next character.
		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
		    $c eq "\\") {
			substr($res, $off, 2, 'XX');
			$off++;
			next;
348
		}
349
350
351
352
		# Regular quotes.
		if ($c eq "'" || $c eq '"') {
			if ($sanitise_quote eq '') {
				$sanitise_quote = $c;
353

354
355
356
357
358
359
				substr($res, $off, 1, $c);
				next;
			} elsif ($sanitise_quote eq $c) {
				$sanitise_quote = '';
			}
		}
360

361
362
363
364
365
366
367
368
		#print "SQ:$sanitise_quote\n";
		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
			substr($res, $off, 1, $;);
		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
			substr($res, $off, 1, 'X');
		} else {
			substr($res, $off, 1, $c);
		}
369
370
371
	}

	# The pathname on a #include may be surrounded by '<' and '>'.
372
	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
373
374
375
376
		my $clean = 'X' x length($1);
		$res =~ s@\<.*\>@<$clean>@;

	# The whole of a #error is a string.
377
	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
378
		my $clean = 'X' x length($1);
379
		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
380
381
	}

382
383
384
	return $res;
}

385
386
387
388
389
390
sub ctx_statement_block {
	my ($linenr, $remain, $off) = @_;
	my $line = $linenr - 1;
	my $blk = '';
	my $soff = $off;
	my $coff = $off - 1;
391
	my $coff_set = 0;
392

393
394
	my $loff = 0;

395
396
	my $type = '';
	my $level = 0;
397
	my $p;
398
399
	my $c;
	my $len = 0;
400
401

	my $remainder;
402
	while (1) {
403
		#warn "CSB: blk<$blk> remain<$remain>\n";
404
405
406
407
		# If we are about to drop off the end, pull in more
		# context.
		if ($off >= $len) {
			for (; $remain > 0; $line++) {
408
				next if ($lines[$line] =~ /^-/);
409
				$remain--;
410
				$loff = $len;
411
				$blk .= $lines[$line] . "\n";
412
413
414
415
416
417
				$len = length($blk);
				$line++;
				last;
			}
			# Bail if there is no further context.
			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
418
			if ($off >= $len) {
419
420
421
				last;
			}
		}
422
		$p = $c;
423
		$c = substr($blk, $off, 1);
424
		$remainder = substr($blk, $off);
425

426
		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
427
428
429
430
431
432
		# Statement ends at the ';' or a close '}' at the
		# outermost level.
		if ($level == 0 && $c eq ';') {
			last;
		}

433
		# An else is really a conditional as long as its not else if
434
435
436
437
438
439
440
441
		if ($level == 0 && $coff_set == 0 &&
				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
				$remainder =~ /^(else)(?:\s|{)/ &&
				$remainder !~ /^else\s+if\b/) {
			$coff = $off + length($1) - 1;
			$coff_set = 1;
			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
442
443
		}

444
445
446
447
448
449
450
451
452
453
		if (($type eq '' || $type eq '(') && $c eq '(') {
			$level++;
			$type = '(';
		}
		if ($type eq '(' && $c eq ')') {
			$level--;
			$type = ($level != 0)? '(' : '';

			if ($level == 0 && $coff < $soff) {
				$coff = $off;
454
455
				$coff_set = 1;
				#warn "CSB: mark coff<$coff>\n";
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
			}
		}
		if (($type eq '' || $type eq '{') && $c eq '{') {
			$level++;
			$type = '{';
		}
		if ($type eq '{' && $c eq '}') {
			$level--;
			$type = ($level != 0)? '{' : '';

			if ($level == 0) {
				last;
			}
		}
		$off++;
	}
472
	# We are truly at the end, so shuffle to the next line.
473
	if ($off == $len) {
474
		$loff = $len + 1;
475
476
477
		$line++;
		$remain--;
	}
478
479
480
481
482
483
484

	my $statement = substr($blk, $soff, $off - $soff + 1);
	my $condition = substr($blk, $soff, $coff - $soff + 1);

	#warn "STATEMENT<$statement>\n";
	#warn "CONDITION<$condition>\n";

485
	#print "coff<$coff> soff<$off> loff<$loff>\n";
486
487
488
489
490

	return ($statement, $condition,
			$line, $remain + 1, $off - $loff + 1, $level);
}

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
sub statement_lines {
	my ($stmt) = @_;

	# Strip the diff line prefixes and rip blank lines at start and end.
	$stmt =~ s/(^|\n)./$1/g;
	$stmt =~ s/^\s*//;
	$stmt =~ s/\s*$//;

	my @stmt_lines = ($stmt =~ /\n/g);

	return $#stmt_lines + 2;
}

sub statement_rawlines {
	my ($stmt) = @_;

	my @stmt_lines = ($stmt =~ /\n/g);

	return $#stmt_lines + 2;
}

sub statement_block_size {
	my ($stmt) = @_;

	$stmt =~ s/(^|\n)./$1/g;
	$stmt =~ s/^\s*{//;
	$stmt =~ s/}\s*$//;
	$stmt =~ s/^\s*//;
	$stmt =~ s/\s*$//;

	my @stmt_lines = ($stmt =~ /\n/g);
	my @stmt_statements = ($stmt =~ /;/g);

	my $stmt_lines = $#stmt_lines + 2;
	my $stmt_statements = $#stmt_statements + 1;

	if ($stmt_lines > $stmt_statements) {
		return $stmt_lines;
	} else {
		return $stmt_statements;
	}
}

534
535
536
537
538
539
sub ctx_statement_full {
	my ($linenr, $remain, $off) = @_;
	my ($statement, $condition, $level);

	my (@chunks);

540
	# Grab the first conditional/block pair.
541
542
	($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
543
	#print "F: c<$condition> s<$statement> remain<$remain>\n";
544
545
546
547
548
549
550
	push(@chunks, [ $condition, $statement ]);
	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
		return ($level, $linenr, @chunks);
	}

	# Pull in the following conditional/block pairs and see if they
	# could continue the statement.
551
552
553
	for (;;) {
		($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
554
		#print "C: c<$condition> s<$statement> remain<$remain>\n";
555
		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
556
557
		#print "C: push\n";
		push(@chunks, [ $condition, $statement ]);
558
559
560
	}

	return ($level, $linenr, @chunks);
561
562
}

563
sub ctx_block_get {
564
	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
565
566
567
568
569
570
571
	my $line;
	my $start = $linenr - 1;
	my $blk = '';
	my @o;
	my @c;
	my @res = ();

572
	my $level = 0;
573
574
575
576
577
	for ($line = $start; $remain > 0; $line++) {
		next if ($rawlines[$line] =~ /^-/);
		$remain--;

		$blk .= $rawlines[$line];
578
579
580
581
582
583
		foreach my $c (split(//, $rawlines[$line])) {
			##print "C<$c>L<$level><$open$close>O<$off>\n";
			if ($off > 0) {
				$off--;
				next;
			}
584

585
586
587
588
589
590
591
			if ($c eq $close && $level > 0) {
				$level--;
				last if ($level == 0);
			} elsif ($c eq $open) {
				$level++;
			}
		}
592

593
		if (!$outer || $level <= 1) {
594
			push(@res, $rawlines[$line]);
595
596
		}

597
		last if ($level == 0);
598
599
	}

600
	return ($level, @res);
601
602
603
604
}
sub ctx_block_outer {
	my ($linenr, $remain) = @_;

605
606
	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
	return @r;
607
608
609
610
}
sub ctx_block {
	my ($linenr, $remain) = @_;

611
612
	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
	return @r;
613
614
}
sub ctx_statement {
615
616
617
618
619
620
	my ($linenr, $remain, $off) = @_;

	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
	return @r;
}
sub ctx_block_level {
621
622
	my ($linenr, $remain) = @_;

623
	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
624
}
625
626
627
628
629
sub ctx_statement_level {
	my ($linenr, $remain, $off) = @_;

	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
}
630
631
632
633
634

sub ctx_locate_comment {
	my ($first_line, $end_line) = @_;

	# Catch a comment on the end of the line itself.
635
	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
636
637
638
639
640
641
642
	return $current_comment if (defined $current_comment);

	# Look through the context and try and figure out if there is a
	# comment.
	my $in_comment = 0;
	$current_comment = '';
	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
643
644
		my $line = $rawlines[$linenr - 1];
		#warn "           $line\n";
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
			$in_comment = 1;
		}
		if ($line =~ m@/\*@) {
			$in_comment = 1;
		}
		if (!$in_comment && $current_comment ne '') {
			$current_comment = '';
		}
		$current_comment .= $line . "\n" if ($in_comment);
		if ($line =~ m@\*/@) {
			$in_comment = 0;
		}
	}

	chomp($current_comment);
	return($current_comment);
}
sub ctx_has_comment {
	my ($first_line, $end_line) = @_;
	my $cmt = ctx_locate_comment($first_line, $end_line);

667
	##print "LINE: $rawlines[$end_line - 1 ]\n";
668
669
670
671
672
	##print "CMMT: $cmt\n";

	return ($cmt ne '');
}

673
674
675
sub cat_vet {
	my ($vet) = @_;
	my ($res, $coded);
676

677
678
679
680
681
682
	$res = '';
	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
		$res .= $1;
		if ($2 ne '') {
			$coded = sprintf("^%c", unpack('C', $2) + 64);
			$res .= $coded;
683
684
		}
	}
685
	$res =~ s/$/\$/;
686

687
	return $res;
688
689
}

690
my $av_preprocessor = 0;
691
my $av_pending;
692
693
694
695
my @av_paren_type;

sub annotate_reset {
	$av_preprocessor = 0;
696
697
	$av_pending = '_';
	@av_paren_type = ('E');
698
699
}

700
701
sub annotate_values {
	my ($stream, $type) = @_;
702

703
704
705
	my $res;
	my $cur = $stream;

706
	print "$stream\n" if ($dbg_values > 1);
707
708

	while (length($cur)) {
709
		@av_paren_type = ('E') if ($#av_paren_type < 0);
710
		print " <" . join('', @av_paren_type) .
711
				"> <$type> <$av_pending>" if ($dbg_values > 1);
712
		if ($cur =~ /^(\s+)/o) {
713
714
			print "WS($1)\n" if ($dbg_values > 1);
			if ($1 =~ /\n/ && $av_preprocessor) {
715
				$type = pop(@av_paren_type);
716
				$av_preprocessor = 0;
717
718
			}

719
		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\))/) {
720
			print "DECLARE($1)\n" if ($dbg_values > 1);
721
722
			$type = 'T';

723
724
725
726
		} elsif ($cur =~ /^($Modifier)\s*/) {
			print "MODIFIER($1)\n" if ($dbg_values > 1);
			$type = 'T';

727
		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
728
			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
729
			$av_preprocessor = 1;
730
731
732
733
734
735
			push(@av_paren_type, $type);
			if ($2 ne '') {
				$av_pending = 'N';
			}
			$type = 'E';

736
		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
737
738
739
			print "UNDEF($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;
			push(@av_paren_type, $type);
740

741
		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
742
			print "PRE_START($1)\n" if ($dbg_values > 1);
743
			$av_preprocessor = 1;
744
745
746

			push(@av_paren_type, $type);
			push(@av_paren_type, $type);
747
			$type = 'E';
748

749
		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
750
751
752
753
754
			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;

			push(@av_paren_type, $av_paren_type[$#av_paren_type]);

755
			$type = 'E';
756

757
		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
758
759
760
761
762
763
764
765
			print "PRE_END($1)\n" if ($dbg_values > 1);

			$av_preprocessor = 1;

			# Assume all arms of the conditional end as this
			# one does, and continue as if the #endif was not here.
			pop(@av_paren_type);
			push(@av_paren_type, $type);
766
			$type = 'E';
767
768

		} elsif ($cur =~ /^(\\\n)/o) {
769
			print "PRECONT($1)\n" if ($dbg_values > 1);
770

771
772
773
774
775
		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
			print "ATTR($1)\n" if ($dbg_values > 1);
			$av_pending = $type;
			$type = 'N';

776
		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
777
			print "SIZEOF($1)\n" if ($dbg_values > 1);
778
			if (defined $2) {
779
				$av_pending = 'V';
780
781
782
			}
			$type = 'N';

783
		} elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
784
			print "COND($1)\n" if ($dbg_values > 1);
785
			$av_pending = 'N';
786
787
			$type = 'N';

788
		} elsif ($cur =~/^(return|case|else|goto)/o) {
789
			print "KEYWORD($1)\n" if ($dbg_values > 1);
790
791
792
			$type = 'N';

		} elsif ($cur =~ /^(\()/o) {
793
			print "PAREN('$1')\n" if ($dbg_values > 1);
794
795
			push(@av_paren_type, $av_pending);
			$av_pending = '_';
796
797
798
			$type = 'N';

		} elsif ($cur =~ /^(\))/o) {
799
800
801
			my $new_type = pop(@av_paren_type);
			if ($new_type ne '_') {
				$type = $new_type;
802
803
				print "PAREN('$1') -> $type\n"
							if ($dbg_values > 1);
804
			} else {
805
				print "PAREN('$1')\n" if ($dbg_values > 1);
806
807
			}

808
		} elsif ($cur =~ /^($Ident)\s*\(/o) {
809
			print "FUNC($1)\n" if ($dbg_values > 1);
810
			$type = 'V';
811
			$av_pending = 'V';
812
813

		} elsif ($cur =~ /^($Ident|$Constant)/o) {
814
			print "IDENT($1)\n" if ($dbg_values > 1);
815
816
817
			$type = 'V';

		} elsif ($cur =~ /^($Assignment)/o) {
818
			print "ASSIGN($1)\n" if ($dbg_values > 1);
819
820
			$type = 'N';

821
		} elsif ($cur =~/^(;|{|})/) {
822
			print "END($1)\n" if ($dbg_values > 1);
823
824
			$type = 'E';

825
		} elsif ($cur =~ /^(;|\?|:|\[)/o) {
826
			print "CLOSE($1)\n" if ($dbg_values > 1);
827
828
829
			$type = 'N';

		} elsif ($cur =~ /^($Operators)/o) {
830
			print "OP($1)\n" if ($dbg_values > 1);
831
832
833
834
835
			if ($1 ne '++' && $1 ne '--') {
				$type = 'N';
			}

		} elsif ($cur =~ /(^.)/o) {
836
			print "C($1)\n" if ($dbg_values > 1);
837
838
839
840
841
		}
		if (defined $1) {
			$cur = substr($cur, length($1));
			$res .= $type x length($1);
		}
842
	}
843

844
	return $res;
845
846
}

847
sub possible {
848
	my ($possible, $line) = @_;
849

850
	print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1);
851
852
853
	if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
	    $possible ne 'goto' && $possible ne 'return' &&
	    $possible ne 'case' && $possible ne 'else' &&
854
	    $possible ne 'asm' && $possible ne '__asm__' &&
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
	    $possible !~ /^(typedef|struct|enum)\b/) {
		# Check for modifiers.
		$possible =~ s/\s*$Storage\s*//g;
		$possible =~ s/\s*$Sparse\s*//g;
		if ($possible =~ /^\s*$/) {

		} elsif ($possible =~ /\s/) {
			$possible =~ s/\s*$Type\s*//g;
			warn "MODIFIER: $possible ($line)\n" if ($dbg_possible);
			push(@modifierList, $possible);

		} else {
			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
			push(@typeList, $possible);
		}
870
871
872
873
		build_types();
	}
}

874
875
my $prefix = '';

876
sub report {
877
878
879
	if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
		return 0;
	}
880
881
882
883
	my $line = $prefix . $_[0];

	$line = (split('\n', $line))[0] . "\n" if ($terse);

884
	push(our @report, $line);
885
886

	return 1;
887
888
}
sub report_dump {
889
	our @report;
890
}
891
sub ERROR {
892
893
894
895
	if (report("ERROR: $_[0]\n")) {
		our $clean = 0;
		our $cnt_error++;
	}
896
897
}
sub WARN {
898
899
900
901
	if (report("WARNING: $_[0]\n")) {
		our $clean = 0;
		our $cnt_warn++;
	}
902
903
}
sub CHK {
904
	if ($check && report("CHECK: $_[0]\n")) {
905
906
907
		our $clean = 0;
		our $cnt_chk++;
	}
908
909
}

910
911
912
913
914
sub process {
	my $filename = shift;

	my $linenr=0;
	my $prevline="";
915
	my $prevrawline="";
916
	my $stashline="";
917
	my $stashrawline="";
918

919
	my $length;
920
921
922
923
	my $indent;
	my $previndent=0;
	my $stashindent=0;

924
	our $clean = 1;
925
926
927
	my $signoff = 0;
	my $is_patch = 0;

928
	our @report = ();
929
930
931
932
933
	our $cnt_lines = 0;
	our $cnt_error = 0;
	our $cnt_warn = 0;
	our $cnt_chk = 0;

934
935
936
937
938
939
	# Trace the real file/line as we go.
	my $realfile = '';
	my $realline = 0;
	my $realcnt = 0;
	my $here = '';
	my $in_comment = 0;
940
	my $comment_edge = 0;
941
942
	my $first_line = 0;

943
944
945
	my $prev_values = 'E';

	# suppression flags
946
	my %suppress_ifbraces;
947

948
	# Pre-scan the patch sanitizing the lines.
949
	# Pre-scan the patch looking for any __setup documentation.
950
	#
951
952
	my @setup_docs = ();
	my $setup_docs = 0;
953
954

	sanitise_line_reset();
955
956
	my $line;
	foreach my $rawline (@rawlines) {
957
958
		$linenr++;
		$line = $rawline;
959

960
		if ($rawline=~/^\+\+\+\s+(\S+)/) {
961
962
963
964
			$setup_docs = 0;
			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
				$setup_docs = 1;
			}
965
966
967
968
969
970
971
972
973
			#next;
		}
		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
			$realline=$1-1;
			if (defined $2) {
				$realcnt=$3+1;
			} else {
				$realcnt=1+1;
			}
974
			$in_comment = 0;
975
976
977
978
979
980

			# Guestimate if this is a continuing comment.  Run
			# the context looking for a comment "edge".  If this
			# edge is a close comment then we must be in a comment
			# at context start.
			my $edge;
981
			for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) {
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
				next if ($line =~ /^-/);
				($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
				last if (defined $edge);
			}
			if (defined $edge && $edge eq '*/') {
				$in_comment = 1;
			}

			# Guestimate if this is a continuing comment.  If this
			# is the start of a diff block and this line starts
			# ' *' then it is very likely a comment.
			if (!defined $edge &&
			    $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@)
			{
				$in_comment = 1;
			}

			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
			sanitise_line_reset($in_comment);

1002
		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1003
			# Standardise the strings and chars within the input to
1004
			# simplify matching -- only bother with positive lines.
1005
			$line = sanitise_line($rawline);
1006
		}
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
		push(@lines, $line);

		if ($realcnt > 1) {
			$realcnt-- if ($line =~ /^(?:\+| |$)/);
		} else {
			$realcnt = 0;
		}

		#print "==>$rawline\n";
		#print "-->$line\n";
1017
1018
1019
1020
1021
1022

		if ($setup_docs && $line =~ /^\+/) {
			push(@setup_docs, $line);
		}
	}

1023
1024
	$prefix = '';

1025
1026
	$realcnt = 0;
	$linenr = 0;
1027
1028
1029
	foreach my $line (@lines) {
		$linenr++;

1030
		my $rawline = $rawlines[$linenr - 1];
1031

1032
#extract the line range in the file after the patch is applied
1033
		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1034
			$is_patch = 1;
1035
			$first_line = $linenr + 1;
1036
1037
1038
1039
1040
1041
			$realline=$1-1;
			if (defined $2) {
				$realcnt=$3+1;
			} else {
				$realcnt=1+1;
			}
1042
			annotate_reset();
1043
1044
			$prev_values = 'E';

1045
			%suppress_ifbraces = ();
1046
1047
			next;

1048
1049
1050
# track the line number as we move through the hunk, note that
# new versions of GNU diff omit the leading space on completely
# blank context lines so we need to count that too.
1051
		} elsif ($line =~ /^( |\+|$)/) {
1052
			$realline++;
1053
			$realcnt-- if ($realcnt != 0);
1054

1055
			# Measure the line length and indent.
1056
			($length, $indent) = line_stats($rawline);
1057
1058
1059
1060

			# Track the previous line.
			($prevline, $stashline) = ($stashline, $line);
			($previndent, $stashindent) = ($stashindent, $indent);
1061
1062
			($prevrawline, $stashrawline) = ($stashrawline, $rawline);

1063
			#warn "line<$line>\n";
1064

1065
1066
		} elsif ($realcnt == 1) {
			$realcnt--;
1067
1068
1069
		}

#make up the handle for any error we report on this line
1070
1071
1072
		$prefix = "$filename:$realline: " if ($emacs && $file);
		$prefix = "$filename:$linenr: " if ($emacs && !$file);

1073
1074
		$here = "#$linenr: " if (!$file);
		$here = "#$realline: " if ($file);
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

		# extract the filename as it passes
		if ($line=~/^\+\+\+\s+(\S+)/) {
			$realfile = $1;
			$realfile =~ s@^[^/]*/@@;

			if ($realfile =~ m@include/asm/@) {
				ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
			}
			next;
		}

1087
		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
1088

1089
1090
1091
		my $hereline = "$here\n$rawline\n";
		my $herecurr = "$here\n$rawline\n";
		my $hereprev = "$here\n$prevrawline\n$rawline\n";
1092

1093
1094
		$cnt_lines++ if ($realcnt != 0);

1095
#check the patch for a signoff:
1096
		if ($line =~ /^\s*signed-off-by:/i) {
1097
1098
			# This is a signoff, if ugly, so do not double report.
			$signoff++;
1099
			if (!($line =~ /^\s*Signed-off-by:/)) {
1100
1101
				WARN("Signed-off-by: is the preferred form\n" .
					$herecurr);
1102
1103
			}
			if ($line =~ /^\s*signed-off-by:\S/i) {
1104
				WARN("space required after Signed-off-by:\n" .
1105
					$herecurr);
1106
1107
1108
			}
		}

1109
# Check for wrappage within a valid hunk of the file
1110
		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1111
			ERROR("patch seems to be corrupt (line wrapped?)\n" .
1112
				$herecurr) if (!$emitted_corrupt++);
1113
1114
1115
1116
		}

# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1117
1118
1119
1120
1121
1122
1123
1124
		    $rawline !~ m/^$UTF8*$/) {
			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);

			my $blank = copy_spacing($rawline);
			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
			my $hereptr = "$hereline$ptr\n";

			ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
1125
1126
1127
1128
		}

#ignore lines being removed
		if ($line=~/^-/) {next;}
1129

1130
1131
# check we are in a valid source file if not then ignore this hunk
		next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1132
1133

#trailing whitespace
1134
		if ($line =~ /^\+.*\015/) {
1135
			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1136
1137
			ERROR("DOS line endings\n" . $herevet);

1138
1139
		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1140
			ERROR("trailing whitespace\n" . $herevet);
1141
1142
		}
#80 column limit
1143
		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1144
1145
1146
		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
		    $line !~ /^\+\s*printk\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
		    $length > 80)
1147
		{
1148
			WARN("line over 80 characters\n" . $herecurr);
1149
1150
		}