checkpatch.pl 67.6 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
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{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
130
our $Compare    = qr{<=|>=|==|!=|<|>};
131
132
133
our $Operators	= qr{
			<=|>=|==|!=|
			=>|->|<<|>>|<|>|!|~|
134
			&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
135
136
		  }x;

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

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

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

157
158
our @typeList = (
	qr{void},
159
160
161
162
163
164
165
	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},
166
167
168
169
170
171
172
173
174
175
176
	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},
);
177
178
179
our @modifierList = (
	qr{fastcall},
);
180
181

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

$chk_signoff = 0 if ($file);

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

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

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

exit($exit);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

393
394
395
	return $res;
}

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

404
405
	my $loff = 0;

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

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

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

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

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

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

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

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

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

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

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
545
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;
	}
}

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

	my (@chunks);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return ($cmt ne '');
}

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
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;
}

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

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

715
	return $res;
716
717
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

786
			$type = 'E';
787

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

875
876
877
878
879
880
881
882
883
884
885
886
887
888
		} 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';
889

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

894
		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
895
896
897
898
899
900
901
902
903
904
905
906
			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';

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

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

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

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

928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
	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) {
944
945
946
947
948
949
950
		# 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;
951
952
953
954
			for my $modifier (split(' ', $possible)) {
				warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
				push(@modifierList, $modifier);
			}
955
956
957
958
959

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

966
967
my $prefix = '';

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

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

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

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

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

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

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

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

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

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

1063
1064
1065
	my $prev_values = 'E';

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

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

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

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

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

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

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

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

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

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

1152
1153
	$prefix = '';

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

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

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

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

1179
1180
1181
# 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.