checkpatch.pl 66.9 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)
4
5
6
7
8
9
# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
# Licensed under the terms of the GNU GPL License version 2

use strict;

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

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

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

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

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

my $exit = 0;

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

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

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

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

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

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

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

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

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

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

$chk_signoff = 0 if ($file);

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

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

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

exit($exit);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

391
392
393
	return $res;
}

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

402
403
	my $loff = 0;

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

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

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

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

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

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

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

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

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

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

501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
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;
	}
}

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

	my (@chunks);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return ($cmt ne '');
}

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

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

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

713
	return $res;
714
715
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

784
			$type = 'E';
785

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

964
965
my $prefix = '';

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

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

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

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

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

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

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

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

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

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

1060
1061
1062
	my $prev_values = 'E';

	# suppression flags
1063
	my %suppress_ifbraces;
1064
	my %suppress_whiletrailers;
1065

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

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

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

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

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

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

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

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

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

1149
1150
	$prefix = '';

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

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

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

1172
			%suppress_ifbraces = ();
1173
			%suppress_whiletrailers = ();
1174
1175
			next;

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

1183
			# Measure the line length and indent.
Andy Whitcroft's avatar