checkpatch.pl 68.4 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 @stack = ([$type, $level]);
409
	my $p;
410
411
	my $c;
	my $len = 0;
412
413

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

439
		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
440
441
442
443
444
445
446
447
448
449

		# Handle nested #if/#else.
		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
			push(@stack, [ $type, $level ]);
		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
			($type, $level) = @{$stack[$#stack - 1]};
		} elsif ($remainder =~ /^#\s*endif\b/) {
			($type, $level) = @{pop(@stack)};
		}

450
451
452
453
454
455
		# Statement ends at the ';' or a close '}' at the
		# outermost level.
		if ($level == 0 && $c eq ';') {
			last;
		}

456
		# An else is really a conditional as long as its not else if
457
458
459
460
461
462
463
464
		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";
465
466
		}

467
468
469
470
471
472
473
474
475
476
		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;
477
478
				$coff_set = 1;
				#warn "CSB: mark coff<$coff>\n";
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
			}
		}
		if (($type eq '' || $type eq '{') && $c eq '{') {
			$level++;
			$type = '{';
		}
		if ($type eq '{' && $c eq '}') {
			$level--;
			$type = ($level != 0)? '{' : '';

			if ($level == 0) {
				last;
			}
		}
		$off++;
	}
495
	# We are truly at the end, so shuffle to the next line.
496
	if ($off == $len) {
497
		$loff = $len + 1;
498
499
500
		$line++;
		$remain--;
	}
501
502
503
504
505
506
507

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

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

508
	#print "coff<$coff> soff<$off> loff<$loff>\n";
509
510
511
512
513

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

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
546
547
548
549
550
551
552
553
554
555
556
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;
	}
}

557
558
559
560
561
562
sub ctx_statement_full {
	my ($linenr, $remain, $off) = @_;
	my ($statement, $condition, $level);

	my (@chunks);

563
	# Grab the first conditional/block pair.
564
565
	($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
566
	#print "F: c<$condition> s<$statement> remain<$remain>\n";
567
568
569
570
571
572
573
	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.
574
575
576
	for (;;) {
		($statement, $condition, $linenr, $remain, $off, $level) =
				ctx_statement_block($linenr, $remain, $off);
577
		#print "C: c<$condition> s<$statement> remain<$remain>\n";
578
		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
579
580
		#print "C: push\n";
		push(@chunks, [ $condition, $statement ]);
581
582
583
	}

	return ($level, $linenr, @chunks);
584
585
}

586
sub ctx_block_get {
587
	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
588
589
590
591
592
593
594
	my $line;
	my $start = $linenr - 1;
	my $blk = '';
	my @o;
	my @c;
	my @res = ();

595
	my $level = 0;
596
	my @stack = ($level);
597
598
599
600
601
	for ($line = $start; $remain > 0; $line++) {
		next if ($rawlines[$line] =~ /^-/);
		$remain--;

		$blk .= $rawlines[$line];
602
603
604
605
606
607
608
609
610
611

		# Handle nested #if/#else.
		if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
			push(@stack, $level);
		} elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
			$level = $stack[$#stack - 1];
		} elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
			$level = pop(@stack);
		}

612
613
614
615
616
617
		foreach my $c (split(//, $rawlines[$line])) {
			##print "C<$c>L<$level><$open$close>O<$off>\n";
			if ($off > 0) {
				$off--;
				next;
			}
618

619
620
621
622
623
624
625
			if ($c eq $close && $level > 0) {
				$level--;
				last if ($level == 0);
			} elsif ($c eq $open) {
				$level++;
			}
		}
626

627
		if (!$outer || $level <= 1) {
628
			push(@res, $rawlines[$line]);
629
630
		}

631
		last if ($level == 0);
632
633
	}

634
	return ($level, @res);
635
636
637
638
}
sub ctx_block_outer {
	my ($linenr, $remain) = @_;

639
640
	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
	return @r;
641
642
643
644
}
sub ctx_block {
	my ($linenr, $remain) = @_;

645
646
	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
	return @r;
647
648
}
sub ctx_statement {
649
650
651
652
653
654
	my ($linenr, $remain, $off) = @_;

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

657
	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
658
}
659
660
661
662
663
sub ctx_statement_level {
	my ($linenr, $remain, $off) = @_;

	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
}
664
665
666
667
668

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

	# Catch a comment on the end of the line itself.
669
	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
670
671
672
673
674
675
676
	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++) {
677
678
		my $line = $rawlines[$linenr - 1];
		#warn "           $line\n";
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
		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);

701
	##print "LINE: $rawlines[$end_line - 1 ]\n";
702
703
704
705
706
	##print "CMMT: $cmt\n";

	return ($cmt ne '');
}

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
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;
}

723
724
725
sub cat_vet {
	my ($vet) = @_;
	my ($res, $coded);
726

727
728
729
730
731
732
	$res = '';
	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
		$res .= $1;
		if ($2 ne '') {
			$coded = sprintf("^%c", unpack('C', $2) + 64);
			$res .= $coded;
733
734
		}
	}
735
	$res =~ s/$/\$/;
736

737
	return $res;
738
739
}

740
my $av_preprocessor = 0;
741
my $av_pending;
742
my @av_paren_type;
743
my $av_pend_colon;
744
745
746

sub annotate_reset {
	$av_preprocessor = 0;
747
748
	$av_pending = '_';
	@av_paren_type = ('E');
749
	$av_pend_colon = 'O';
750
751
}

752
753
sub annotate_values {
	my ($stream, $type) = @_;
754

755
	my $res;
756
	my $var = '_' x length($stream);
757
758
	my $cur = $stream;

759
	print "$stream\n" if ($dbg_values > 1);
760
761

	while (length($cur)) {
762
		@av_paren_type = ('E') if ($#av_paren_type < 0);
763
		print " <" . join('', @av_paren_type) .
764
				"> <$type> <$av_pending>" if ($dbg_values > 1);
765
		if ($cur =~ /^(\s+)/o) {
766
767
			print "WS($1)\n" if ($dbg_values > 1);
			if ($1 =~ /\n/ && $av_preprocessor) {
768
				$type = pop(@av_paren_type);
769
				$av_preprocessor = 0;
770
771
			}

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

776
777
778
779
		} elsif ($cur =~ /^($Modifier)\s*/) {
			print "MODIFIER($1)\n" if ($dbg_values > 1);
			$type = 'T';

780
		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
781
			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
782
			$av_preprocessor = 1;
783
784
785
786
787
788
			push(@av_paren_type, $type);
			if ($2 ne '') {
				$av_pending = 'N';
			}
			$type = 'E';

789
		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
790
791
792
			print "UNDEF($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;
			push(@av_paren_type, $type);
793

794
		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
795
			print "PRE_START($1)\n" if ($dbg_values > 1);
796
			$av_preprocessor = 1;
797
798
799

			push(@av_paren_type, $type);
			push(@av_paren_type, $type);
800
			$type = 'E';
801

802
		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
803
804
805
806
807
			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
			$av_preprocessor = 1;

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

808
			$type = 'E';
809

810
		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
811
812
813
814
815
816
817
818
			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);
819
			$type = 'E';
820
821

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

824
825
826
827
828
		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
			print "ATTR($1)\n" if ($dbg_values > 1);
			$av_pending = $type;
			$type = 'N';

829
		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
830
			print "SIZEOF($1)\n" if ($dbg_values > 1);
831
			if (defined $2) {
832
				$av_pending = 'V';
833
834
835
			}
			$type = 'N';

836
		} elsif ($cur =~ /^(if|while|for)\b/o) {
837
			print "COND($1)\n" if ($dbg_values > 1);
838
			$av_pending = 'E';
839
840
			$type = 'N';

841
842
843
844
845
		} elsif ($cur =~/^(case)/o) {
			print "CASE($1)\n" if ($dbg_values > 1);
			$av_pend_colon = 'C';
			$type = 'N';

846
		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
847
			print "KEYWORD($1)\n" if ($dbg_values > 1);
848
849
850
			$type = 'N';

		} elsif ($cur =~ /^(\()/o) {
851
			print "PAREN('$1')\n" if ($dbg_values > 1);
852
853
			push(@av_paren_type, $av_pending);
			$av_pending = '_';
854
855
856
			$type = 'N';

		} elsif ($cur =~ /^(\))/o) {
857
858
859
			my $new_type = pop(@av_paren_type);
			if ($new_type ne '_') {
				$type = $new_type;
860
861
				print "PAREN('$1') -> $type\n"
							if ($dbg_values > 1);
862
			} else {
863
				print "PAREN('$1')\n" if ($dbg_values > 1);
864
865
			}

866
		} elsif ($cur =~ /^($Ident)\s*\(/o) {
867
			print "FUNC($1)\n" if ($dbg_values > 1);
868
			$type = 'V';
869
			$av_pending = 'V';
870

871
872
		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
			if (defined $2 && $type eq 'C' || $type eq 'T') {
873
				$av_pend_colon = 'B';
874
875
			} elsif ($type eq 'E') {
				$av_pend_colon = 'L';
876
877
878
879
			}
			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
			$type = 'V';

880
		} elsif ($cur =~ /^($Ident|$Constant)/o) {
881
			print "IDENT($1)\n" if ($dbg_values > 1);
882
883
884
			$type = 'V';

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

888
		} elsif ($cur =~/^(;|{|})/) {
889
			print "END($1)\n" if ($dbg_values > 1);
890
			$type = 'E';
891
892
			$av_pend_colon = 'O';

893
894
895
896
		} elsif ($cur =~/^(,)/) {
			print "COMMA($1)\n" if ($dbg_values > 1);
			$type = 'C';

897
898
899
900
901
902
903
904
905
906
907
908
909
910
		} 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';
911

912
		} elsif ($cur =~ /^(\[)/o) {
913
			print "CLOSE($1)\n" if ($dbg_values > 1);
914
915
			$type = 'N';

916
		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
917
918
919
920
921
922
923
924
925
926
927
928
			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';

929
		} elsif ($cur =~ /^($Operators)/o) {
930
			print "OP($1)\n" if ($dbg_values > 1);
931
932
933
934
935
			if ($1 ne '++' && $1 ne '--') {
				$type = 'N';
			}

		} elsif ($cur =~ /(^.)/o) {
936
			print "C($1)\n" if ($dbg_values > 1);
937
938
939
940
941
		}
		if (defined $1) {
			$cur = substr($cur, length($1));
			$res .= $type x length($1);
		}
942
	}
943

944
	return ($res, $var);
945
946
}

947
sub possible {
948
	my ($possible, $line) = @_;
949

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
	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) {
966
967
968
969
970
971
972
		# 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;
973
974
975
976
			for my $modifier (split(' ', $possible)) {
				warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
				push(@modifierList, $modifier);
			}
977
978
979
980
981

		} else {
			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
			push(@typeList, $possible);
		}
982
		build_types();
983
984
	} else {
		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
985
986
987
	}
}

988
989
my $prefix = '';

990
sub report {
991
992
993
	if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
		return 0;
	}
994
995
996
997
	my $line = $prefix . $_[0];

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

998
	push(our @report, $line);
999
1000

	return 1;
1001
1002
}
sub report_dump {
1003
	our @report;
1004
}
1005
sub ERROR {
1006
1007
1008
1009
	if (report("ERROR: $_[0]\n")) {
		our $clean = 0;
		our $cnt_error++;
	}
1010
1011
}
sub WARN {
1012
1013
1014
1015
	if (report("WARNING: $_[0]\n")) {
		our $clean = 0;
		our $cnt_warn++;
	}
1016
1017
}
sub CHK {
1018
	if ($check && report("CHECK: $_[0]\n")) {
1019
1020
1021
		our $clean = 0;
		our $cnt_chk++;
	}
1022
1023
}

1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
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);
	}
}

1051
1052
1053
1054
1055
sub process {
	my $filename = shift;

	my $linenr=0;
	my $prevline="";
1056
	my $prevrawline="";
1057
	my $stashline="";
1058
	my $stashrawline="";
1059

1060
	my $length;
1061
1062
1063
1064
	my $indent;
	my $previndent=0;
	my $stashindent=0;

1065
	our $clean = 1;
1066
1067
1068
	my $signoff = 0;
	my $is_patch = 0;

1069
	our @report = ();
1070
1071
1072
1073
1074
	our $cnt_lines = 0;
	our $cnt_error = 0;
	our $cnt_warn = 0;
	our $cnt_chk = 0;

1075
1076
1077
1078
1079
1080
	# Trace the real file/line as we go.
	my $realfile = '';
	my $realline = 0;
	my $realcnt = 0;
	my $here = '';
	my $in_comment = 0;
1081
	my $comment_edge = 0;
1082
	my $first_line = 0;
1083
	my $p1_prefix = '';
1084

1085
1086
1087
	my $prev_values = 'E';

	# suppression flags
1088
	my %suppress_ifbraces;
1089
	my %suppress_whiletrailers;
1090

1091
	# Pre-scan the patch sanitizing the lines.
1092
	# Pre-scan the patch looking for any __setup documentation.
1093
	#
1094
1095
	my @setup_docs = ();
	my $setup_docs = 0;
1096
1097

	sanitise_line_reset();
1098
1099
	my $line;
	foreach my $rawline (@rawlines) {
1100
1101
		$linenr++;
		$line = $rawline;
1102

1103
		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1104
1105
1106
1107
			$setup_docs = 0;
			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
				$setup_docs = 1;
			}
1108
1109
1110
1111
1112
1113
1114
1115
1116
			#next;
		}
		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
			$realline=$1-1;
			if (defined $2) {
				$realcnt=$3+1;
			} else {
				$realcnt=1+1;
			}
1117
			$in_comment = 0;
1118
1119
1120
1121
1122
1123

			# 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;
1124
1125
1126
1127
1128
1129
			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";
1130
				last if (!defined $rawlines[$ln - 1]);
1131
1132
1133
1134
1135
				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
					($edge) = $1;
					last;
				}
1136
1137
1138
1139
1140
1141
1142
1143
1144
			}
			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 &&
1145
			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1146
1147
1148
1149
1150
1151
1152
			{
				$in_comment = 1;
			}

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

1153
		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1154
			# Standardise the strings and chars within the input to
1155
			# simplify matching -- only bother with positive lines.
1156
			$line = sanitise_line($rawline);
1157
		}
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
		push(@lines, $line);

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

		#print "==>$rawline\n";
		#print "-->$line\n";
1168
1169
1170
1171
1172
1173

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

1174
1175
	$prefix = '';

1176
1177
	$realcnt = 0;
	$linenr = 0;
1178
1179
1180
	foreach my $line (@lines) {
		$linenr++;

1181
		my $rawline = $rawlines[$linenr - 1];
1182
		my $hunk_line = ($realcnt != 0);
1183

1184
#extract the line range in the file after the patch is applied
1185
		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1186
			$is_patch = 1;
1187
			$first_line = $linenr + 1;
1188
1189