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

use strict;

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

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

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

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

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

my $exit = 0;

if ($#ARGV < 0) {
53
	print "usage: $P [options] patchfile\n";
54
	print "version: $V\n";
55
56
57
58
59
60
61
62
63
	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";
64
65
66
	exit(1);
}

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

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

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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);
	}
98
99
}

100
101
102
103
104
105
106
107
108
109
110
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|
111
			__kprobes
112
113
114
115
116
		}x;
our $Attribute	= qr{
			const|
			__read_mostly|
			__kprobes|
117
118
119
			__(?:mem|cpu|dev|)(?:initdata|init)|
			____cacheline_aligned|
			____cacheline_aligned_in_smp|
120
121
			____cacheline_internodealigned_in_smp|
			__weak
122
		  }x;
123
our $Modifier;
124
125
126
127
128
129
130
131
132
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{
			<=|>=|==|!=|
			=>|->|<<|>>|<|>|!|~|
133
			&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
134
135
		  }x;

136
137
138
139
our $NonptrType;
our $Type;
our $Declare;

140
141
142
143
144
145
146
147
148
149
150
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;

151
152
153
154
155
our $typeTypedefs = qr{(?x:
	(?:__)?(?:u|s|be|le)(?:\d|\d\d)|
	atomic_t
)};

156
157
our @typeList = (
	qr{void},
158
159
160
161
162
163
164
	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},
165
166
167
168
169
170
171
172
173
174
175
	qr{unsigned},
	qr{float},
	qr{double},
	qr{bool},
	qr{struct\s+$Ident},
	qr{union\s+$Ident},
	qr{enum\s+$Ident},
	qr{${Ident}_t},
	qr{${Ident}_handler},
	qr{${Ident}_handler_fn},
);
176
177
178
our @modifierList = (
	qr{fastcall},
);
179
180

sub build_types {
181
182
	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
183
	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
184
	$NonptrType	= qr{
185
			(?:$Modifier\s+|const\s+)*
186
			(?:
187
				(?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
188
				(?:$typeTypedefs\b)|
189
				(?:${all}\b)
190
			)
191
			(?:\s+$Modifier|\s+const)*
192
193
		  }x;
	$Type	= qr{
194
			$NonptrType
195
			(?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
196
			(?:\s+$Inline|\s+$Modifier)*
197
198
199
200
		  }x;
	$Declare	= qr{(?:$Storage\s+)?$Type};
}
build_types();
201
202
203

$chk_signoff = 0 if ($file);

204
205
my @dep_includes = ();
my @dep_functions = ();
206
207
208
209
my $removal = "Documentation/feature-removal-schedule.txt";
if ($tree && -f "$root/$removal") {
	open(REMOVE, "<$root/$removal") ||
				die "$P: $removal: open failed - $!\n";
210
	while (<REMOVE>) {
211
212
213
		if (/^Check:\s+(.*\S)/) {
			for my $entry (split(/[, ]+/, $1)) {
				if ($entry =~ m@include/(.*)@) {
214
215
					push(@dep_includes, $1);

216
217
218
				} elsif ($entry !~ m@/@) {
					push(@dep_functions, $entry);
				}
219
			}
220
221
222
223
		}
	}
}

224
my @rawlines = ();
225
226
my @lines = ();
my $vname;
227
228
229
230
231
232
233
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";
234
	}
235
236
237
238
239
	if ($filename eq '-') {
		$vname = 'Your patch';
	} else {
		$vname = $filename;
	}
240
241
242
243
244
	while (<FILE>) {
		chomp;
		push(@rawlines, $_);
	}
	close(FILE);
245
	if (!process($filename)) {
246
247
248
		$exit = 1;
	}
	@rawlines = ();
249
	@lines = ();
250
251
252
253
254
}

exit($exit);

sub top_of_kernel_tree {
255
256
257
258
259
260
261
262
263
264
265
266
	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;
		}
267
	}
268
	return 1;
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
}

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;
}
291
sub copy_spacing {
292
	(my $res = shift) =~ tr/\t/ /c;
293
294
	return $res;
}
295

296
297
298
299
300
301
302
303
304
305
306
307
308
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));
}

309
310
311
312
313
314
315
316
317
318
319
my $sanitise_quote = '';

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

	if ($in_comment) {
		$sanitise_quote = '*/';
	} else {
		$sanitise_quote = '';
	}
}
320
321
322
323
324
325
sub sanitise_line {
	my ($line) = @_;

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

326
	my $qlen = 0;
327
328
	my $off = 0;
	my $c;
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
	# 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;
344
		}
345
		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
346
347
348
349
			$sanitise_quote = '';
			substr($res, $off, 2, "$;$;");
			$off++;
			next;
350
		}
351
352
353
354
355
356
357

		# 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;
358
		}
359
360
361
362
		# Regular quotes.
		if ($c eq "'" || $c eq '"') {
			if ($sanitise_quote eq '') {
				$sanitise_quote = $c;
363

364
365
366
367
368
369
				substr($res, $off, 1, $c);
				next;
			} elsif ($sanitise_quote eq $c) {
				$sanitise_quote = '';
			}
		}
370

371
		#print "c<$c> SQ<$sanitise_quote>\n";
372
373
374
375
376
377
378
		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);
		}
379
380
381
	}

	# The pathname on a #include may be surrounded by '<' and '>'.
382
	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
383
384
385
386
		my $clean = 'X' x length($1);
		$res =~ s@\<.*\>@<$clean>@;

	# The whole of a #error is a string.
387
	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
388
		my $clean = 'X' x length($1);
389
		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
390
391
	}

392
393
394
	return $res;
}

395
396
397
398
399
400
sub ctx_statement_block {
	my ($linenr, $remain, $off) = @_;
	my $line = $linenr - 1;
	my $blk = '';
	my $soff = $off;
	my $coff = $off - 1;
401
	my $coff_set = 0;
402

403
404
	my $loff = 0;

405
406
	my $type = '';
	my $level = 0;
407
	my $p;
408
409
	my $c;
	my $len = 0;
410
411

	my $remainder;
412
	while (1) {
413
		#warn "CSB: blk<$blk> remain<$remain>\n";
414
415
416
417
		# If we are about to drop off the end, pull in more
		# context.
		if ($off >= $len) {
			for (; $remain > 0; $line++) {
418
				last if (!defined $lines[$line]);
419
				next if ($lines[$line] =~ /^-/);
420
				$remain--;
421
				$loff = $len;
422
				$blk .= $lines[$line] . "\n";
423
424
425
426
427
428
				$len = length($blk);
				$line++;
				last;
			}
			# Bail if there is no further context.
			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
429
			if ($off >= $len) {
430
431
432
				last;
			}
		}
433
		$p = $c;
434
		$c = substr($blk, $off, 1);
435
		$remainder = substr($blk, $off);
436

437
		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
438
439
440
441
442
443
		# Statement ends at the ';' or a close '}' at the
		# outermost level.
		if ($level == 0 && $c eq ';') {
			last;
		}

444
		# An else is really a conditional as long as its not else if
445
446
447
448
449
450
451
452
		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";
453
454
		}

455
456
457
458
459
460
461
462
463
464
		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;
465
466
				$coff_set = 1;
				#warn "CSB: mark coff<$coff>\n";
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
			}
		}
		if (($type eq '' || $type eq '{') && $c eq '{') {
			$level++;
			$type = '{';
		}
		if ($type eq '{' && $c eq '}') {
			$level--;
			$type = ($level != 0)? '{' : '';

			if ($level == 0) {
				last;
			}
		}
		$off++;
	}
483
	# We are truly at the end, so shuffle to the next line.
484
	if ($off == $len) {
485
		$loff = $len + 1;
486
487
488
		$line++;
		$remain--;
	}
489
490
491
492
493
494
495

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

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

496
	#print "coff<$coff> soff<$off> loff<$loff>\n";
497
498
499
500
501

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

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
534
535
536
537
538
539
540
541
542
543
544
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;
	}
}

545
546
547
548
549
550
sub ctx_statement_full {
	my ($linenr, $remain, $off) = @_;
	my ($statement, $condition, $level);

	my (@chunks);

551
	# Grab the first conditional/block pair.
552
553
	($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
554
	#print "F: c<$condition> s<$statement> remain<$remain>\n";
555
556
557
558
559
560
561
	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.
562
563
564
	for (;;) {
		($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
565
		#print "C: c<$condition> s<$statement> remain<$remain>\n";
566
		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
567
568
		#print "C: push\n";
		push(@chunks, [ $condition, $statement ]);
569
570
571
	}

	return ($level, $linenr, @chunks);
572
573
}

574
sub ctx_block_get {
575
	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
576
577
578
579
580
581
582
	my $line;
	my $start = $linenr - 1;
	my $blk = '';
	my @o;
	my @c;
	my @res = ();

583
	my $level = 0;
584
585
586
587
588
	for ($line = $start; $remain > 0; $line++) {
		next if ($rawlines[$line] =~ /^-/);
		$remain--;

		$blk .= $rawlines[$line];
589
590
591
592
593
594
		foreach my $c (split(//, $rawlines[$line])) {
			##print "C<$c>L<$level><$open$close>O<$off>\n";
			if ($off > 0) {
				$off--;
				next;
			}
595

596
597
598
599
600
601
602
			if ($c eq $close && $level > 0) {
				$level--;
				last if ($level == 0);
			} elsif ($c eq $open) {
				$level++;
			}
		}
603

604
		if (!$outer || $level <= 1) {
605
			push(@res, $rawlines[$line]);
606
607
		}

608
		last if ($level == 0);
609
610
	}

611
	return ($level, @res);
612
613
614
615
}
sub ctx_block_outer {
	my ($linenr, $remain) = @_;

616
617
	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
	return @r;
618
619
620
621
}
sub ctx_block {
	my ($linenr, $remain) = @_;

622
623
	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
	return @r;
624
625
}
sub ctx_statement {
626
627
628
629
630
631
	my ($linenr, $remain, $off) = @_;

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

634
	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
635
}
636
637
638
639
640
sub ctx_statement_level {
	my ($linenr, $remain, $off) = @_;

	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
}
641
642
643
644
645

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

	# Catch a comment on the end of the line itself.
646
	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
647
648
649
650
651
652
653
	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++) {
654
655
		my $line = $rawlines[$linenr - 1];
		#warn "           $line\n";
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
		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);

678
	##print "LINE: $rawlines[$end_line - 1 ]\n";
679
680
681
682
683
	##print "CMMT: $cmt\n";

	return ($cmt ne '');
}

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
sub raw_line {
	my ($linenr, $cnt) = @_;

	my $offset = $linenr - 1;
	$cnt++;

	my $line;
	while ($cnt) {
		$line = $rawlines[$offset++];
		next if (defined($line) && $line =~ /^-/);
		$cnt--;
	}

	return $line;
}

700
701
702
sub cat_vet {
	my ($vet) = @_;
	my ($res, $coded);
703

704
705
706
707
708
709
	$res = '';
	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
		$res .= $1;
		if ($2 ne '') {
			$coded = sprintf("^%c", unpack('C', $2) + 64);
			$res .= $coded;
710
711
		}
	}
712
	$res =~ s/$/\$/;
713

714
	return $res;
715
716
}

717
my $av_preprocessor = 0;
718
my $av_pending;
719
my @av_paren_type;
720
my $av_pend_colon;
721
722
723

sub annotate_reset {
	$av_preprocessor = 0;
724
725
	$av_pending = '_';
	@av_paren_type = ('E');
726
	$av_pend_colon = 'O';
727
728
}

729
730
sub annotate_values {
	my ($stream, $type) = @_;
731

732
	my $res;
733
	my $var = '_' x length($stream);
734
735
	my $cur = $stream;

736
	print "$stream\n" if ($dbg_values > 1);
737
738

	while (length($cur)) {
739
		@av_paren_type = ('E') if ($#av_paren_type < 0);
740
		print " <" . join('', @av_paren_type) .
741
				"> <$type> <$av_pending>" if ($dbg_values > 1);
742
		if ($cur =~ /^(\s+)/o) {
743
744
			print "WS($1)\n" if ($dbg_values > 1);
			if ($1 =~ /\n/ && $av_preprocessor) {
745
				$type = pop(@av_paren_type);
746
				$av_preprocessor = 0;
747
748
			}

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

753
754
755
756
		} elsif ($cur =~ /^($Modifier)\s*/) {
			print "MODIFIER($1)\n" if ($dbg_values > 1);
			$type = 'T';

757
		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
758
			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
759
			$av_preprocessor = 1;
760
761
762
763
764
765
			push(@av_paren_type, $type);
			if ($2 ne '') {
				$av_pending = 'N';
			}
			$type = 'E';

766
		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
767
768
769
			print "UNDEF($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;
			push(@av_paren_type, $type);
770

771
		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
772
			print "PRE_START($1)\n" if ($dbg_values > 1);
773
			$av_preprocessor = 1;
774
775
776

			push(@av_paren_type, $type);
			push(@av_paren_type, $type);
777
			$type = 'E';
778

779
		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
780
781
782
783
784
			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;

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

785
			$type = 'E';
786

787
		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
788
789
790
791
792
793
794
795
			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);
796
			$type = 'E';
797
798

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

801
802
803
804
805
		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
			print "ATTR($1)\n" if ($dbg_values > 1);
			$av_pending = $type;
			$type = 'N';

806
		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
807
			print "SIZEOF($1)\n" if ($dbg_values > 1);
808
			if (defined $2) {
809
				$av_pending = 'V';
810
811
812
			}
			$type = 'N';

813
		} elsif ($cur =~ /^(if|while|for)\b/o) {
814
			print "COND($1)\n" if ($dbg_values > 1);
815
			$av_pending = 'E';
816
817
			$type = 'N';

818
819
820
821
822
		} elsif ($cur =~/^(case)/o) {
			print "CASE($1)\n" if ($dbg_values > 1);
			$av_pend_colon = 'C';
			$type = 'N';

823
		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
824
			print "KEYWORD($1)\n" if ($dbg_values > 1);
825
826
827
			$type = 'N';

		} elsif ($cur =~ /^(\()/o) {
828
			print "PAREN('$1')\n" if ($dbg_values > 1);
829
830
			push(@av_paren_type, $av_pending);
			$av_pending = '_';
831
832
833
			$type = 'N';

		} elsif ($cur =~ /^(\))/o) {
834
835
836
			my $new_type = pop(@av_paren_type);
			if ($new_type ne '_') {
				$type = $new_type;
837
838
				print "PAREN('$1') -> $type\n"
							if ($dbg_values > 1);
839
			} else {
840
				print "PAREN('$1')\n" if ($dbg_values > 1);
841
842
			}

843
		} elsif ($cur =~ /^($Ident)\s*\(/o) {
844
			print "FUNC($1)\n" if ($dbg_values > 1);
845
			$type = 'V';
846
			$av_pending = 'V';
847

848
849
		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
			if (defined $2 && $type eq 'C' || $type eq 'T') {
850
				$av_pend_colon = 'B';
851
852
			} elsif ($type eq 'E') {
				$av_pend_colon = 'L';
853
854
855
856
			}
			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
			$type = 'V';

857
		} elsif ($cur =~ /^($Ident|$Constant)/o) {
858
			print "IDENT($1)\n" if ($dbg_values > 1);
859
860
861
			$type = 'V';

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

865
		} elsif ($cur =~/^(;|{|})/) {
866
			print "END($1)\n" if ($dbg_values > 1);
867
			$type = 'E';
868
869
			$av_pend_colon = 'O';

870
871
872
873
		} elsif ($cur =~/^(,)/) {
			print "COMMA($1)\n" if ($dbg_values > 1);
			$type = 'C';

874
875
876
877
878
879
880
881
882
883
884
885
886
887
		} elsif ($cur =~ /^(\?)/o) {
			print "QUESTION($1)\n" if ($dbg_values > 1);
			$type = 'N';

		} elsif ($cur =~ /^(:)/o) {
			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);

			substr($var, length($res), 1, $av_pend_colon);
			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
				$type = 'E';
			} else {
				$type = 'N';
			}
			$av_pend_colon = 'O';
888

889
		} elsif ($cur =~ /^(\[)/o) {
890
			print "CLOSE($1)\n" if ($dbg_values > 1);
891
892
			$type = 'N';

893
		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
894
895
896
897
898
899
900
901
902
903
904
905
			my $variant;

			print "OPV($1)\n" if ($dbg_values > 1);
			if ($type eq 'V') {
				$variant = 'B';
			} else {
				$variant = 'U';
			}

			substr($var, length($res), 1, $variant);
			$type = 'N';

906
		} elsif ($cur =~ /^($Operators)/o) {
907
			print "OP($1)\n" if ($dbg_values > 1);
908
909
910
911
912
			if ($1 ne '++' && $1 ne '--') {
				$type = 'N';
			}

		} elsif ($cur =~ /(^.)/o) {
913
			print "C($1)\n" if ($dbg_values > 1);
914
915
916
917
918
		}
		if (defined $1) {
			$cur = substr($cur, length($1));
			$res .= $type x length($1);
		}
919
	}
920

921
	return ($res, $var);
922
923
}

924
sub possible {
925
	my ($possible, $line) = @_;
926

927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
	print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
	if ($possible !~ /(?:
		^(?:
			$Modifier|
			$Storage|
			$Type|
			DEFINE_\S+|
			goto|
			return|
			case|
			else|
			asm|__asm__|
			do
		)$|
		^(?:typedef|struct|enum)\b
	    )/x) {
943
944
945
946
947
948
949
		# 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;
950
951
952
953
			for my $modifier (split(' ', $possible)) {
				warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
				push(@modifierList, $modifier);
			}
954
955
956
957
958

		} else {
			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
			push(@typeList, $possible);
		}
959
		build_types();
960
961
	} else {
		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
962
963
964
	}
}

965
966
my $prefix = '';

967
sub report {
968
969
970
	if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
		return 0;
	}
971
972
973
974
	my $line = $prefix . $_[0];

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

975
	push(our @report, $line);
976
977

	return 1;
978
979
}
sub report_dump {
980
	our @report;
981
}
982
sub ERROR {
983
984
985
986
	if (report("ERROR: $_[0]\n")) {
		our $clean = 0;
		our $cnt_error++;
	}
987
988
}
sub WARN {
989
990
991
992
	if (report("WARNING: $_[0]\n")) {
		our $clean = 0;
		our $cnt_warn++;
	}
993
994
}
sub CHK {
995
	if ($check && report("CHECK: $_[0]\n")) {
996
997
998
		our $clean = 0;
		our $cnt_chk++;
	}
999
1000
}

1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
sub check_absolute_file {
	my ($absolute, $herecurr) = @_;
	my $file = $absolute;

	##print "absolute<$absolute>\n";

	# See if any suffix of this path is a path within the tree.
	while ($file =~ s@^[^/]*/@@) {
		if (-f "$root/$file") {
			##print "file<$file>\n";
			last;
		}
	}
	if (! -f _)  {
		return 0;
	}

	# It is, so see if the prefix is acceptable.
	my $prefix = $absolute;
	substr($prefix, -length($file)) = '';

	##print "prefix<$prefix>\n";
	if ($prefix ne ".../") {
		WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
	}
}

1028
1029
1030
1031
1032
sub process {
	my $filename = shift;

	my $linenr=0;
	my $prevline="";
1033
	my $prevrawline="";
1034
	my $stashline="";
1035
	my $stashrawline="";
1036

1037
	my $length;
1038
1039
1040
1041
	my $indent;
	my $previndent=0;
	my $stashindent=0;

1042
	our $clean = 1;
1043
1044
1045
	my $signoff = 0;
	my $is_patch = 0;

1046
	our @report = ();
1047
1048
1049
1050
1051
	our $cnt_lines = 0;
	our $cnt_error = 0;
	our $cnt_warn = 0;
	our $cnt_chk = 0;

1052
1053
1054
1055
1056
1057
	# Trace the real file/line as we go.
	my $realfile = '';
	my $realline = 0;
	my $realcnt = 0;
	my $here = '';
	my $in_comment = 0;
1058
	my $comment_edge = 0;
1059
	my $first_line = 0;
1060
	my $p1_prefix = '';
1061

1062
1063
1064
	my $prev_values = 'E';

	# suppression flags
1065
	my %suppress_ifbraces;
1066
	my %suppress_whiletrailers;
1067

1068
	# Pre-scan the patch sanitizing the lines.
1069
	# Pre-scan the patch looking for any __setup documentation.
1070
	#
1071
1072
	my @setup_docs = ();
	my $setup_docs = 0;
1073
1074

	sanitise_line_reset();
1075
1076
	my $line;
	foreach my $rawline (@rawlines) {
1077
1078
		$linenr++;
		$line = $rawline;
1079

1080
		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1081
1082
1083
1084
			$setup_docs = 0;
			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
				$setup_docs = 1;
			}
1085
1086
1087
1088
1089
1090
1091
1092
1093
			#next;
		}
		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
			$realline=$1-1;
			if (defined $2) {
				$realcnt=$3+1;
			} else {
				$realcnt=1+1;
			}
1094
			$in_comment = 0;
1095
1096
1097
1098
1099
1100

			# 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;
1101
1102
1103
1104
1105
1106
			my $cnt = $realcnt;
			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
				next if (defined $rawlines[$ln - 1] &&
					 $rawlines[$ln - 1] =~ /^-/);
				$cnt--;
				#print "RAW<$rawlines[$ln - 1]>\n";
1107
				last if (!defined $rawlines[$ln - 1]);
1108
1109
1110
1111
1112
				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
					($edge) = $1;
					last;
				}
1113
1114
1115
1116
1117
1118
1119
1120
1121
			}
			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 &&
1122
			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1123
1124
1125
1126
1127
1128
1129
			{
				$in_comment = 1;
			}

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

1130
		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1131
			# Standardise the strings and chars within the input to
1132
			# simplify matching -- only bother with positive lines.
1133
			$line = sanitise_line($rawline);
1134
		}
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
		push(@lines, $line);

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

		#print "==>$rawline\n";
		#print "-->$line\n";
1145
1146
1147
1148
1149
1150

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

1151
1152
	$prefix = '';

1153
1154
	$realcnt = 0;
	$linenr = 0;
1155
1156
1157
	foreach my $line (@lines) {
		$linenr++;

1158
		my $rawline = $rawlines[$linenr - 1];
1159
		my $hunk_line = ($realcnt != 0);
1160

1161
#extract the line range in the file after the patch is applied
1162
		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1163
			$is_patch = 1;
1164
			$first_line = $linenr + 1;
1165
1166
1167
1168
1169
1170
			$realline=$1-1;
			if (defined $2) {
				$realcnt=$3+1;
			} else {
				$realcnt=1+1;
			}
1171
			annotate_reset();
1172
1173
			$prev_values = 'E';

1174
			%suppress_ifbraces = ();
1175
			%suppress_whiletrailers = ();
1176
1177
			next;

1178
1179
1180
# 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.
1181
		} elsif ($line =~ /^( |\+|$)/) {
1182
			$realline++;