xref: /linux-6.15/scripts/checkpatch.pl (revision 3445686a)
10a920b5bSAndy Whitcroft#!/usr/bin/perl -w
2dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit)
300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit)
42a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)
5015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]>
60a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2
70a920b5bSAndy Whitcroft
80a920b5bSAndy Whitcroftuse strict;
90a920b5bSAndy Whitcroft
100a920b5bSAndy Whitcroftmy $P = $0;
1100df344fSAndy Whitcroft$P =~ s@.*/@@g;
120a920b5bSAndy Whitcroft
13000d1cc1SJoe Perchesmy $V = '0.32';
140a920b5bSAndy Whitcroft
150a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
160a920b5bSAndy Whitcroft
170a920b5bSAndy Whitcroftmy $quiet = 0;
180a920b5bSAndy Whitcroftmy $tree = 1;
190a920b5bSAndy Whitcroftmy $chk_signoff = 1;
200a920b5bSAndy Whitcroftmy $chk_patch = 1;
21773647a0SAndy Whitcroftmy $tst_only;
226c72ffaaSAndy Whitcroftmy $emacs = 0;
238905a67cSAndy Whitcroftmy $terse = 0;
246c72ffaaSAndy Whitcroftmy $file = 0;
256c72ffaaSAndy Whitcroftmy $check = 0;
268905a67cSAndy Whitcroftmy $summary = 1;
278905a67cSAndy Whitcroftmy $mailback = 0;
2813214adfSAndy Whitcroftmy $summary_file = 0;
29000d1cc1SJoe Perchesmy $show_types = 0;
303705ce5bSJoe Perchesmy $fix = 0;
316c72ffaaSAndy Whitcroftmy $root;
32c2fdda0dSAndy Whitcroftmy %debug;
33000d1cc1SJoe Perchesmy %ignore_type = ();
34*3445686aSJoe Perchesmy %camelcase = ();
35000d1cc1SJoe Perchesmy @ignore = ();
3677f5b10aSHannes Edermy $help = 0;
37000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
386cd7f386SJoe Perchesmy $max_line_length = 80;
3977f5b10aSHannes Eder
4077f5b10aSHannes Edersub help {
4177f5b10aSHannes Eder	my ($exitcode) = @_;
4277f5b10aSHannes Eder
4377f5b10aSHannes Eder	print << "EOM";
4477f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
4577f5b10aSHannes EderVersion: $V
4677f5b10aSHannes Eder
4777f5b10aSHannes EderOptions:
4877f5b10aSHannes Eder  -q, --quiet                quiet
4977f5b10aSHannes Eder  --no-tree                  run without a kernel tree
5077f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
5177f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
5277f5b10aSHannes Eder  --emacs                    emacs compile window format
5377f5b10aSHannes Eder  --terse                    one line per report
5477f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
5577f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
56000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
576cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
58000d1cc1SJoe Perches  --show-types               show the message "types" in the output
5977f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
6077f5b10aSHannes Eder  --no-summary               suppress the per-file summary
6177f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
6277f5b10aSHannes Eder  --summary-file             include the filename in summary
6377f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
6477f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
6577f5b10aSHannes Eder                             is all off)
6677f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
6777f5b10aSHannes Eder                             literally
683705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
693705ce5bSJoe Perches                             If correctable single-line errors exist, create
703705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
713705ce5bSJoe Perches                             with potential errors corrected to the preferred
723705ce5bSJoe Perches                             checkpatch style
7377f5b10aSHannes Eder  -h, --help, --version      display this help and exit
7477f5b10aSHannes Eder
7577f5b10aSHannes EderWhen FILE is - read standard input.
7677f5b10aSHannes EderEOM
7777f5b10aSHannes Eder
7877f5b10aSHannes Eder	exit($exitcode);
7977f5b10aSHannes Eder}
8077f5b10aSHannes Eder
81000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
82000d1cc1SJoe Perchesif (-f $conf) {
83000d1cc1SJoe Perches	my @conf_args;
84000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
85000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
86000d1cc1SJoe Perches
87000d1cc1SJoe Perches	while (<$conffile>) {
88000d1cc1SJoe Perches		my $line = $_;
89000d1cc1SJoe Perches
90000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
91000d1cc1SJoe Perches		$line =~ s/^\s*//g;
92000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
93000d1cc1SJoe Perches
94000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
95000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
96000d1cc1SJoe Perches
97000d1cc1SJoe Perches		my @words = split(" ", $line);
98000d1cc1SJoe Perches		foreach my $word (@words) {
99000d1cc1SJoe Perches			last if ($word =~ m/^#/);
100000d1cc1SJoe Perches			push (@conf_args, $word);
101000d1cc1SJoe Perches		}
102000d1cc1SJoe Perches	}
103000d1cc1SJoe Perches	close($conffile);
104000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
105000d1cc1SJoe Perches}
106000d1cc1SJoe Perches
1070a920b5bSAndy WhitcroftGetOptions(
1086c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1090a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1100a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1110a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1126c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1138905a67cSAndy Whitcroft	'terse!'	=> \$terse,
11477f5b10aSHannes Eder	'f|file!'	=> \$file,
1156c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1166c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
117000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
118000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
1196cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
1206c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
1218905a67cSAndy Whitcroft	'summary!'	=> \$summary,
1228905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
12313214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
1243705ce5bSJoe Perches	'fix!'		=> \$fix,
125c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
126773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
12777f5b10aSHannes Eder	'h|help'	=> \$help,
12877f5b10aSHannes Eder	'version'	=> \$help
12977f5b10aSHannes Eder) or help(1);
13077f5b10aSHannes Eder
13177f5b10aSHannes Ederhelp(0) if ($help);
1320a920b5bSAndy Whitcroft
1330a920b5bSAndy Whitcroftmy $exit = 0;
1340a920b5bSAndy Whitcroft
1350a920b5bSAndy Whitcroftif ($#ARGV < 0) {
13677f5b10aSHannes Eder	print "$P: no input files\n";
1370a920b5bSAndy Whitcroft	exit(1);
1380a920b5bSAndy Whitcroft}
1390a920b5bSAndy Whitcroft
140000d1cc1SJoe Perches@ignore = split(/,/, join(',',@ignore));
141000d1cc1SJoe Perchesforeach my $word (@ignore) {
142000d1cc1SJoe Perches	$word =~ s/\s*\n?$//g;
143000d1cc1SJoe Perches	$word =~ s/^\s*//g;
144000d1cc1SJoe Perches	$word =~ s/\s+/ /g;
145000d1cc1SJoe Perches	$word =~ tr/[a-z]/[A-Z]/;
146000d1cc1SJoe Perches
147000d1cc1SJoe Perches	next if ($word =~ m/^\s*#/);
148000d1cc1SJoe Perches	next if ($word =~ m/^\s*$/);
149000d1cc1SJoe Perches
150000d1cc1SJoe Perches	$ignore_type{$word}++;
151000d1cc1SJoe Perches}
152000d1cc1SJoe Perches
153c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
154c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
1557429c690SAndy Whitcroftmy $dbg_type = 0;
156a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
157c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
15821caa13cSAndy Whitcroft	## no critic
15921caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
16021caa13cSAndy Whitcroft	die "$@" if ($@);
161c2fdda0dSAndy Whitcroft}
162c2fdda0dSAndy Whitcroft
163d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
164d2c0a235SAndy Whitcroft
1658905a67cSAndy Whitcroftif ($terse) {
1668905a67cSAndy Whitcroft	$emacs = 1;
1678905a67cSAndy Whitcroft	$quiet++;
1688905a67cSAndy Whitcroft}
1698905a67cSAndy Whitcroft
1706c72ffaaSAndy Whitcroftif ($tree) {
1716c72ffaaSAndy Whitcroft	if (defined $root) {
1726c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
1736c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
1746c72ffaaSAndy Whitcroft		}
1756c72ffaaSAndy Whitcroft	} else {
1766c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
1776c72ffaaSAndy Whitcroft			$root = '.';
1786c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
1796c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
1806c72ffaaSAndy Whitcroft			$root = $1;
1816c72ffaaSAndy Whitcroft		}
1826c72ffaaSAndy Whitcroft	}
1836c72ffaaSAndy Whitcroft
1846c72ffaaSAndy Whitcroft	if (!defined $root) {
1850a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
1860a920b5bSAndy Whitcroft		exit(2);
1870a920b5bSAndy Whitcroft	}
1886c72ffaaSAndy Whitcroft}
1896c72ffaaSAndy Whitcroft
1906c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
1916c72ffaaSAndy Whitcroft
1922ceb532bSAndy Whitcroftour $Ident	= qr{
1932ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
1942ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
1952ceb532bSAndy Whitcroft		}x;
1966c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
1976c72ffaaSAndy Whitcroftour $Sparse	= qr{
1986c72ffaaSAndy Whitcroft			__user|
1996c72ffaaSAndy Whitcroft			__kernel|
2006c72ffaaSAndy Whitcroft			__force|
2016c72ffaaSAndy Whitcroft			__iomem|
2026c72ffaaSAndy Whitcroft			__must_check|
2036c72ffaaSAndy Whitcroft			__init_refok|
204417495edSAndy Whitcroft			__kprobes|
205165e72a6SSven Eckelmann			__ref|
206165e72a6SSven Eckelmann			__rcu
2076c72ffaaSAndy Whitcroft		}x;
20852131292SWolfram Sang
20952131292SWolfram Sang# Notes to $Attribute:
21052131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
2116c72ffaaSAndy Whitcroftour $Attribute	= qr{
2126c72ffaaSAndy Whitcroft			const|
21303f1df7dSJoe Perches			__percpu|
21403f1df7dSJoe Perches			__nocast|
21503f1df7dSJoe Perches			__safe|
21603f1df7dSJoe Perches			__bitwise__|
21703f1df7dSJoe Perches			__packed__|
21803f1df7dSJoe Perches			__packed2__|
21903f1df7dSJoe Perches			__naked|
22003f1df7dSJoe Perches			__maybe_unused|
22103f1df7dSJoe Perches			__always_unused|
22203f1df7dSJoe Perches			__noreturn|
22303f1df7dSJoe Perches			__used|
22403f1df7dSJoe Perches			__cold|
22503f1df7dSJoe Perches			__noclone|
22603f1df7dSJoe Perches			__deprecated|
2276c72ffaaSAndy Whitcroft			__read_mostly|
2286c72ffaaSAndy Whitcroft			__kprobes|
22952131292SWolfram Sang			__(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
23024e1d81aSAndy Whitcroft			____cacheline_aligned|
23124e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
2325fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
2335fe3af11SAndy Whitcroft			__weak
2346c72ffaaSAndy Whitcroft		  }x;
235c45dcabdSAndy Whitcroftour $Modifier;
2366c72ffaaSAndy Whitcroftour $Inline	= qr{inline|__always_inline|noinline};
2376c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
2386c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
2396c72ffaaSAndy Whitcroft
24095e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
24195e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
24295e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
24395e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
244326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
245326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
246326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
24774349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
24895e2c602SJoe Perchesour $Constant	= qr{$Float|$Binary|$Hex|$Int};
249326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
25086f9d059SAndy Whitcroftour $Compare    = qr{<=|>=|==|!=|<|>};
25123f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
2526c72ffaaSAndy Whitcroftour $Operators	= qr{
2536c72ffaaSAndy Whitcroft			<=|>=|==|!=|
2546c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
25523f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
2566c72ffaaSAndy Whitcroft		  }x;
2576c72ffaaSAndy Whitcroft
2588905a67cSAndy Whitcroftour $NonptrType;
2598905a67cSAndy Whitcroftour $Type;
2608905a67cSAndy Whitcroftour $Declare;
2618905a67cSAndy Whitcroft
26215662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
26315662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
264171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
265171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
266171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
267171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
268171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
269171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
270171ae1a4SAndy Whitcroft}x;
271171ae1a4SAndy Whitcroft
27215662b3eSJoe Perchesour $UTF8	= qr{
27315662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
27415662b3eSJoe Perches	| $NON_ASCII_UTF8
27515662b3eSJoe Perches}x;
27615662b3eSJoe Perches
2778ed22cadSAndy Whitcroftour $typeTypedefs = qr{(?x:
278fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
2798ed22cadSAndy Whitcroft	atomic_t
2808ed22cadSAndy Whitcroft)};
2818ed22cadSAndy Whitcroft
282691e669bSJoe Perchesour $logFunctions = qr{(?x:
2836e60c02eSJoe Perches	printk(?:_ratelimited|_once|)|
2846e60c02eSJoe Perches	[a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
2856e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
286b0531722SJoe Perches	panic|
287b0531722SJoe Perches	MODULE_[A-Z_]+
288691e669bSJoe Perches)};
289691e669bSJoe Perches
29020112475SJoe Perchesour $signature_tags = qr{(?xi:
29120112475SJoe Perches	Signed-off-by:|
29220112475SJoe Perches	Acked-by:|
29320112475SJoe Perches	Tested-by:|
29420112475SJoe Perches	Reviewed-by:|
29520112475SJoe Perches	Reported-by:|
2968543ae12SMugunthan V N	Suggested-by:|
29720112475SJoe Perches	To:|
29820112475SJoe Perches	Cc:
29920112475SJoe Perches)};
30020112475SJoe Perches
3018905a67cSAndy Whitcroftour @typeList = (
3028905a67cSAndy Whitcroft	qr{void},
303c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?char},
304c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?short},
305c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?int},
306c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long},
307c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+int},
308c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long},
309c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long\s+int},
3108905a67cSAndy Whitcroft	qr{unsigned},
3118905a67cSAndy Whitcroft	qr{float},
3128905a67cSAndy Whitcroft	qr{double},
3138905a67cSAndy Whitcroft	qr{bool},
3148905a67cSAndy Whitcroft	qr{struct\s+$Ident},
3158905a67cSAndy Whitcroft	qr{union\s+$Ident},
3168905a67cSAndy Whitcroft	qr{enum\s+$Ident},
3178905a67cSAndy Whitcroft	qr{${Ident}_t},
3188905a67cSAndy Whitcroft	qr{${Ident}_handler},
3198905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
3208905a67cSAndy Whitcroft);
321c45dcabdSAndy Whitcroftour @modifierList = (
322c45dcabdSAndy Whitcroft	qr{fastcall},
323c45dcabdSAndy Whitcroft);
3248905a67cSAndy Whitcroft
3257840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
3267840a94cSWolfram Sang	irq|
3277840a94cSWolfram Sang	memory
3287840a94cSWolfram Sang)};
3297840a94cSWolfram Sang# memory.h: ARM has a custom one
3307840a94cSWolfram Sang
3318905a67cSAndy Whitcroftsub build_types {
332d2172eb5SAndy Whitcroft	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
333d2172eb5SAndy Whitcroft	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
334c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
3358905a67cSAndy Whitcroft	$NonptrType	= qr{
336d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
337cf655043SAndy Whitcroft			(?:
3386b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
3398ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
340c45dcabdSAndy Whitcroft				(?:${all}\b)
341cf655043SAndy Whitcroft			)
342c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
3438905a67cSAndy Whitcroft		  }x;
3448905a67cSAndy Whitcroft	$Type	= qr{
345c45dcabdSAndy Whitcroft			$NonptrType
346b337d8b8SAndy Whitcroft			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
347c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
3488905a67cSAndy Whitcroft		  }x;
3498905a67cSAndy Whitcroft	$Declare	= qr{(?:$Storage\s+)?$Type};
3508905a67cSAndy Whitcroft}
3518905a67cSAndy Whitcroftbuild_types();
3526c72ffaaSAndy Whitcroft
3537d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
354d1fe9c09SJoe Perches
355d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
356d1fe9c09SJoe Perches# requires at least perl version v5.10.0
357d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
358d1fe9c09SJoe Perches
359d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
360d1fe9c09SJoe Perchesour $LvalOrFunc	= qr{($Lval)\s*($balanced_parens{0,1})\s*};
361d7c76ba7SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
3627d2367afSJoe Perches
3637d2367afSJoe Perchessub deparenthesize {
3647d2367afSJoe Perches	my ($string) = @_;
3657d2367afSJoe Perches	return "" if (!defined($string));
3667d2367afSJoe Perches	$string =~ s@^\s*\(\s*@@g;
3677d2367afSJoe Perches	$string =~ s@\s*\)\s*$@@g;
3687d2367afSJoe Perches	$string =~ s@\s+@ @g;
3697d2367afSJoe Perches	return $string;
3707d2367afSJoe Perches}
3717d2367afSJoe Perches
372*3445686aSJoe Perchessub seed_camelcase_file {
373*3445686aSJoe Perches	my ($file) = @_;
374*3445686aSJoe Perches
375*3445686aSJoe Perches	return if (!(-f $file));
376*3445686aSJoe Perches
377*3445686aSJoe Perches	local $/;
378*3445686aSJoe Perches
379*3445686aSJoe Perches	open(my $include_file, '<', "$file")
380*3445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
381*3445686aSJoe Perches	my $text = <$include_file>;
382*3445686aSJoe Perches	close($include_file);
383*3445686aSJoe Perches
384*3445686aSJoe Perches	my @lines = split('\n', $text);
385*3445686aSJoe Perches
386*3445686aSJoe Perches	foreach my $line (@lines) {
387*3445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
388*3445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
389*3445686aSJoe Perches			$camelcase{$1} = 1;
390*3445686aSJoe Perches		}
391*3445686aSJoe Perches	        elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*\(/) {
392*3445686aSJoe Perches			$camelcase{$1} = 1;
393*3445686aSJoe Perches		}
394*3445686aSJoe Perches	}
395*3445686aSJoe Perches}
396*3445686aSJoe Perches
397*3445686aSJoe Perchesmy $camelcase_seeded = 0;
398*3445686aSJoe Perchessub seed_camelcase_includes {
399*3445686aSJoe Perches	return if ($camelcase_seeded);
400*3445686aSJoe Perches
401*3445686aSJoe Perches	my $files;
402*3445686aSJoe Perches	if (-d ".git") {
403*3445686aSJoe Perches		$files = `git ls-files include`;
404*3445686aSJoe Perches	} else {
405*3445686aSJoe Perches		$files = `find $root/include -name "*.h"`;
406*3445686aSJoe Perches	}
407*3445686aSJoe Perches	my @include_files = split('\n', $files);
408*3445686aSJoe Perches	foreach my $file (@include_files) {
409*3445686aSJoe Perches		seed_camelcase_file($file);
410*3445686aSJoe Perches	}
411*3445686aSJoe Perches	$camelcase_seeded = 1;
412*3445686aSJoe Perches}
413*3445686aSJoe Perches
4146c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
4150a920b5bSAndy Whitcroft
41600df344fSAndy Whitcroftmy @rawlines = ();
417c2fdda0dSAndy Whitcroftmy @lines = ();
4183705ce5bSJoe Perchesmy @fixed = ();
419c2fdda0dSAndy Whitcroftmy $vname;
4206c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
42121caa13cSAndy Whitcroft	my $FILE;
4226c72ffaaSAndy Whitcroft	if ($file) {
42321caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
4246c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
42521caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
42621caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
4276c72ffaaSAndy Whitcroft	} else {
42821caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
4296c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
4306c72ffaaSAndy Whitcroft	}
431c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
432c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
433c2fdda0dSAndy Whitcroft	} else {
434c2fdda0dSAndy Whitcroft		$vname = $filename;
435c2fdda0dSAndy Whitcroft	}
43621caa13cSAndy Whitcroft	while (<$FILE>) {
4370a920b5bSAndy Whitcroft		chomp;
43800df344fSAndy Whitcroft		push(@rawlines, $_);
4396c72ffaaSAndy Whitcroft	}
44021caa13cSAndy Whitcroft	close($FILE);
441c2fdda0dSAndy Whitcroft	if (!process($filename)) {
4420a920b5bSAndy Whitcroft		$exit = 1;
4430a920b5bSAndy Whitcroft	}
44400df344fSAndy Whitcroft	@rawlines = ();
44513214adfSAndy Whitcroft	@lines = ();
4463705ce5bSJoe Perches	@fixed = ();
4470a920b5bSAndy Whitcroft}
4480a920b5bSAndy Whitcroft
4490a920b5bSAndy Whitcroftexit($exit);
4500a920b5bSAndy Whitcroft
4510a920b5bSAndy Whitcroftsub top_of_kernel_tree {
4526c72ffaaSAndy Whitcroft	my ($root) = @_;
4536c72ffaaSAndy Whitcroft
4546c72ffaaSAndy Whitcroft	my @tree_check = (
4556c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
4566c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
4576c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
4586c72ffaaSAndy Whitcroft	);
4596c72ffaaSAndy Whitcroft
4606c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
4616c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
4620a920b5bSAndy Whitcroft			return 0;
4630a920b5bSAndy Whitcroft		}
4646c72ffaaSAndy Whitcroft	}
4656c72ffaaSAndy Whitcroft	return 1;
4666c72ffaaSAndy Whitcroft}
4670a920b5bSAndy Whitcroft
46820112475SJoe Perchessub parse_email {
46920112475SJoe Perches	my ($formatted_email) = @_;
47020112475SJoe Perches
47120112475SJoe Perches	my $name = "";
47220112475SJoe Perches	my $address = "";
47320112475SJoe Perches	my $comment = "";
47420112475SJoe Perches
47520112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
47620112475SJoe Perches		$name = $1;
47720112475SJoe Perches		$address = $2;
47820112475SJoe Perches		$comment = $3 if defined $3;
47920112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
48020112475SJoe Perches		$address = $1;
48120112475SJoe Perches		$comment = $2 if defined $2;
48220112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
48320112475SJoe Perches		$address = $1;
48420112475SJoe Perches		$comment = $2 if defined $2;
48520112475SJoe Perches		$formatted_email =~ s/$address.*$//;
48620112475SJoe Perches		$name = $formatted_email;
4873705ce5bSJoe Perches		$name = trim($name);
48820112475SJoe Perches		$name =~ s/^\"|\"$//g;
48920112475SJoe Perches		# If there's a name left after stripping spaces and
49020112475SJoe Perches		# leading quotes, and the address doesn't have both
49120112475SJoe Perches		# leading and trailing angle brackets, the address
49220112475SJoe Perches		# is invalid. ie:
49320112475SJoe Perches		#   "joe smith [email protected]" bad
49420112475SJoe Perches		#   "joe smith <[email protected]" bad
49520112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
49620112475SJoe Perches			$name = "";
49720112475SJoe Perches			$address = "";
49820112475SJoe Perches			$comment = "";
49920112475SJoe Perches		}
50020112475SJoe Perches	}
50120112475SJoe Perches
5023705ce5bSJoe Perches	$name = trim($name);
50320112475SJoe Perches	$name =~ s/^\"|\"$//g;
5043705ce5bSJoe Perches	$address = trim($address);
50520112475SJoe Perches	$address =~ s/^\<|\>$//g;
50620112475SJoe Perches
50720112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
50820112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
50920112475SJoe Perches		$name = "\"$name\"";
51020112475SJoe Perches	}
51120112475SJoe Perches
51220112475SJoe Perches	return ($name, $address, $comment);
51320112475SJoe Perches}
51420112475SJoe Perches
51520112475SJoe Perchessub format_email {
51620112475SJoe Perches	my ($name, $address) = @_;
51720112475SJoe Perches
51820112475SJoe Perches	my $formatted_email;
51920112475SJoe Perches
5203705ce5bSJoe Perches	$name = trim($name);
52120112475SJoe Perches	$name =~ s/^\"|\"$//g;
5223705ce5bSJoe Perches	$address = trim($address);
52320112475SJoe Perches
52420112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
52520112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
52620112475SJoe Perches		$name = "\"$name\"";
52720112475SJoe Perches	}
52820112475SJoe Perches
52920112475SJoe Perches	if ("$name" eq "") {
53020112475SJoe Perches		$formatted_email = "$address";
53120112475SJoe Perches	} else {
53220112475SJoe Perches		$formatted_email = "$name <$address>";
53320112475SJoe Perches	}
53420112475SJoe Perches
53520112475SJoe Perches	return $formatted_email;
53620112475SJoe Perches}
53720112475SJoe Perches
538000d1cc1SJoe Perchessub which_conf {
539000d1cc1SJoe Perches	my ($conf) = @_;
540000d1cc1SJoe Perches
541000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
542000d1cc1SJoe Perches		if (-e "$path/$conf") {
543000d1cc1SJoe Perches			return "$path/$conf";
544000d1cc1SJoe Perches		}
545000d1cc1SJoe Perches	}
546000d1cc1SJoe Perches
547000d1cc1SJoe Perches	return "";
548000d1cc1SJoe Perches}
549000d1cc1SJoe Perches
5500a920b5bSAndy Whitcroftsub expand_tabs {
5510a920b5bSAndy Whitcroft	my ($str) = @_;
5520a920b5bSAndy Whitcroft
5530a920b5bSAndy Whitcroft	my $res = '';
5540a920b5bSAndy Whitcroft	my $n = 0;
5550a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
5560a920b5bSAndy Whitcroft		if ($c eq "\t") {
5570a920b5bSAndy Whitcroft			$res .= ' ';
5580a920b5bSAndy Whitcroft			$n++;
5590a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
5600a920b5bSAndy Whitcroft				$res .= ' ';
5610a920b5bSAndy Whitcroft			}
5620a920b5bSAndy Whitcroft			next;
5630a920b5bSAndy Whitcroft		}
5640a920b5bSAndy Whitcroft		$res .= $c;
5650a920b5bSAndy Whitcroft		$n++;
5660a920b5bSAndy Whitcroft	}
5670a920b5bSAndy Whitcroft
5680a920b5bSAndy Whitcroft	return $res;
5690a920b5bSAndy Whitcroft}
5706c72ffaaSAndy Whitcroftsub copy_spacing {
571773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
5726c72ffaaSAndy Whitcroft	return $res;
5736c72ffaaSAndy Whitcroft}
5740a920b5bSAndy Whitcroft
5754a0df2efSAndy Whitcroftsub line_stats {
5764a0df2efSAndy Whitcroft	my ($line) = @_;
5774a0df2efSAndy Whitcroft
5784a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
5794a0df2efSAndy Whitcroft	$line =~ s/^.//;
5804a0df2efSAndy Whitcroft	$line = expand_tabs($line);
5814a0df2efSAndy Whitcroft
5824a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
5834a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
5844a0df2efSAndy Whitcroft
5854a0df2efSAndy Whitcroft	return (length($line), length($white));
5864a0df2efSAndy Whitcroft}
5874a0df2efSAndy Whitcroft
588773647a0SAndy Whitcroftmy $sanitise_quote = '';
589773647a0SAndy Whitcroft
590773647a0SAndy Whitcroftsub sanitise_line_reset {
591773647a0SAndy Whitcroft	my ($in_comment) = @_;
592773647a0SAndy Whitcroft
593773647a0SAndy Whitcroft	if ($in_comment) {
594773647a0SAndy Whitcroft		$sanitise_quote = '*/';
595773647a0SAndy Whitcroft	} else {
596773647a0SAndy Whitcroft		$sanitise_quote = '';
597773647a0SAndy Whitcroft	}
598773647a0SAndy Whitcroft}
59900df344fSAndy Whitcroftsub sanitise_line {
60000df344fSAndy Whitcroft	my ($line) = @_;
60100df344fSAndy Whitcroft
60200df344fSAndy Whitcroft	my $res = '';
60300df344fSAndy Whitcroft	my $l = '';
60400df344fSAndy Whitcroft
605c2fdda0dSAndy Whitcroft	my $qlen = 0;
606773647a0SAndy Whitcroft	my $off = 0;
607773647a0SAndy Whitcroft	my $c;
60800df344fSAndy Whitcroft
609773647a0SAndy Whitcroft	# Always copy over the diff marker.
610773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
611773647a0SAndy Whitcroft
612773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
613773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
614773647a0SAndy Whitcroft
615773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
616773647a0SAndy Whitcroft		# and end, all to $;.
617773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
618773647a0SAndy Whitcroft			$sanitise_quote = '*/';
619773647a0SAndy Whitcroft
620773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
621773647a0SAndy Whitcroft			$off++;
62200df344fSAndy Whitcroft			next;
623773647a0SAndy Whitcroft		}
62481bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
625773647a0SAndy Whitcroft			$sanitise_quote = '';
626773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
627773647a0SAndy Whitcroft			$off++;
628773647a0SAndy Whitcroft			next;
629773647a0SAndy Whitcroft		}
630113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
631113f04a8SDaniel Walker			$sanitise_quote = '//';
632113f04a8SDaniel Walker
633113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
634113f04a8SDaniel Walker			$off++;
635113f04a8SDaniel Walker			next;
636113f04a8SDaniel Walker		}
637773647a0SAndy Whitcroft
638773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
639773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
640773647a0SAndy Whitcroft		    $c eq "\\") {
641773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
642773647a0SAndy Whitcroft			$off++;
643773647a0SAndy Whitcroft			next;
644773647a0SAndy Whitcroft		}
645773647a0SAndy Whitcroft		# Regular quotes.
646773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
647773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
648773647a0SAndy Whitcroft				$sanitise_quote = $c;
649773647a0SAndy Whitcroft
650773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
651773647a0SAndy Whitcroft				next;
652773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
653773647a0SAndy Whitcroft				$sanitise_quote = '';
65400df344fSAndy Whitcroft			}
65500df344fSAndy Whitcroft		}
656773647a0SAndy Whitcroft
657fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
658773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
659773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
660113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
661113f04a8SDaniel Walker			substr($res, $off, 1, $;);
662773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
663773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
66400df344fSAndy Whitcroft		} else {
665773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
66600df344fSAndy Whitcroft		}
667c2fdda0dSAndy Whitcroft	}
668c2fdda0dSAndy Whitcroft
669113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
670113f04a8SDaniel Walker		$sanitise_quote = '';
671113f04a8SDaniel Walker	}
672113f04a8SDaniel Walker
673c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
674c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
675c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
676c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
677c2fdda0dSAndy Whitcroft
678c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
679c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
680c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
681c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
682c2fdda0dSAndy Whitcroft	}
683c2fdda0dSAndy Whitcroft
68400df344fSAndy Whitcroft	return $res;
68500df344fSAndy Whitcroft}
68600df344fSAndy Whitcroft
687a6962d72SJoe Perchessub get_quoted_string {
688a6962d72SJoe Perches	my ($line, $rawline) = @_;
689a6962d72SJoe Perches
690a6962d72SJoe Perches	return "" if ($line !~ m/(\"[X]+\")/g);
691a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
692a6962d72SJoe Perches}
693a6962d72SJoe Perches
6948905a67cSAndy Whitcroftsub ctx_statement_block {
6958905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
6968905a67cSAndy Whitcroft	my $line = $linenr - 1;
6978905a67cSAndy Whitcroft	my $blk = '';
6988905a67cSAndy Whitcroft	my $soff = $off;
6998905a67cSAndy Whitcroft	my $coff = $off - 1;
700773647a0SAndy Whitcroft	my $coff_set = 0;
7018905a67cSAndy Whitcroft
70213214adfSAndy Whitcroft	my $loff = 0;
70313214adfSAndy Whitcroft
7048905a67cSAndy Whitcroft	my $type = '';
7058905a67cSAndy Whitcroft	my $level = 0;
706a2750645SAndy Whitcroft	my @stack = ();
707cf655043SAndy Whitcroft	my $p;
7088905a67cSAndy Whitcroft	my $c;
7098905a67cSAndy Whitcroft	my $len = 0;
71013214adfSAndy Whitcroft
71113214adfSAndy Whitcroft	my $remainder;
7128905a67cSAndy Whitcroft	while (1) {
713a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
714a2750645SAndy Whitcroft
715773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
7168905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
7178905a67cSAndy Whitcroft		# context.
7188905a67cSAndy Whitcroft		if ($off >= $len) {
7198905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
720dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
721c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
7228905a67cSAndy Whitcroft				$remain--;
72313214adfSAndy Whitcroft				$loff = $len;
724c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
7258905a67cSAndy Whitcroft				$len = length($blk);
7268905a67cSAndy Whitcroft				$line++;
7278905a67cSAndy Whitcroft				last;
7288905a67cSAndy Whitcroft			}
7298905a67cSAndy Whitcroft			# Bail if there is no further context.
7308905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
73113214adfSAndy Whitcroft			if ($off >= $len) {
7328905a67cSAndy Whitcroft				last;
7338905a67cSAndy Whitcroft			}
734f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
735f74bd194SAndy Whitcroft				$level++;
736f74bd194SAndy Whitcroft				$type = '#';
737f74bd194SAndy Whitcroft			}
7388905a67cSAndy Whitcroft		}
739cf655043SAndy Whitcroft		$p = $c;
7408905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
74113214adfSAndy Whitcroft		$remainder = substr($blk, $off);
7428905a67cSAndy Whitcroft
743773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
7444635f4fbSAndy Whitcroft
7454635f4fbSAndy Whitcroft		# Handle nested #if/#else.
7464635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
7474635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
7484635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
7494635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
7504635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
7514635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
7524635f4fbSAndy Whitcroft		}
7534635f4fbSAndy Whitcroft
7548905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
7558905a67cSAndy Whitcroft		# outermost level.
7568905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
7578905a67cSAndy Whitcroft			last;
7588905a67cSAndy Whitcroft		}
7598905a67cSAndy Whitcroft
76013214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
761773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
762773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
763773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
764773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
765773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
766773647a0SAndy Whitcroft			$coff_set = 1;
767773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
768773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
76913214adfSAndy Whitcroft		}
77013214adfSAndy Whitcroft
7718905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
7728905a67cSAndy Whitcroft			$level++;
7738905a67cSAndy Whitcroft			$type = '(';
7748905a67cSAndy Whitcroft		}
7758905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
7768905a67cSAndy Whitcroft			$level--;
7778905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
7788905a67cSAndy Whitcroft
7798905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
7808905a67cSAndy Whitcroft				$coff = $off;
781773647a0SAndy Whitcroft				$coff_set = 1;
782773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
7838905a67cSAndy Whitcroft			}
7848905a67cSAndy Whitcroft		}
7858905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
7868905a67cSAndy Whitcroft			$level++;
7878905a67cSAndy Whitcroft			$type = '{';
7888905a67cSAndy Whitcroft		}
7898905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
7908905a67cSAndy Whitcroft			$level--;
7918905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
7928905a67cSAndy Whitcroft
7938905a67cSAndy Whitcroft			if ($level == 0) {
794b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
795b998e001SPatrick Pannuto					$off++;
796b998e001SPatrick Pannuto				}
7978905a67cSAndy Whitcroft				last;
7988905a67cSAndy Whitcroft			}
7998905a67cSAndy Whitcroft		}
800f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
801f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
802f74bd194SAndy Whitcroft			$level--;
803f74bd194SAndy Whitcroft			$type = '';
804f74bd194SAndy Whitcroft			$off++;
805f74bd194SAndy Whitcroft			last;
806f74bd194SAndy Whitcroft		}
8078905a67cSAndy Whitcroft		$off++;
8088905a67cSAndy Whitcroft	}
809a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
81013214adfSAndy Whitcroft	if ($off == $len) {
811a3bb97a7SAndy Whitcroft		$loff = $len + 1;
81213214adfSAndy Whitcroft		$line++;
81313214adfSAndy Whitcroft		$remain--;
81413214adfSAndy Whitcroft	}
8158905a67cSAndy Whitcroft
8168905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
8178905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
8188905a67cSAndy Whitcroft
8198905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
8208905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
8218905a67cSAndy Whitcroft
822773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
82313214adfSAndy Whitcroft
82413214adfSAndy Whitcroft	return ($statement, $condition,
82513214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
82613214adfSAndy Whitcroft}
82713214adfSAndy Whitcroft
828cf655043SAndy Whitcroftsub statement_lines {
829cf655043SAndy Whitcroft	my ($stmt) = @_;
830cf655043SAndy Whitcroft
831cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
832cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
833cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
834cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
835cf655043SAndy Whitcroft
836cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
837cf655043SAndy Whitcroft
838cf655043SAndy Whitcroft	return $#stmt_lines + 2;
839cf655043SAndy Whitcroft}
840cf655043SAndy Whitcroft
841cf655043SAndy Whitcroftsub statement_rawlines {
842cf655043SAndy Whitcroft	my ($stmt) = @_;
843cf655043SAndy Whitcroft
844cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
845cf655043SAndy Whitcroft
846cf655043SAndy Whitcroft	return $#stmt_lines + 2;
847cf655043SAndy Whitcroft}
848cf655043SAndy Whitcroft
849cf655043SAndy Whitcroftsub statement_block_size {
850cf655043SAndy Whitcroft	my ($stmt) = @_;
851cf655043SAndy Whitcroft
852cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
853cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
854cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
855cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
856cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
857cf655043SAndy Whitcroft
858cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
859cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
860cf655043SAndy Whitcroft
861cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
862cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
863cf655043SAndy Whitcroft
864cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
865cf655043SAndy Whitcroft		return $stmt_lines;
866cf655043SAndy Whitcroft	} else {
867cf655043SAndy Whitcroft		return $stmt_statements;
868cf655043SAndy Whitcroft	}
869cf655043SAndy Whitcroft}
870cf655043SAndy Whitcroft
87113214adfSAndy Whitcroftsub ctx_statement_full {
87213214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
87313214adfSAndy Whitcroft	my ($statement, $condition, $level);
87413214adfSAndy Whitcroft
87513214adfSAndy Whitcroft	my (@chunks);
87613214adfSAndy Whitcroft
877cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
87813214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
87913214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
880773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
88113214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
882cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
883cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
884cf655043SAndy Whitcroft	}
885cf655043SAndy Whitcroft
886cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
887cf655043SAndy Whitcroft	# could continue the statement.
888cf655043SAndy Whitcroft	for (;;) {
88913214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
89013214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
891cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
892773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
893cf655043SAndy Whitcroft		#print "C: push\n";
894cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
89513214adfSAndy Whitcroft	}
89613214adfSAndy Whitcroft
89713214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
8988905a67cSAndy Whitcroft}
8998905a67cSAndy Whitcroft
9004a0df2efSAndy Whitcroftsub ctx_block_get {
901f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
9024a0df2efSAndy Whitcroft	my $line;
9034a0df2efSAndy Whitcroft	my $start = $linenr - 1;
9044a0df2efSAndy Whitcroft	my $blk = '';
9054a0df2efSAndy Whitcroft	my @o;
9064a0df2efSAndy Whitcroft	my @c;
9074a0df2efSAndy Whitcroft	my @res = ();
9084a0df2efSAndy Whitcroft
909f0a594c1SAndy Whitcroft	my $level = 0;
9104635f4fbSAndy Whitcroft	my @stack = ($level);
91100df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
91200df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
91300df344fSAndy Whitcroft		$remain--;
91400df344fSAndy Whitcroft
91500df344fSAndy Whitcroft		$blk .= $rawlines[$line];
9164635f4fbSAndy Whitcroft
9174635f4fbSAndy Whitcroft		# Handle nested #if/#else.
91801464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
9194635f4fbSAndy Whitcroft			push(@stack, $level);
92001464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
9214635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
92201464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
9234635f4fbSAndy Whitcroft			$level = pop(@stack);
9244635f4fbSAndy Whitcroft		}
9254635f4fbSAndy Whitcroft
92601464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
927f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
928f0a594c1SAndy Whitcroft			if ($off > 0) {
929f0a594c1SAndy Whitcroft				$off--;
930f0a594c1SAndy Whitcroft				next;
931f0a594c1SAndy Whitcroft			}
9324a0df2efSAndy Whitcroft
933f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
934f0a594c1SAndy Whitcroft				$level--;
935f0a594c1SAndy Whitcroft				last if ($level == 0);
936f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
937f0a594c1SAndy Whitcroft				$level++;
938f0a594c1SAndy Whitcroft			}
939f0a594c1SAndy Whitcroft		}
9404a0df2efSAndy Whitcroft
941f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
94200df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
9434a0df2efSAndy Whitcroft		}
9444a0df2efSAndy Whitcroft
945f0a594c1SAndy Whitcroft		last if ($level == 0);
9464a0df2efSAndy Whitcroft	}
9474a0df2efSAndy Whitcroft
948f0a594c1SAndy Whitcroft	return ($level, @res);
9494a0df2efSAndy Whitcroft}
9504a0df2efSAndy Whitcroftsub ctx_block_outer {
9514a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
9524a0df2efSAndy Whitcroft
953f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
954f0a594c1SAndy Whitcroft	return @r;
9554a0df2efSAndy Whitcroft}
9564a0df2efSAndy Whitcroftsub ctx_block {
9574a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
9584a0df2efSAndy Whitcroft
959f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
960f0a594c1SAndy Whitcroft	return @r;
961653d4876SAndy Whitcroft}
962653d4876SAndy Whitcroftsub ctx_statement {
963f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
964f0a594c1SAndy Whitcroft
965f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
966f0a594c1SAndy Whitcroft	return @r;
967f0a594c1SAndy Whitcroft}
968f0a594c1SAndy Whitcroftsub ctx_block_level {
969653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
970653d4876SAndy Whitcroft
971f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
9724a0df2efSAndy Whitcroft}
9739c0ca6f9SAndy Whitcroftsub ctx_statement_level {
9749c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
9759c0ca6f9SAndy Whitcroft
9769c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
9779c0ca6f9SAndy Whitcroft}
9784a0df2efSAndy Whitcroft
9794a0df2efSAndy Whitcroftsub ctx_locate_comment {
9804a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
9814a0df2efSAndy Whitcroft
9824a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
983beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
9844a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
9854a0df2efSAndy Whitcroft
9864a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
9874a0df2efSAndy Whitcroft	# comment.
9884a0df2efSAndy Whitcroft	my $in_comment = 0;
9894a0df2efSAndy Whitcroft	$current_comment = '';
9904a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
99100df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
99200df344fSAndy Whitcroft		#warn "           $line\n";
9934a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
9944a0df2efSAndy Whitcroft			$in_comment = 1;
9954a0df2efSAndy Whitcroft		}
9964a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
9974a0df2efSAndy Whitcroft			$in_comment = 1;
9984a0df2efSAndy Whitcroft		}
9994a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
10004a0df2efSAndy Whitcroft			$current_comment = '';
10014a0df2efSAndy Whitcroft		}
10024a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
10034a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
10044a0df2efSAndy Whitcroft			$in_comment = 0;
10054a0df2efSAndy Whitcroft		}
10064a0df2efSAndy Whitcroft	}
10074a0df2efSAndy Whitcroft
10084a0df2efSAndy Whitcroft	chomp($current_comment);
10094a0df2efSAndy Whitcroft	return($current_comment);
10104a0df2efSAndy Whitcroft}
10114a0df2efSAndy Whitcroftsub ctx_has_comment {
10124a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
10134a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
10144a0df2efSAndy Whitcroft
101500df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
10164a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
10174a0df2efSAndy Whitcroft
10184a0df2efSAndy Whitcroft	return ($cmt ne '');
10194a0df2efSAndy Whitcroft}
10204a0df2efSAndy Whitcroft
10214d001e4dSAndy Whitcroftsub raw_line {
10224d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
10234d001e4dSAndy Whitcroft
10244d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
10254d001e4dSAndy Whitcroft	$cnt++;
10264d001e4dSAndy Whitcroft
10274d001e4dSAndy Whitcroft	my $line;
10284d001e4dSAndy Whitcroft	while ($cnt) {
10294d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
10304d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
10314d001e4dSAndy Whitcroft		$cnt--;
10324d001e4dSAndy Whitcroft	}
10334d001e4dSAndy Whitcroft
10344d001e4dSAndy Whitcroft	return $line;
10354d001e4dSAndy Whitcroft}
10364d001e4dSAndy Whitcroft
10370a920b5bSAndy Whitcroftsub cat_vet {
10380a920b5bSAndy Whitcroft	my ($vet) = @_;
10399c0ca6f9SAndy Whitcroft	my ($res, $coded);
10400a920b5bSAndy Whitcroft
10419c0ca6f9SAndy Whitcroft	$res = '';
10426c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
10436c72ffaaSAndy Whitcroft		$res .= $1;
10446c72ffaaSAndy Whitcroft		if ($2 ne '') {
10459c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
10466c72ffaaSAndy Whitcroft			$res .= $coded;
10476c72ffaaSAndy Whitcroft		}
10489c0ca6f9SAndy Whitcroft	}
10499c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
10500a920b5bSAndy Whitcroft
10519c0ca6f9SAndy Whitcroft	return $res;
10520a920b5bSAndy Whitcroft}
10530a920b5bSAndy Whitcroft
1054c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1055cf655043SAndy Whitcroftmy $av_pending;
1056c2fdda0dSAndy Whitcroftmy @av_paren_type;
10571f65f947SAndy Whitcroftmy $av_pend_colon;
1058c2fdda0dSAndy Whitcroft
1059c2fdda0dSAndy Whitcroftsub annotate_reset {
1060c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1061cf655043SAndy Whitcroft	$av_pending = '_';
1062cf655043SAndy Whitcroft	@av_paren_type = ('E');
10631f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1064c2fdda0dSAndy Whitcroft}
1065c2fdda0dSAndy Whitcroft
10666c72ffaaSAndy Whitcroftsub annotate_values {
10676c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
10686c72ffaaSAndy Whitcroft
10696c72ffaaSAndy Whitcroft	my $res;
10701f65f947SAndy Whitcroft	my $var = '_' x length($stream);
10716c72ffaaSAndy Whitcroft	my $cur = $stream;
10726c72ffaaSAndy Whitcroft
1073c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
10746c72ffaaSAndy Whitcroft
10756c72ffaaSAndy Whitcroft	while (length($cur)) {
1076773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1077cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1078171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
10796c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1080c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1081c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1082cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1083c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
10846c72ffaaSAndy Whitcroft			}
10856c72ffaaSAndy Whitcroft
1086c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
10879446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
10889446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1089addcdceaSAndy Whitcroft			$type = 'c';
10909446ef56SAndy Whitcroft
1091e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1092c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
10936c72ffaaSAndy Whitcroft			$type = 'T';
10946c72ffaaSAndy Whitcroft
1095389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1096389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1097389a2fe5SAndy Whitcroft			$type = 'T';
1098389a2fe5SAndy Whitcroft
1099c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1100171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1101c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1102171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1103171ae1a4SAndy Whitcroft			if ($2 ne '') {
1104cf655043SAndy Whitcroft				$av_pending = 'N';
1105171ae1a4SAndy Whitcroft			}
1106171ae1a4SAndy Whitcroft			$type = 'E';
1107171ae1a4SAndy Whitcroft
1108c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1109171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1110171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1111171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
11126c72ffaaSAndy Whitcroft
1113c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1114cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1115c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1116cf655043SAndy Whitcroft
1117cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1118cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1119171ae1a4SAndy Whitcroft			$type = 'E';
1120cf655043SAndy Whitcroft
1121c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1122cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1123cf655043SAndy Whitcroft			$av_preprocessor = 1;
1124cf655043SAndy Whitcroft
1125cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1126cf655043SAndy Whitcroft
1127171ae1a4SAndy Whitcroft			$type = 'E';
1128cf655043SAndy Whitcroft
1129c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1130cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1131cf655043SAndy Whitcroft
1132cf655043SAndy Whitcroft			$av_preprocessor = 1;
1133cf655043SAndy Whitcroft
1134cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1135cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1136cf655043SAndy Whitcroft			pop(@av_paren_type);
1137cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1138171ae1a4SAndy Whitcroft			$type = 'E';
11396c72ffaaSAndy Whitcroft
11406c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1141c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
11426c72ffaaSAndy Whitcroft
1143171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1144171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1145171ae1a4SAndy Whitcroft			$av_pending = $type;
1146171ae1a4SAndy Whitcroft			$type = 'N';
1147171ae1a4SAndy Whitcroft
11486c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1149c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
11506c72ffaaSAndy Whitcroft			if (defined $2) {
1151cf655043SAndy Whitcroft				$av_pending = 'V';
11526c72ffaaSAndy Whitcroft			}
11536c72ffaaSAndy Whitcroft			$type = 'N';
11546c72ffaaSAndy Whitcroft
115514b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1156c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
115714b111c1SAndy Whitcroft			$av_pending = 'E';
11586c72ffaaSAndy Whitcroft			$type = 'N';
11596c72ffaaSAndy Whitcroft
11601f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
11611f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
11621f65f947SAndy Whitcroft			$av_pend_colon = 'C';
11631f65f947SAndy Whitcroft			$type = 'N';
11641f65f947SAndy Whitcroft
116514b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1166c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
11676c72ffaaSAndy Whitcroft			$type = 'N';
11686c72ffaaSAndy Whitcroft
11696c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1170c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1171cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1172cf655043SAndy Whitcroft			$av_pending = '_';
11736c72ffaaSAndy Whitcroft			$type = 'N';
11746c72ffaaSAndy Whitcroft
11756c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1176cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1177cf655043SAndy Whitcroft			if ($new_type ne '_') {
1178cf655043SAndy Whitcroft				$type = $new_type;
1179c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1180c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
11816c72ffaaSAndy Whitcroft			} else {
1182c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
11836c72ffaaSAndy Whitcroft			}
11846c72ffaaSAndy Whitcroft
1185c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1186c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1187c8cb2ca3SAndy Whitcroft			$type = 'V';
1188cf655043SAndy Whitcroft			$av_pending = 'V';
11896c72ffaaSAndy Whitcroft
11908e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
11918e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
11921f65f947SAndy Whitcroft				$av_pend_colon = 'B';
11938e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
11948e761b04SAndy Whitcroft				$av_pend_colon = 'L';
11951f65f947SAndy Whitcroft			}
11961f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
11971f65f947SAndy Whitcroft			$type = 'V';
11981f65f947SAndy Whitcroft
11996c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1200c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
12016c72ffaaSAndy Whitcroft			$type = 'V';
12026c72ffaaSAndy Whitcroft
12036c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1204c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
12056c72ffaaSAndy Whitcroft			$type = 'N';
12066c72ffaaSAndy Whitcroft
1207cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1208c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
120913214adfSAndy Whitcroft			$type = 'E';
12101f65f947SAndy Whitcroft			$av_pend_colon = 'O';
121113214adfSAndy Whitcroft
12128e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
12138e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
12148e761b04SAndy Whitcroft			$type = 'C';
12158e761b04SAndy Whitcroft
12161f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
12171f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
12181f65f947SAndy Whitcroft			$type = 'N';
12191f65f947SAndy Whitcroft
12201f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
12211f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
12221f65f947SAndy Whitcroft
12231f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
12241f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
12251f65f947SAndy Whitcroft				$type = 'E';
12261f65f947SAndy Whitcroft			} else {
12271f65f947SAndy Whitcroft				$type = 'N';
12281f65f947SAndy Whitcroft			}
12291f65f947SAndy Whitcroft			$av_pend_colon = 'O';
12301f65f947SAndy Whitcroft
12318e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
123213214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
12336c72ffaaSAndy Whitcroft			$type = 'N';
12346c72ffaaSAndy Whitcroft
12350d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
123674048ed8SAndy Whitcroft			my $variant;
123774048ed8SAndy Whitcroft
123874048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
123974048ed8SAndy Whitcroft			if ($type eq 'V') {
124074048ed8SAndy Whitcroft				$variant = 'B';
124174048ed8SAndy Whitcroft			} else {
124274048ed8SAndy Whitcroft				$variant = 'U';
124374048ed8SAndy Whitcroft			}
124474048ed8SAndy Whitcroft
124574048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
124674048ed8SAndy Whitcroft			$type = 'N';
124774048ed8SAndy Whitcroft
12486c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1249c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
12506c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
12516c72ffaaSAndy Whitcroft				$type = 'N';
12526c72ffaaSAndy Whitcroft			}
12536c72ffaaSAndy Whitcroft
12546c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1255c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
12566c72ffaaSAndy Whitcroft		}
12576c72ffaaSAndy Whitcroft		if (defined $1) {
12586c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
12596c72ffaaSAndy Whitcroft			$res .= $type x length($1);
12606c72ffaaSAndy Whitcroft		}
12616c72ffaaSAndy Whitcroft	}
12626c72ffaaSAndy Whitcroft
12631f65f947SAndy Whitcroft	return ($res, $var);
12646c72ffaaSAndy Whitcroft}
12656c72ffaaSAndy Whitcroft
12668905a67cSAndy Whitcroftsub possible {
126713214adfSAndy Whitcroft	my ($possible, $line) = @_;
12689a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
12690776e594SAndy Whitcroft		^(?:
12700776e594SAndy Whitcroft			$Modifier|
12710776e594SAndy Whitcroft			$Storage|
12720776e594SAndy Whitcroft			$Type|
12739a974fdbSAndy Whitcroft			DEFINE_\S+
12749a974fdbSAndy Whitcroft		)$|
12759a974fdbSAndy Whitcroft		^(?:
12760776e594SAndy Whitcroft			goto|
12770776e594SAndy Whitcroft			return|
12780776e594SAndy Whitcroft			case|
12790776e594SAndy Whitcroft			else|
12800776e594SAndy Whitcroft			asm|__asm__|
128189a88353SAndy Whitcroft			do|
128289a88353SAndy Whitcroft			\#|
128389a88353SAndy Whitcroft			\#\#|
12849a974fdbSAndy Whitcroft		)(?:\s|$)|
12850776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
12869a974fdbSAndy Whitcroft	    )}x;
12879a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
12889a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1289c45dcabdSAndy Whitcroft		# Check for modifiers.
1290c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1291c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1292c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1293c45dcabdSAndy Whitcroft
1294c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1295c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1296d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
12979a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1298d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1299d2506586SAndy Whitcroft					push(@modifierList, $modifier);
1300d2506586SAndy Whitcroft				}
13019a974fdbSAndy Whitcroft			}
1302c45dcabdSAndy Whitcroft
1303c45dcabdSAndy Whitcroft		} else {
130413214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
13058905a67cSAndy Whitcroft			push(@typeList, $possible);
1306c45dcabdSAndy Whitcroft		}
13078905a67cSAndy Whitcroft		build_types();
13080776e594SAndy Whitcroft	} else {
13090776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
13108905a67cSAndy Whitcroft	}
13118905a67cSAndy Whitcroft}
13128905a67cSAndy Whitcroft
13136c72ffaaSAndy Whitcroftmy $prefix = '';
13146c72ffaaSAndy Whitcroft
1315000d1cc1SJoe Perchessub show_type {
1316000d1cc1SJoe Perches       return !defined $ignore_type{$_[0]};
1317000d1cc1SJoe Perches}
1318000d1cc1SJoe Perches
1319f0a594c1SAndy Whitcroftsub report {
1320000d1cc1SJoe Perches	if (!show_type($_[1]) ||
1321000d1cc1SJoe Perches	    (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) {
1322773647a0SAndy Whitcroft		return 0;
1323773647a0SAndy Whitcroft	}
1324000d1cc1SJoe Perches	my $line;
1325000d1cc1SJoe Perches	if ($show_types) {
1326000d1cc1SJoe Perches		$line = "$prefix$_[0]:$_[1]: $_[2]\n";
1327000d1cc1SJoe Perches	} else {
1328000d1cc1SJoe Perches		$line = "$prefix$_[0]: $_[2]\n";
1329000d1cc1SJoe Perches	}
13308905a67cSAndy Whitcroft	$line = (split('\n', $line))[0] . "\n" if ($terse);
13318905a67cSAndy Whitcroft
133213214adfSAndy Whitcroft	push(our @report, $line);
1333773647a0SAndy Whitcroft
1334773647a0SAndy Whitcroft	return 1;
1335f0a594c1SAndy Whitcroft}
1336f0a594c1SAndy Whitcroftsub report_dump {
133713214adfSAndy Whitcroft	our @report;
1338f0a594c1SAndy Whitcroft}
1339000d1cc1SJoe Perches
1340de7d4f0eSAndy Whitcroftsub ERROR {
1341000d1cc1SJoe Perches	if (report("ERROR", $_[0], $_[1])) {
1342de7d4f0eSAndy Whitcroft		our $clean = 0;
13436c72ffaaSAndy Whitcroft		our $cnt_error++;
13443705ce5bSJoe Perches		return 1;
1345de7d4f0eSAndy Whitcroft	}
13463705ce5bSJoe Perches	return 0;
1347773647a0SAndy Whitcroft}
1348de7d4f0eSAndy Whitcroftsub WARN {
1349000d1cc1SJoe Perches	if (report("WARNING", $_[0], $_[1])) {
1350de7d4f0eSAndy Whitcroft		our $clean = 0;
13516c72ffaaSAndy Whitcroft		our $cnt_warn++;
13523705ce5bSJoe Perches		return 1;
1353de7d4f0eSAndy Whitcroft	}
13543705ce5bSJoe Perches	return 0;
1355773647a0SAndy Whitcroft}
1356de7d4f0eSAndy Whitcroftsub CHK {
1357000d1cc1SJoe Perches	if ($check && report("CHECK", $_[0], $_[1])) {
1358de7d4f0eSAndy Whitcroft		our $clean = 0;
13596c72ffaaSAndy Whitcroft		our $cnt_chk++;
13603705ce5bSJoe Perches		return 1;
13616c72ffaaSAndy Whitcroft	}
13623705ce5bSJoe Perches	return 0;
1363de7d4f0eSAndy Whitcroft}
1364de7d4f0eSAndy Whitcroft
13656ecd9674SAndy Whitcroftsub check_absolute_file {
13666ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
13676ecd9674SAndy Whitcroft	my $file = $absolute;
13686ecd9674SAndy Whitcroft
13696ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
13706ecd9674SAndy Whitcroft
13716ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
13726ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
13736ecd9674SAndy Whitcroft		if (-f "$root/$file") {
13746ecd9674SAndy Whitcroft			##print "file<$file>\n";
13756ecd9674SAndy Whitcroft			last;
13766ecd9674SAndy Whitcroft		}
13776ecd9674SAndy Whitcroft	}
13786ecd9674SAndy Whitcroft	if (! -f _)  {
13796ecd9674SAndy Whitcroft		return 0;
13806ecd9674SAndy Whitcroft	}
13816ecd9674SAndy Whitcroft
13826ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
13836ecd9674SAndy Whitcroft	my $prefix = $absolute;
13846ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
13856ecd9674SAndy Whitcroft
13866ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
13876ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
1388000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
1389000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
13906ecd9674SAndy Whitcroft	}
13916ecd9674SAndy Whitcroft}
13926ecd9674SAndy Whitcroft
13933705ce5bSJoe Perchessub trim {
13943705ce5bSJoe Perches	my ($string) = @_;
13953705ce5bSJoe Perches
13963705ce5bSJoe Perches	$string =~ s/(^\s+|\s+$)//g;
13973705ce5bSJoe Perches
13983705ce5bSJoe Perches	return $string;
13993705ce5bSJoe Perches}
14003705ce5bSJoe Perches
14013705ce5bSJoe Perchessub tabify {
14023705ce5bSJoe Perches	my ($leading) = @_;
14033705ce5bSJoe Perches
14043705ce5bSJoe Perches	my $source_indent = 8;
14053705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
14063705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
14073705ce5bSJoe Perches
14083705ce5bSJoe Perches	#convert leading spaces to tabs
14093705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
14103705ce5bSJoe Perches	#Remove spaces before a tab
14113705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
14123705ce5bSJoe Perches
14133705ce5bSJoe Perches	return "$leading";
14143705ce5bSJoe Perches}
14153705ce5bSJoe Perches
1416d1fe9c09SJoe Perchessub pos_last_openparen {
1417d1fe9c09SJoe Perches	my ($line) = @_;
1418d1fe9c09SJoe Perches
1419d1fe9c09SJoe Perches	my $pos = 0;
1420d1fe9c09SJoe Perches
1421d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
1422d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
1423d1fe9c09SJoe Perches
1424d1fe9c09SJoe Perches	my $last_openparen = 0;
1425d1fe9c09SJoe Perches
1426d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
1427d1fe9c09SJoe Perches		return -1;
1428d1fe9c09SJoe Perches	}
1429d1fe9c09SJoe Perches
1430d1fe9c09SJoe Perches	my $len = length($line);
1431d1fe9c09SJoe Perches
1432d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
1433d1fe9c09SJoe Perches		my $string = substr($line, $pos);
1434d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
1435d1fe9c09SJoe Perches			$pos += length($1) - 1;
1436d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
1437d1fe9c09SJoe Perches			$last_openparen = $pos;
1438d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
1439d1fe9c09SJoe Perches			last;
1440d1fe9c09SJoe Perches		}
1441d1fe9c09SJoe Perches	}
1442d1fe9c09SJoe Perches
1443d1fe9c09SJoe Perches	return $last_openparen + 1;
1444d1fe9c09SJoe Perches}
1445d1fe9c09SJoe Perches
14460a920b5bSAndy Whitcroftsub process {
14470a920b5bSAndy Whitcroft	my $filename = shift;
14480a920b5bSAndy Whitcroft
14490a920b5bSAndy Whitcroft	my $linenr=0;
14500a920b5bSAndy Whitcroft	my $prevline="";
1451c2fdda0dSAndy Whitcroft	my $prevrawline="";
14520a920b5bSAndy Whitcroft	my $stashline="";
1453c2fdda0dSAndy Whitcroft	my $stashrawline="";
14540a920b5bSAndy Whitcroft
14554a0df2efSAndy Whitcroft	my $length;
14560a920b5bSAndy Whitcroft	my $indent;
14570a920b5bSAndy Whitcroft	my $previndent=0;
14580a920b5bSAndy Whitcroft	my $stashindent=0;
14590a920b5bSAndy Whitcroft
1460de7d4f0eSAndy Whitcroft	our $clean = 1;
14610a920b5bSAndy Whitcroft	my $signoff = 0;
14620a920b5bSAndy Whitcroft	my $is_patch = 0;
14630a920b5bSAndy Whitcroft
146415662b3eSJoe Perches	my $in_header_lines = 1;
146515662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
146615662b3eSJoe Perches
1467fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
1468fa64205dSPasi Savanainen
146913214adfSAndy Whitcroft	our @report = ();
14706c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
14716c72ffaaSAndy Whitcroft	our $cnt_error = 0;
14726c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
14736c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
14746c72ffaaSAndy Whitcroft
14750a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
14760a920b5bSAndy Whitcroft	my $realfile = '';
14770a920b5bSAndy Whitcroft	my $realline = 0;
14780a920b5bSAndy Whitcroft	my $realcnt = 0;
14790a920b5bSAndy Whitcroft	my $here = '';
14800a920b5bSAndy Whitcroft	my $in_comment = 0;
1481c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
14820a920b5bSAndy Whitcroft	my $first_line = 0;
14831e855726SWolfram Sang	my $p1_prefix = '';
14840a920b5bSAndy Whitcroft
148513214adfSAndy Whitcroft	my $prev_values = 'E';
148613214adfSAndy Whitcroft
148713214adfSAndy Whitcroft	# suppression flags
1488773647a0SAndy Whitcroft	my %suppress_ifbraces;
1489170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
14902b474a1aSAndy Whitcroft	my %suppress_export;
14913e469cdcSAndy Whitcroft	my $suppress_statement = 0;
1492653d4876SAndy Whitcroft
1493323c1260SJoe Perches
1494c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
1495de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
1496c2fdda0dSAndy Whitcroft	#
1497de7d4f0eSAndy Whitcroft	my @setup_docs = ();
1498de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
1499773647a0SAndy Whitcroft
1500773647a0SAndy Whitcroft	sanitise_line_reset();
1501c2fdda0dSAndy Whitcroft	my $line;
1502c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
1503773647a0SAndy Whitcroft		$linenr++;
1504773647a0SAndy Whitcroft		$line = $rawline;
1505c2fdda0dSAndy Whitcroft
15063705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
15073705ce5bSJoe Perches
1508773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1509de7d4f0eSAndy Whitcroft			$setup_docs = 0;
1510de7d4f0eSAndy Whitcroft			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1511de7d4f0eSAndy Whitcroft				$setup_docs = 1;
1512de7d4f0eSAndy Whitcroft			}
1513773647a0SAndy Whitcroft			#next;
1514de7d4f0eSAndy Whitcroft		}
1515773647a0SAndy Whitcroft		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1516773647a0SAndy Whitcroft			$realline=$1-1;
1517773647a0SAndy Whitcroft			if (defined $2) {
1518773647a0SAndy Whitcroft				$realcnt=$3+1;
1519773647a0SAndy Whitcroft			} else {
1520773647a0SAndy Whitcroft				$realcnt=1+1;
1521773647a0SAndy Whitcroft			}
1522c45dcabdSAndy Whitcroft			$in_comment = 0;
1523773647a0SAndy Whitcroft
1524773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
1525773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
1526773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
1527773647a0SAndy Whitcroft			# at context start.
1528773647a0SAndy Whitcroft			my $edge;
152901fa9147SAndy Whitcroft			my $cnt = $realcnt;
153001fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
153101fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
153201fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
153301fa9147SAndy Whitcroft				$cnt--;
153401fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
1535721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
1536fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1537fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1538fae17daeSAndy Whitcroft					($edge) = $1;
1539fae17daeSAndy Whitcroft					last;
1540fae17daeSAndy Whitcroft				}
1541773647a0SAndy Whitcroft			}
1542773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
1543773647a0SAndy Whitcroft				$in_comment = 1;
1544773647a0SAndy Whitcroft			}
1545773647a0SAndy Whitcroft
1546773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
1547773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
1548773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
1549773647a0SAndy Whitcroft			if (!defined $edge &&
155083242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1551773647a0SAndy Whitcroft			{
1552773647a0SAndy Whitcroft				$in_comment = 1;
1553773647a0SAndy Whitcroft			}
1554773647a0SAndy Whitcroft
1555773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1556773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
1557773647a0SAndy Whitcroft
1558171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1559773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
1560171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
1561773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
1562773647a0SAndy Whitcroft		}
1563773647a0SAndy Whitcroft		push(@lines, $line);
1564773647a0SAndy Whitcroft
1565773647a0SAndy Whitcroft		if ($realcnt > 1) {
1566773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
1567773647a0SAndy Whitcroft		} else {
1568773647a0SAndy Whitcroft			$realcnt = 0;
1569773647a0SAndy Whitcroft		}
1570773647a0SAndy Whitcroft
1571773647a0SAndy Whitcroft		#print "==>$rawline\n";
1572773647a0SAndy Whitcroft		#print "-->$line\n";
1573de7d4f0eSAndy Whitcroft
1574de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
1575de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
1576de7d4f0eSAndy Whitcroft		}
1577de7d4f0eSAndy Whitcroft	}
1578de7d4f0eSAndy Whitcroft
15796c72ffaaSAndy Whitcroft	$prefix = '';
15806c72ffaaSAndy Whitcroft
1581773647a0SAndy Whitcroft	$realcnt = 0;
1582773647a0SAndy Whitcroft	$linenr = 0;
15830a920b5bSAndy Whitcroft	foreach my $line (@lines) {
15840a920b5bSAndy Whitcroft		$linenr++;
15850a920b5bSAndy Whitcroft
1586c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
15876c72ffaaSAndy Whitcroft
15880a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
15896c72ffaaSAndy Whitcroft		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
15900a920b5bSAndy Whitcroft			$is_patch = 1;
15914a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
15920a920b5bSAndy Whitcroft			$realline=$1-1;
15930a920b5bSAndy Whitcroft			if (defined $2) {
15940a920b5bSAndy Whitcroft				$realcnt=$3+1;
15950a920b5bSAndy Whitcroft			} else {
15960a920b5bSAndy Whitcroft				$realcnt=1+1;
15970a920b5bSAndy Whitcroft			}
1598c2fdda0dSAndy Whitcroft			annotate_reset();
159913214adfSAndy Whitcroft			$prev_values = 'E';
160013214adfSAndy Whitcroft
1601773647a0SAndy Whitcroft			%suppress_ifbraces = ();
1602170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
16032b474a1aSAndy Whitcroft			%suppress_export = ();
16043e469cdcSAndy Whitcroft			$suppress_statement = 0;
16050a920b5bSAndy Whitcroft			next;
16060a920b5bSAndy Whitcroft
16074a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
16084a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
16094a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
1610773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
16110a920b5bSAndy Whitcroft			$realline++;
1612d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
16130a920b5bSAndy Whitcroft
16144a0df2efSAndy Whitcroft			# Measure the line length and indent.
1615c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
16160a920b5bSAndy Whitcroft
16170a920b5bSAndy Whitcroft			# Track the previous line.
16180a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
16190a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
1620c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1621c2fdda0dSAndy Whitcroft
1622773647a0SAndy Whitcroft			#warn "line<$line>\n";
16236c72ffaaSAndy Whitcroft
1624d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
1625d8aaf121SAndy Whitcroft			$realcnt--;
16260a920b5bSAndy Whitcroft		}
16270a920b5bSAndy Whitcroft
1628cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
1629cc77cdcaSAndy Whitcroft
16300a920b5bSAndy Whitcroft#make up the handle for any error we report on this line
1631773647a0SAndy Whitcroft		$prefix = "$filename:$realline: " if ($emacs && $file);
1632773647a0SAndy Whitcroft		$prefix = "$filename:$linenr: " if ($emacs && !$file);
1633773647a0SAndy Whitcroft
16346c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
16356c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
1636773647a0SAndy Whitcroft
1637773647a0SAndy Whitcroft		# extract the filename as it passes
16383bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
16393bf9a009SRabin Vincent			$realfile = $1;
16403bf9a009SRabin Vincent			$realfile =~ s@^([^/]*)/@@;
1641270c49a0SJoe Perches			$in_commit_log = 0;
16423bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1643773647a0SAndy Whitcroft			$realfile = $1;
16441e855726SWolfram Sang			$realfile =~ s@^([^/]*)/@@;
1645270c49a0SJoe Perches			$in_commit_log = 0;
16461e855726SWolfram Sang
16471e855726SWolfram Sang			$p1_prefix = $1;
1648e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
1649e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
1650000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
1651000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
16521e855726SWolfram Sang			}
1653773647a0SAndy Whitcroft
1654c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
1655000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
1656000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1657773647a0SAndy Whitcroft			}
1658773647a0SAndy Whitcroft			next;
1659773647a0SAndy Whitcroft		}
1660773647a0SAndy Whitcroft
1661389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
16620a920b5bSAndy Whitcroft
1663c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
1664c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
1665c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
16660a920b5bSAndy Whitcroft
16676c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
16686c72ffaaSAndy Whitcroft
16693bf9a009SRabin Vincent# Check for incorrect file permissions
16703bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
16713bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
167204db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
167304db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
1674000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
1675000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
16763bf9a009SRabin Vincent			}
16773bf9a009SRabin Vincent		}
16783bf9a009SRabin Vincent
167920112475SJoe Perches# Check the patch for a signoff:
1680d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
16814a0df2efSAndy Whitcroft			$signoff++;
168215662b3eSJoe Perches			$in_commit_log = 0;
16830a920b5bSAndy Whitcroft		}
168420112475SJoe Perches
168520112475SJoe Perches# Check signature styles
1686270c49a0SJoe Perches		if (!$in_header_lines &&
1687ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
168820112475SJoe Perches			my $space_before = $1;
168920112475SJoe Perches			my $sign_off = $2;
169020112475SJoe Perches			my $space_after = $3;
169120112475SJoe Perches			my $email = $4;
169220112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
169320112475SJoe Perches
1694ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
1695ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
1696ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
1697ce0338dfSJoe Perches			}
169820112475SJoe Perches			if (defined $space_before && $space_before ne "") {
16993705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17003705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
17013705ce5bSJoe Perches				    $fix) {
17023705ce5bSJoe Perches					$fixed[$linenr - 1] =
17033705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17043705ce5bSJoe Perches				}
170520112475SJoe Perches			}
170620112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
17073705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17083705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
17093705ce5bSJoe Perches				    $fix) {
17103705ce5bSJoe Perches					$fixed[$linenr - 1] =
17113705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17123705ce5bSJoe Perches				}
17133705ce5bSJoe Perches
171420112475SJoe Perches			}
171520112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
17163705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17173705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
17183705ce5bSJoe Perches				    $fix) {
17193705ce5bSJoe Perches					$fixed[$linenr - 1] =
17203705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17213705ce5bSJoe Perches				}
172220112475SJoe Perches			}
172320112475SJoe Perches
172420112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
172520112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
172620112475SJoe Perches			if ($suggested_email eq "") {
1727000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
1728000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
172920112475SJoe Perches			} else {
173020112475SJoe Perches				my $dequoted = $suggested_email;
173120112475SJoe Perches				$dequoted =~ s/^"//;
173220112475SJoe Perches				$dequoted =~ s/" </ </;
173320112475SJoe Perches				# Don't force email to have quotes
173420112475SJoe Perches				# Allow just an angle bracketed address
173520112475SJoe Perches				if ("$dequoted$comment" ne $email &&
173620112475SJoe Perches				    "<$email_address>$comment" ne $email &&
173720112475SJoe Perches				    "$suggested_email$comment" ne $email) {
1738000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
1739000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
174020112475SJoe Perches				}
17410a920b5bSAndy Whitcroft			}
17420a920b5bSAndy Whitcroft		}
17430a920b5bSAndy Whitcroft
174400df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
17458905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1746000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
1747000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
17486c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
1749de7d4f0eSAndy Whitcroft		}
1750de7d4f0eSAndy Whitcroft
17516ecd9674SAndy Whitcroft# Check for absolute kernel paths.
17526ecd9674SAndy Whitcroft		if ($tree) {
17536ecd9674SAndy Whitcroft			while ($line =~ m{(?:^|\s)(/\S*)}g) {
17546ecd9674SAndy Whitcroft				my $file = $1;
17556ecd9674SAndy Whitcroft
17566ecd9674SAndy Whitcroft				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
17576ecd9674SAndy Whitcroft				    check_absolute_file($1, $herecurr)) {
17586ecd9674SAndy Whitcroft					#
17596ecd9674SAndy Whitcroft				} else {
17606ecd9674SAndy Whitcroft					check_absolute_file($file, $herecurr);
17616ecd9674SAndy Whitcroft				}
17626ecd9674SAndy Whitcroft			}
17636ecd9674SAndy Whitcroft		}
17646ecd9674SAndy Whitcroft
1765de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1766de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1767171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
1768171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1769171ae1a4SAndy Whitcroft
1770171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
1771171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1772171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
1773171ae1a4SAndy Whitcroft
177434d99219SJoe Perches			CHK("INVALID_UTF8",
1775000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
177600df344fSAndy Whitcroft		}
17770a920b5bSAndy Whitcroft
177815662b3eSJoe Perches# Check if it's the start of a commit log
177915662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
178015662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
1781270c49a0SJoe Perches		    $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
178215662b3eSJoe Perches			$in_header_lines = 0;
178315662b3eSJoe Perches			$in_commit_log = 1;
178415662b3eSJoe Perches		}
178515662b3eSJoe Perches
1786fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
1787fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
1788fa64205dSPasi Savanainen		if ($in_header_lines &&
1789fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
1790fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
1791fa64205dSPasi Savanainen			$non_utf8_charset = 1;
1792fa64205dSPasi Savanainen		}
1793fa64205dSPasi Savanainen
1794fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
179515662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
1796fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
179715662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
179815662b3eSJoe Perches		}
179915662b3eSJoe Perches
180030670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
180130670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
180200df344fSAndy Whitcroft
18030a920b5bSAndy Whitcroft#trailing whitespace
18049c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
1805c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1806000d1cc1SJoe Perches			ERROR("DOS_LINE_ENDINGS",
1807000d1cc1SJoe Perches			      "DOS line endings\n" . $herevet);
18089c0ca6f9SAndy Whitcroft
1809c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1810c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
18113705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
18123705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
18133705ce5bSJoe Perches			    $fix) {
18143705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*?)\s+$/$1/;
18153705ce5bSJoe Perches			}
18163705ce5bSJoe Perches
1817d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
18180a920b5bSAndy Whitcroft		}
18195368df20SAndy Whitcroft
18203354957aSAndi Kleen# check for Kconfig help text having a real description
18219fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
18229fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
18233354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
1824a1385803SAndy Whitcroft		    $line =~ /.\s*config\s+/) {
18253354957aSAndi Kleen			my $length = 0;
18269fe287d7SAndy Whitcroft			my $cnt = $realcnt;
18279fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
18289fe287d7SAndy Whitcroft			my $f;
1829a1385803SAndy Whitcroft			my $is_start = 0;
18309fe287d7SAndy Whitcroft			my $is_end = 0;
1831a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
18329fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
18339fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
18349fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
18359fe287d7SAndy Whitcroft
18369fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
1837a1385803SAndy Whitcroft
1838a1385803SAndy Whitcroft				if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) {
1839a1385803SAndy Whitcroft					$is_start = 1;
1840a1385803SAndy Whitcroft				} elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) {
1841a1385803SAndy Whitcroft					$length = -1;
1842a1385803SAndy Whitcroft				}
1843a1385803SAndy Whitcroft
18449fe287d7SAndy Whitcroft				$f =~ s/^.//;
18453354957aSAndi Kleen				$f =~ s/#.*//;
18463354957aSAndi Kleen				$f =~ s/^\s+//;
18473354957aSAndi Kleen				next if ($f =~ /^$/);
18489fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
18499fe287d7SAndy Whitcroft					$is_end = 1;
18509fe287d7SAndy Whitcroft					last;
18519fe287d7SAndy Whitcroft				}
18523354957aSAndi Kleen				$length++;
18533354957aSAndi Kleen			}
1854000d1cc1SJoe Perches			WARN("CONFIG_DESCRIPTION",
1855a1385803SAndy Whitcroft			     "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);
1856a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
18573354957aSAndi Kleen		}
18583354957aSAndi Kleen
18591ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
18601ba8dfd1SKees Cook		if ($realfile =~ /Kconfig/ &&
18611ba8dfd1SKees Cook		    $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
18621ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
18631ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
18641ba8dfd1SKees Cook		}
18651ba8dfd1SKees Cook
1866c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
1867c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
1868c68e5878SArnaud Lacombe			my $flag = $1;
1869c68e5878SArnaud Lacombe			my $replacement = {
1870c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
1871c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
1872c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
1873c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
1874c68e5878SArnaud Lacombe			};
1875c68e5878SArnaud Lacombe
1876c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
1877c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
1878c68e5878SArnaud Lacombe		}
1879c68e5878SArnaud Lacombe
18805368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
18815368df20SAndy Whitcroft		next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
18825368df20SAndy Whitcroft
18836cd7f386SJoe Perches#line length limit
1884c45dcabdSAndy Whitcroft		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1885f4c014c0SAndy Whitcroft		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
18860fccc622SJoe Perches		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
18878bbea968SJoe Perches		    $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
18886cd7f386SJoe Perches		    $length > $max_line_length)
1889c45dcabdSAndy Whitcroft		{
1890000d1cc1SJoe Perches			WARN("LONG_LINE",
18916cd7f386SJoe Perches			     "line over $max_line_length characters\n" . $herecurr);
18920a920b5bSAndy Whitcroft		}
18930a920b5bSAndy Whitcroft
1894ca56dc09SJosh Triplett# Check for user-visible strings broken across lines, which breaks the ability
1895ca56dc09SJosh Triplett# to grep for the string.  Limited to strings used as parameters (those
1896ca56dc09SJosh Triplett# following an open parenthesis), which almost completely eliminates false
1897ca56dc09SJosh Triplett# positives, as well as warning only once per parameter rather than once per
1898ca56dc09SJosh Triplett# line of the string.  Make an exception when the previous string ends in a
1899ca56dc09SJosh Triplett# newline (multiple lines in one string constant) or \n\t (common in inline
1900ca56dc09SJosh Triplett# assembly to indent the instruction on the following line).
1901ca56dc09SJosh Triplett		if ($line =~ /^\+\s*"/ &&
1902ca56dc09SJosh Triplett		    $prevline =~ /"\s*$/ &&
1903ca56dc09SJosh Triplett		    $prevline =~ /\(/ &&
1904ca56dc09SJosh Triplett		    $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
1905ca56dc09SJosh Triplett			WARN("SPLIT_STRING",
1906ca56dc09SJosh Triplett			     "quoted string split across lines\n" . $hereprev);
1907ca56dc09SJosh Triplett		}
1908ca56dc09SJosh Triplett
19095e79d96eSJoe Perches# check for spaces before a quoted newline
19105e79d96eSJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
19113705ce5bSJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
19123705ce5bSJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
19133705ce5bSJoe Perches			    $fix) {
19143705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
19153705ce5bSJoe Perches			}
19163705ce5bSJoe Perches
19175e79d96eSJoe Perches		}
19185e79d96eSJoe Perches
19198905a67cSAndy Whitcroft# check for adding lines without a newline.
19208905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1921000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
1922000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
19238905a67cSAndy Whitcroft		}
19248905a67cSAndy Whitcroft
192542e41c54SMike Frysinger# Blackfin: use hi/lo macros
192642e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
192742e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
192842e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1929000d1cc1SJoe Perches				ERROR("LO_MACRO",
1930000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
193142e41c54SMike Frysinger			}
193242e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
193342e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1934000d1cc1SJoe Perches				ERROR("HI_MACRO",
1935000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
193642e41c54SMike Frysinger			}
193742e41c54SMike Frysinger		}
193842e41c54SMike Frysinger
1939b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
1940b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c|pl)$/);
19410a920b5bSAndy Whitcroft
19420a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
19430a920b5bSAndy Whitcroft# more than 8 must use tabs.
1944c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
1945c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
1946c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1947d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
19483705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
19493705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
19503705ce5bSJoe Perches			    $fix) {
19513705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
19523705ce5bSJoe Perches			}
19530a920b5bSAndy Whitcroft		}
19540a920b5bSAndy Whitcroft
195508e44365SAlberto Panizzo# check for space before tabs.
195608e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
195708e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
19583705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
19593705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
19603705ce5bSJoe Perches			    $fix) {
19613705ce5bSJoe Perches				$fixed[$linenr - 1] =~
19623705ce5bSJoe Perches				    s/(^\+.*) +\t/$1\t/;
19633705ce5bSJoe Perches			}
196408e44365SAlberto Panizzo		}
196508e44365SAlberto Panizzo
1966d1fe9c09SJoe Perches# check for && or || at the start of a line
1967d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
1968d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
1969d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
1970d1fe9c09SJoe Perches		}
1971d1fe9c09SJoe Perches
1972d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
1973d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
1974d1fe9c09SJoe Perches		    $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
1975d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
1976d1fe9c09SJoe Perches			my $oldindent = $1;
1977d1fe9c09SJoe Perches			my $rest = $2;
1978d1fe9c09SJoe Perches
1979d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
1980d1fe9c09SJoe Perches			if ($pos >= 0) {
1981b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
1982b34a26f3SJoe Perches				my $newindent = $2;
1983d1fe9c09SJoe Perches
1984d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
1985d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
1986d1fe9c09SJoe Perches					" "  x ($pos % 8);
1987d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
1988d1fe9c09SJoe Perches
1989d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
1990d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
19913705ce5bSJoe Perches
19923705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
19933705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
19943705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
19953705ce5bSJoe Perches						$fixed[$linenr - 1] =~
19963705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
19973705ce5bSJoe Perches					}
1998d1fe9c09SJoe Perches				}
1999d1fe9c09SJoe Perches			}
2000d1fe9c09SJoe Perches		}
2001d1fe9c09SJoe Perches
200223f780c9SJoe Perches		if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
20033705ce5bSJoe Perches			if (CHK("SPACING",
20043705ce5bSJoe Perches				"No space is necessary after a cast\n" . $hereprev) &&
20053705ce5bSJoe Perches			    $fix) {
20063705ce5bSJoe Perches				$fixed[$linenr - 1] =~
20073705ce5bSJoe Perches				    s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
20083705ce5bSJoe Perches			}
2009aad4f614SJoe Perches		}
2010aad4f614SJoe Perches
201105880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2012fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
2013fdb4bcd6SJoe Perches		    $rawline =~ /^\+[ \t]*\*/) {
201405880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
201505880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
201605880600SJoe Perches		}
201705880600SJoe Perches
201805880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2019a605e32eSJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*
2020a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
2021a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
2022a605e32eSJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2023a605e32eSJoe Perches			     "networking block comments start with * on subsequent lines\n" . $hereprev);
2024a605e32eSJoe Perches		}
2025a605e32eSJoe Perches
2026a605e32eSJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2027c24f9f19SJoe Perches		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
2028c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
2029c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
2030c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
203105880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
203205880600SJoe Perches			     "networking block comments put the trailing */ on a separate line\n" . $herecurr);
203305880600SJoe Perches		}
203405880600SJoe Perches
20355f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
20366b4c5bebSAndy Whitcroft# Exceptions:
20376b4c5bebSAndy Whitcroft#  1) within comments
20386b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
20396b4c5bebSAndy Whitcroft#  3) hanging labels
20403705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
20415f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
20423705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
20433705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
20443705ce5bSJoe Perches			    $fix) {
20453705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
20463705ce5bSJoe Perches			}
20475f7ddae6SRaffaele Recalcati		}
20485f7ddae6SRaffaele Recalcati
2049b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
2050b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
2051b9ea10d6SAndy Whitcroft
20521ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
20531ba8dfd1SKees Cook		if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
20541ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
20551ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
20561ba8dfd1SKees Cook		}
20571ba8dfd1SKees Cook
2058c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
2059cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2060000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
2061000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2062c2fdda0dSAndy Whitcroft		}
206322f2a2efSAndy Whitcroft
206442e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
206542e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
206642e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2067000d1cc1SJoe Perches			ERROR("CSYNC",
2068000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
206942e41c54SMike Frysinger		}
207042e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
207142e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2072000d1cc1SJoe Perches			ERROR("SSYNC",
2073000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
207442e41c54SMike Frysinger		}
207542e41c54SMike Frysinger
207656e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
207756e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
207856e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
207956e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
208056e77d70SJoe Perches		}
208156e77d70SJoe Perches
20829c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
20832b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
20842b474a1aSAndy Whitcroft		    $realline_next);
20853e469cdcSAndy Whitcroft#print "LINE<$line>\n";
20863e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
20873e469cdcSAndy Whitcroft		    $realcnt && $line =~ /.\s*\S/) {
2088170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2089f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
2090171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
2091171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
2092171ae1a4SAndy Whitcroft
20933e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
20943e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
20953e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
20963e469cdcSAndy Whitcroft			# until we hit end of it.
20973e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
20983e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
20993e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
21003e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
21013e469cdcSAndy Whitcroft			}
2102f74bd194SAndy Whitcroft
21032b474a1aSAndy Whitcroft			# Find the real next line.
21042b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
21052b474a1aSAndy Whitcroft			if (defined $realline_next &&
21062b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
21072b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
21082b474a1aSAndy Whitcroft				$realline_next++;
21092b474a1aSAndy Whitcroft			}
21102b474a1aSAndy Whitcroft
2111171ae1a4SAndy Whitcroft			my $s = $stat;
2112171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
2113cf655043SAndy Whitcroft
2114c2fdda0dSAndy Whitcroft			# Ignore goto labels.
2115171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
2116c2fdda0dSAndy Whitcroft
2117c2fdda0dSAndy Whitcroft			# Ignore functions being called
2118171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2119c2fdda0dSAndy Whitcroft
2120463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
2121463f2864SAndy Whitcroft
2122c45dcabdSAndy Whitcroft			# declarations always start with types
2123d2506586SAndy Whitcroft			} elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) {
2124c45dcabdSAndy Whitcroft				my $type = $1;
2125c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
2126c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
2127c45dcabdSAndy Whitcroft
21286c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
2129a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2130c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
2131c2fdda0dSAndy Whitcroft			}
21328905a67cSAndy Whitcroft
21336c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
213465863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2135c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
21369c0ca6f9SAndy Whitcroft			}
21378905a67cSAndy Whitcroft
21388905a67cSAndy Whitcroft			# Check for any sort of function declaration.
21398905a67cSAndy Whitcroft			# int foo(something bar, other baz);
21408905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
2141171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
21428905a67cSAndy Whitcroft				my ($name_len) = length($1);
21438905a67cSAndy Whitcroft
2144cf655043SAndy Whitcroft				my $ctx = $s;
2145773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
21468905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
2147cf655043SAndy Whitcroft
21488905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
2149c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
21508905a67cSAndy Whitcroft
2151c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
21528905a67cSAndy Whitcroft					}
21538905a67cSAndy Whitcroft				}
21548905a67cSAndy Whitcroft			}
21558905a67cSAndy Whitcroft
21569c0ca6f9SAndy Whitcroft		}
21579c0ca6f9SAndy Whitcroft
215800df344fSAndy Whitcroft#
215900df344fSAndy Whitcroft# Checks which may be anchored in the context.
216000df344fSAndy Whitcroft#
216100df344fSAndy Whitcroft
216200df344fSAndy Whitcroft# Check for switch () and associated case and default
216300df344fSAndy Whitcroft# statements should be at the same indent.
216400df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
216500df344fSAndy Whitcroft			my $err = '';
216600df344fSAndy Whitcroft			my $sep = '';
216700df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
216800df344fSAndy Whitcroft			shift(@ctx);
216900df344fSAndy Whitcroft			for my $ctx (@ctx) {
217000df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
217100df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
217200df344fSAndy Whitcroft							$indent != $cindent) {
217300df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
217400df344fSAndy Whitcroft					$sep = '';
217500df344fSAndy Whitcroft				} else {
217600df344fSAndy Whitcroft					$sep = "[...]\n";
217700df344fSAndy Whitcroft				}
217800df344fSAndy Whitcroft			}
217900df344fSAndy Whitcroft			if ($err ne '') {
2180000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
2181000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
2182de7d4f0eSAndy Whitcroft			}
2183de7d4f0eSAndy Whitcroft		}
2184de7d4f0eSAndy Whitcroft
2185de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
2186de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
2187c45dcabdSAndy Whitcroft		if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2188773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
2189773647a0SAndy Whitcroft
21909c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
21918eef05ddSJoe Perches
21928eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
21938eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
21948eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
21958eef05ddSJoe Perches			}
21968eef05ddSJoe Perches
2197de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
2198de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
2199de7d4f0eSAndy Whitcroft
2200548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
2201548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
2202de7d4f0eSAndy Whitcroft
2203548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2204548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
2205548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
2206548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2207548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2208773647a0SAndy Whitcroft				$ctx_ln++;
2209773647a0SAndy Whitcroft			}
2210548596d5SAndy Whitcroft
221153210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
221253210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2213773647a0SAndy Whitcroft
2214773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2215000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
2216000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
221701464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
221800df344fSAndy Whitcroft			}
2219773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2220773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
2221773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
2222773647a0SAndy Whitcroft			{
22239c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
22249c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
2225000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
2226000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
222701464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
22289c0ca6f9SAndy Whitcroft				}
22299c0ca6f9SAndy Whitcroft			}
223000df344fSAndy Whitcroft		}
223100df344fSAndy Whitcroft
22324d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
22334d001e4dSAndy Whitcroft		if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
22343e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
22353e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
22363e469cdcSAndy Whitcroft					if (!defined $stat);
22374d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
22384d001e4dSAndy Whitcroft
22394d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
22404d001e4dSAndy Whitcroft
22414d001e4dSAndy Whitcroft			# Make sure we remove the line prefixes as we have
22424d001e4dSAndy Whitcroft			# none on the first line, and are going to readd them
22434d001e4dSAndy Whitcroft			# where necessary.
22444d001e4dSAndy Whitcroft			$s =~ s/\n./\n/gs;
22454d001e4dSAndy Whitcroft
22464d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
22476f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
22486f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
22494d001e4dSAndy Whitcroft
22504d001e4dSAndy Whitcroft			# We want to check the first line inside the block
22514d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
22524d001e4dSAndy Whitcroft			#  1) any blank line termination
22534d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
22544d001e4dSAndy Whitcroft			#  3) any do (...) {
22554d001e4dSAndy Whitcroft			my $continuation = 0;
22564d001e4dSAndy Whitcroft			my $check = 0;
22574d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
22584d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
22594d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
22604d001e4dSAndy Whitcroft				$continuation = 1;
22614d001e4dSAndy Whitcroft			}
22629bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
22634d001e4dSAndy Whitcroft				$check = 1;
22644d001e4dSAndy Whitcroft				$cond_lines++;
22654d001e4dSAndy Whitcroft			}
22664d001e4dSAndy Whitcroft
22674d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
22684d001e4dSAndy Whitcroft			# preprocessor statement.
22694d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
22704d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
22714d001e4dSAndy Whitcroft				$check = 0;
22724d001e4dSAndy Whitcroft			}
22734d001e4dSAndy Whitcroft
22749bd49efeSAndy Whitcroft			my $cond_ptr = -1;
2275740504c6SAndy Whitcroft			$continuation = 0;
22769bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
22779bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
22784d001e4dSAndy Whitcroft
2279f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
2280f16fa28fSAndy Whitcroft				# is not linear.
2281f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2282f16fa28fSAndy Whitcroft					$check = 0;
2283f16fa28fSAndy Whitcroft				}
2284f16fa28fSAndy Whitcroft
22859bd49efeSAndy Whitcroft				# Ignore:
22869bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
22879bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
22889bd49efeSAndy Whitcroft				#  3) labels.
2289740504c6SAndy Whitcroft				if ($continuation ||
2290740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
22919bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
22929bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
2293740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
229430dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
22959bd49efeSAndy Whitcroft						$cond_lines++;
22969bd49efeSAndy Whitcroft					}
22974d001e4dSAndy Whitcroft				}
229830dad6ebSAndy Whitcroft			}
22994d001e4dSAndy Whitcroft
23004d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
23014d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
23024d001e4dSAndy Whitcroft
23034d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
23044d001e4dSAndy Whitcroft			# this is not this patch's fault.
23054d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
23064d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
23074d001e4dSAndy Whitcroft				$check = 0;
23084d001e4dSAndy Whitcroft			}
23094d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
23104d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
23114d001e4dSAndy Whitcroft			}
23124d001e4dSAndy Whitcroft
23139bd49efeSAndy Whitcroft			#print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
23144d001e4dSAndy Whitcroft
23154d001e4dSAndy Whitcroft			if ($check && (($sindent % 8) != 0 ||
23164d001e4dSAndy Whitcroft			    ($sindent <= $indent && $s ne ''))) {
2317000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
2318000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
23194d001e4dSAndy Whitcroft			}
23204d001e4dSAndy Whitcroft		}
23214d001e4dSAndy Whitcroft
23226c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
23236c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
23241f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
23251f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
23266c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
2327c2fdda0dSAndy Whitcroft		if ($dbg_values) {
2328c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
2329cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
2330cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
23311f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
2332c2fdda0dSAndy Whitcroft		}
23336c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
23346c72ffaaSAndy Whitcroft
233500df344fSAndy Whitcroft#ignore lines not being added
23363705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
233700df344fSAndy Whitcroft
2338653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
23397429c690SAndy Whitcroft		if ($dbg_type) {
23407429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
2341000d1cc1SJoe Perches				ERROR("TEST_TYPE",
2342000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
23437429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
2344000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
2345000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
23467429c690SAndy Whitcroft			}
2347653d4876SAndy Whitcroft			next;
2348653d4876SAndy Whitcroft		}
2349a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
2350a1ef277eSAndy Whitcroft		if ($dbg_attr) {
23519360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
2352000d1cc1SJoe Perches				ERROR("TEST_ATTR",
2353000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
23549360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
2355000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
2356000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
2357a1ef277eSAndy Whitcroft			}
2358a1ef277eSAndy Whitcroft			next;
2359a1ef277eSAndy Whitcroft		}
2360653d4876SAndy Whitcroft
2361f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
236299423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
236399423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
2364000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2365000d1cc1SJoe Perches			      "that open brace { should be on the previous line\n" . $hereprev);
2366f0a594c1SAndy Whitcroft		}
2367f0a594c1SAndy Whitcroft
236800df344fSAndy Whitcroft#
236900df344fSAndy Whitcroft# Checks which are anchored on the added line.
237000df344fSAndy Whitcroft#
237100df344fSAndy Whitcroft
2372653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
2373c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
2374653d4876SAndy Whitcroft			my $path = $1;
2375653d4876SAndy Whitcroft			if ($path =~ m{//}) {
2376000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
2377495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
2378495e9d84SJoe Perches			}
2379495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
2380495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
2381495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
2382653d4876SAndy Whitcroft			}
2383653d4876SAndy Whitcroft		}
2384653d4876SAndy Whitcroft
238500df344fSAndy Whitcroft# no C99 // comments
238600df344fSAndy Whitcroft		if ($line =~ m{//}) {
23873705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
23883705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
23893705ce5bSJoe Perches			    $fix) {
23903705ce5bSJoe Perches				my $line = $fixed[$linenr - 1];
23913705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
23923705ce5bSJoe Perches					my $comment = trim($1);
23933705ce5bSJoe Perches					$fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
23943705ce5bSJoe Perches				}
23953705ce5bSJoe Perches			}
239600df344fSAndy Whitcroft		}
239700df344fSAndy Whitcroft		# Remove C99 comments.
23980a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
23996c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
24000a920b5bSAndy Whitcroft
24012b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
24022b474a1aSAndy Whitcroft# the whole statement.
24032b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
24042b474a1aSAndy Whitcroft		if (defined $realline_next &&
24052b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
24062b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
24072b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
24082b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
24093cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
24103cbf62dfSAndy Whitcroft			# a prefix:
24113cbf62dfSAndy Whitcroft			#   XXX(foo);
24123cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
2413653d4876SAndy Whitcroft			my $name = $1;
241487a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
24153cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
24163cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
24173cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
24183cbf62dfSAndy Whitcroft
24193cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
24202b474a1aSAndy Whitcroft				\n.}\s*$|
242148012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
242248012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
242348012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
24242b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
24252b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
242648012058SAndy Whitcroft			    )/x) {
24272b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
24282b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
24292b474a1aSAndy Whitcroft			} else {
24302b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
24310a920b5bSAndy Whitcroft			}
24320a920b5bSAndy Whitcroft		}
24332b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
24342b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
24352b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
24362b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
24372b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
24382b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
24392b474a1aSAndy Whitcroft		}
24402b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
24412b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
2442000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
2443000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
24442b474a1aSAndy Whitcroft		}
24450a920b5bSAndy Whitcroft
24465150bda4SJoe Eloff# check for global initialisers.
2447c45dcabdSAndy Whitcroft		if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
2448000d1cc1SJoe Perches			ERROR("GLOBAL_INITIALISERS",
2449000d1cc1SJoe Perches			      "do not initialise globals to 0 or NULL\n" .
2450f0a594c1SAndy Whitcroft				$herecurr);
2451f0a594c1SAndy Whitcroft		}
24520a920b5bSAndy Whitcroft# check for static initialisers.
24532d1bafd7SAndy Whitcroft		if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
2454000d1cc1SJoe Perches			ERROR("INITIALISED_STATIC",
2455000d1cc1SJoe Perches			      "do not initialise statics to 0 or NULL\n" .
2456de7d4f0eSAndy Whitcroft				$herecurr);
24570a920b5bSAndy Whitcroft		}
24580a920b5bSAndy Whitcroft
2459cb710ecaSJoe Perches# check for static const char * arrays.
2460cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
2461000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2462000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
2463cb710ecaSJoe Perches				$herecurr);
2464cb710ecaSJoe Perches               }
2465cb710ecaSJoe Perches
2466cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
2467cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
2468000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2469000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
2470cb710ecaSJoe Perches				$herecurr);
2471cb710ecaSJoe Perches               }
2472cb710ecaSJoe Perches
247393ed0e2dSJoe Perches# check for declarations of struct pci_device_id
247493ed0e2dSJoe Perches		if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
2475000d1cc1SJoe Perches			WARN("DEFINE_PCI_DEVICE_TABLE",
2476000d1cc1SJoe Perches			     "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
247793ed0e2dSJoe Perches		}
247893ed0e2dSJoe Perches
2479653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
2480653d4876SAndy Whitcroft# make sense.
2481653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
24828054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
2483c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
24848ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
2485653d4876SAndy Whitcroft		    $line !~ /\b__bitwise(?:__|)\b/) {
2486000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
2487000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
24880a920b5bSAndy Whitcroft		}
24890a920b5bSAndy Whitcroft
24900a920b5bSAndy Whitcroft# * goes on variable not on type
249165863862SAndy Whitcroft		# (char*[ const])
2492bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
2493bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
24943705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
2495d8aaf121SAndy Whitcroft
249665863862SAndy Whitcroft			# Should start with a space.
249765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
249865863862SAndy Whitcroft			# Should not end with a space.
249965863862SAndy Whitcroft			$to =~ s/\s+$//;
250065863862SAndy Whitcroft			# '*'s should not have spaces between.
2501f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
250265863862SAndy Whitcroft			}
2503d8aaf121SAndy Whitcroft
25043705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
250565863862SAndy Whitcroft			if ($from ne $to) {
25063705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
25073705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
25083705ce5bSJoe Perches				    $fix) {
25093705ce5bSJoe Perches					my $sub_from = $ident;
25103705ce5bSJoe Perches					my $sub_to = $ident;
25113705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
25123705ce5bSJoe Perches					$fixed[$linenr - 1] =~
25133705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
25143705ce5bSJoe Perches				}
251565863862SAndy Whitcroft			}
2516bfcb2cc7SAndy Whitcroft		}
2517bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
2518bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
25193705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
2520d8aaf121SAndy Whitcroft
252165863862SAndy Whitcroft			# Should start with a space.
252265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
252365863862SAndy Whitcroft			# Should not end with a space.
252465863862SAndy Whitcroft			$to =~ s/\s+$//;
252565863862SAndy Whitcroft			# '*'s should not have spaces between.
2526f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
252765863862SAndy Whitcroft			}
252865863862SAndy Whitcroft			# Modifiers should have spaces.
252965863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
253065863862SAndy Whitcroft
25313705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
2532667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
25333705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
25343705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
25353705ce5bSJoe Perches				    $fix) {
25363705ce5bSJoe Perches
25373705ce5bSJoe Perches					my $sub_from = $match;
25383705ce5bSJoe Perches					my $sub_to = $match;
25393705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
25403705ce5bSJoe Perches					$fixed[$linenr - 1] =~
25413705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
25423705ce5bSJoe Perches				}
254365863862SAndy Whitcroft			}
25440a920b5bSAndy Whitcroft		}
25450a920b5bSAndy Whitcroft
25460a920b5bSAndy Whitcroft# # no BUG() or BUG_ON()
25470a920b5bSAndy Whitcroft# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {
25480a920b5bSAndy Whitcroft# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
25490a920b5bSAndy Whitcroft# 			print "$herecurr";
25500a920b5bSAndy Whitcroft# 			$clean = 0;
25510a920b5bSAndy Whitcroft# 		}
25520a920b5bSAndy Whitcroft
25538905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
2554000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
2555000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
25568905a67cSAndy Whitcroft		}
25578905a67cSAndy Whitcroft
255817441227SJoe Perches# check for uses of printk_ratelimit
255917441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
2560000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
2561000d1cc1SJoe Perches"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
256217441227SJoe Perches		}
256317441227SJoe Perches
256400df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
256500df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
256600df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
256725985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
256800df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
2569f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
257000df344fSAndy Whitcroft			my $ok = 0;
257100df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
257200df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
257325985edcSLucas De Marchi				# we have a preceding printk if it ends
257400df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
257500df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
257600df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
257700df344fSAndy Whitcroft						$ok = 1;
257800df344fSAndy Whitcroft					}
257900df344fSAndy Whitcroft					last;
258000df344fSAndy Whitcroft				}
258100df344fSAndy Whitcroft			}
258200df344fSAndy Whitcroft			if ($ok == 0) {
2583000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
2584000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
25850a920b5bSAndy Whitcroft			}
258600df344fSAndy Whitcroft		}
25870a920b5bSAndy Whitcroft
2588243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
2589243f3803SJoe Perches			my $orig = $1;
2590243f3803SJoe Perches			my $level = lc($orig);
2591243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
25928f26b837SJoe Perches			my $level2 = $level;
25938f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
2594243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
25958f26b837SJoe Perches			     "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
2596243f3803SJoe Perches		}
2597243f3803SJoe Perches
2598243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
2599243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
2600243f3803SJoe Perches			     "Prefer pr_warn(... to pr_warning(...\n" . $herecurr);
2601243f3803SJoe Perches		}
2602243f3803SJoe Perches
2603dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
2604dc139313SJoe Perches			my $orig = $1;
2605dc139313SJoe Perches			my $level = lc($orig);
2606dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
2607dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
2608dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
2609dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
2610dc139313SJoe Perches		}
2611dc139313SJoe Perches
2612653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
2613653d4876SAndy Whitcroft# or if closed on same line
2614c45dcabdSAndy Whitcroft		if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
2615c45dcabdSAndy Whitcroft		    !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
2616000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2617000d1cc1SJoe Perches			      "open brace '{' following function declarations go on the next line\n" . $herecurr);
26180a920b5bSAndy Whitcroft		}
2619653d4876SAndy Whitcroft
26208905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
26218905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
26228905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2623000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2624000d1cc1SJoe Perches			      "open brace '{' following $1 go on the same line\n" . $hereprev);
26258905a67cSAndy Whitcroft		}
26268905a67cSAndy Whitcroft
26270c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
26283705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
26293705ce5bSJoe Perches			if (WARN("SPACING",
26303705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
26313705ce5bSJoe Perches			    $fix) {
26323705ce5bSJoe Perches				$fixed[$linenr - 1] =~
26333705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
26343705ce5bSJoe Perches			}
26350c73b4ebSAndy Whitcroft		}
26360c73b4ebSAndy Whitcroft
26378d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
26388d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
2639fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2640fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
26418d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
26428d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
26438d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
2644fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
2645daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
26463705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
26473705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
26483705ce5bSJoe Perches				    $fix) {
26493705ce5bSJoe Perches				    $fixed[$linenr - 1] =~
26503705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
26513705ce5bSJoe Perches				}
26528d31cfceSAndy Whitcroft			}
26538d31cfceSAndy Whitcroft		}
26548d31cfceSAndy Whitcroft
2655f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
26566c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
2657c2fdda0dSAndy Whitcroft			my $name = $1;
2658773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
2659773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
2660c2fdda0dSAndy Whitcroft
2661c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
2662773647a0SAndy Whitcroft			if ($name =~ /^(?:
2663773647a0SAndy Whitcroft				if|for|while|switch|return|case|
2664773647a0SAndy Whitcroft				volatile|__volatile__|
2665773647a0SAndy Whitcroft				__attribute__|format|__extension__|
2666773647a0SAndy Whitcroft				asm|__asm__)$/x)
2667773647a0SAndy Whitcroft			{
2668c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
2669c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
2670c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
2671c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
2672773647a0SAndy Whitcroft
2673773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
2674c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
2675c2fdda0dSAndy Whitcroft
2676c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
2677c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
2678773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
2679c2fdda0dSAndy Whitcroft
2680c2fdda0dSAndy Whitcroft			} else {
26813705ce5bSJoe Perches				if (WARN("SPACING",
26823705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
26833705ce5bSJoe Perches					     $fix) {
26843705ce5bSJoe Perches					$fixed[$linenr - 1] =~
26853705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
26863705ce5bSJoe Perches				}
2687f0a594c1SAndy Whitcroft			}
26886c72ffaaSAndy Whitcroft		}
26899a4cad4eSEric Nelson
2690653d4876SAndy Whitcroft# Check operator spacing.
26910a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
26923705ce5bSJoe Perches			my $fixed_line = "";
26933705ce5bSJoe Perches			my $line_fixed = 0;
26943705ce5bSJoe Perches
26959c0ca6f9SAndy Whitcroft			my $ops = qr{
26969c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
26979c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
26989c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
26991f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
27001f65f947SAndy Whitcroft				\?|:
27019c0ca6f9SAndy Whitcroft			}x;
2702cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
27033705ce5bSJoe Perches
27043705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
27053705ce5bSJoe Perches##			foreach my $el (@elements) {
27063705ce5bSJoe Perches##				print("el: <$el>\n");
27073705ce5bSJoe Perches##			}
27083705ce5bSJoe Perches
27093705ce5bSJoe Perches			my @fix_elements = ();
271000df344fSAndy Whitcroft			my $off = 0;
27116c72ffaaSAndy Whitcroft
27123705ce5bSJoe Perches			foreach my $el (@elements) {
27133705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
27143705ce5bSJoe Perches				$off += length($el);
27153705ce5bSJoe Perches			}
27163705ce5bSJoe Perches
27173705ce5bSJoe Perches			$off = 0;
27183705ce5bSJoe Perches
27196c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
27206c72ffaaSAndy Whitcroft
27210a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
27223705ce5bSJoe Perches
27233705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
27243705ce5bSJoe Perches
27253705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
27263705ce5bSJoe Perches
27274a0df2efSAndy Whitcroft				$off += length($elements[$n]);
27284a0df2efSAndy Whitcroft
272925985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
2730773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
2731773647a0SAndy Whitcroft				my $cc = '';
2732773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
2733773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
2734773647a0SAndy Whitcroft				}
2735773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
2736773647a0SAndy Whitcroft
27374a0df2efSAndy Whitcroft				my $a = '';
27384a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
27394a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
2740cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
27414a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
27424a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
2743773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
27444a0df2efSAndy Whitcroft
27450a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
27464a0df2efSAndy Whitcroft
27474a0df2efSAndy Whitcroft				my $c = '';
27480a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
27494a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
27504a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
2751cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
27524a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
27534a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
27548b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
27554a0df2efSAndy Whitcroft				} else {
27564a0df2efSAndy Whitcroft					$c = 'E';
27570a920b5bSAndy Whitcroft				}
27580a920b5bSAndy Whitcroft
27594a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
27604a0df2efSAndy Whitcroft
27614a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
27624a0df2efSAndy Whitcroft
27636c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
2764de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
27650a920b5bSAndy Whitcroft
276674048ed8SAndy Whitcroft				# Pull out the value of this operator.
27676c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
27680a920b5bSAndy Whitcroft
27691f65f947SAndy Whitcroft				# Get the full operator variant.
27701f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
27711f65f947SAndy Whitcroft
277213214adfSAndy Whitcroft				# Ignore operators passed as parameters.
277313214adfSAndy Whitcroft				if ($op_type ne 'V' &&
277413214adfSAndy Whitcroft				    $ca =~ /\s$/ && $cc =~ /^\s*,/) {
277513214adfSAndy Whitcroft
2776cf655043SAndy Whitcroft#				# Ignore comments
2777cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
277813214adfSAndy Whitcroft
2779d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
278013214adfSAndy Whitcroft				} elsif ($op eq ';') {
2781cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
2782cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
27833705ce5bSJoe Perches						if (ERROR("SPACING",
27843705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
27853705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
27863705ce5bSJoe Perches							$line_fixed = 1;
27873705ce5bSJoe Perches						}
2788d8aaf121SAndy Whitcroft					}
2789d8aaf121SAndy Whitcroft
2790d8aaf121SAndy Whitcroft				# // is a comment
2791d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
27920a920b5bSAndy Whitcroft
27931f65f947SAndy Whitcroft				# No spaces for:
27941f65f947SAndy Whitcroft				#   ->
27951f65f947SAndy Whitcroft				#   :   when part of a bitfield
27961f65f947SAndy Whitcroft				} elsif ($op eq '->' || $opv eq ':B') {
27974a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
27983705ce5bSJoe Perches						if (ERROR("SPACING",
27993705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
28003705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
28013705ce5bSJoe Perches							$line_fixed = 1;
28023705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
28033705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
28043705ce5bSJoe Perches							}
28053705ce5bSJoe Perches						}
28060a920b5bSAndy Whitcroft					}
28070a920b5bSAndy Whitcroft
28080a920b5bSAndy Whitcroft				# , must have a space on the right.
28090a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
2810cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
28113705ce5bSJoe Perches						if (ERROR("SPACING",
28123705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
28133705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
28143705ce5bSJoe Perches							$line_fixed = 1;
28153705ce5bSJoe Perches						}
28160a920b5bSAndy Whitcroft					}
28170a920b5bSAndy Whitcroft
28189c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
281974048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
28209c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
28219c0ca6f9SAndy Whitcroft
28229c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
28239c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
28249c0ca6f9SAndy Whitcroft				# unary operator, or a cast
28259c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
282674048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
28270d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
2828cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
28293705ce5bSJoe Perches						if (ERROR("SPACING",
28303705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
28313705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
28323705ce5bSJoe Perches							$line_fixed = 1;
28333705ce5bSJoe Perches						}
28340a920b5bSAndy Whitcroft					}
2835a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2836171ae1a4SAndy Whitcroft						# A unary '*' may be const
2837171ae1a4SAndy Whitcroft
2838171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
28393705ce5bSJoe Perches						if (ERROR("SPACING",
28403705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
28413705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
28423705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
28433705ce5bSJoe Perches							$line_fixed = 1;
28443705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
28453705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
28463705ce5bSJoe Perches							}
28473705ce5bSJoe Perches						}
28480a920b5bSAndy Whitcroft					}
28490a920b5bSAndy Whitcroft
28500a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
28510a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
2852773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
28533705ce5bSJoe Perches						if (ERROR("SPACING",
28543705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
28553705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
28563705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
28573705ce5bSJoe Perches							$line_fixed = 1;
28583705ce5bSJoe Perches						}
28590a920b5bSAndy Whitcroft					}
2860773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
2861773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
28623705ce5bSJoe Perches						if (ERROR("SPACING",
28633705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
28643705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
28653705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
28663705ce5bSJoe Perches							$line_fixed = 1;
28673705ce5bSJoe Perches						}
2868653d4876SAndy Whitcroft					}
2869773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
28703705ce5bSJoe Perches						if (ERROR("SPACING",
28713705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
28723705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
28733705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
28743705ce5bSJoe Perches							$line_fixed = 1;
28753705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
28763705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
2877773647a0SAndy Whitcroft							}
28783705ce5bSJoe Perches						}
28793705ce5bSJoe Perches					}
28800a920b5bSAndy Whitcroft
28810a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
28829c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
28839c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
28849c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
2885c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
2886c2fdda0dSAndy Whitcroft					 $op eq '%')
28870a920b5bSAndy Whitcroft				{
2888773647a0SAndy Whitcroft					if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
28893705ce5bSJoe Perches						if (ERROR("SPACING",
28903705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
28913705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
28923705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
28933705ce5bSJoe Perches							$line_fixed = 1;
28943705ce5bSJoe Perches						}
28950a920b5bSAndy Whitcroft					}
28960a920b5bSAndy Whitcroft
28971f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
28981f65f947SAndy Whitcroft				# terminating a case value or a label.
28991f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
29001f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
29013705ce5bSJoe Perches						if (ERROR("SPACING",
29023705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
29033705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
29043705ce5bSJoe Perches							$line_fixed = 1;
29053705ce5bSJoe Perches						}
29061f65f947SAndy Whitcroft					}
29071f65f947SAndy Whitcroft
29080a920b5bSAndy Whitcroft				# All the others need spaces both sides.
2909cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
29101f65f947SAndy Whitcroft					my $ok = 0;
29111f65f947SAndy Whitcroft
291222f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
29131f65f947SAndy Whitcroft					if (($op eq '<' &&
29141f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
29151f65f947SAndy Whitcroft					    ($op eq '>' &&
29161f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
29171f65f947SAndy Whitcroft					{
29181f65f947SAndy Whitcroft					    	$ok = 1;
29191f65f947SAndy Whitcroft					}
29201f65f947SAndy Whitcroft
29211f65f947SAndy Whitcroft					# Ignore ?:
29221f65f947SAndy Whitcroft					if (($opv eq ':O' && $ca =~ /\?$/) ||
29231f65f947SAndy Whitcroft					    ($op eq '?' && $cc =~ /^:/)) {
29241f65f947SAndy Whitcroft					    	$ok = 1;
29251f65f947SAndy Whitcroft					}
29261f65f947SAndy Whitcroft
29271f65f947SAndy Whitcroft					if ($ok == 0) {
29283705ce5bSJoe Perches						if (ERROR("SPACING",
29293705ce5bSJoe Perches							  "spaces required around that '$op' $at\n" . $hereptr)) {
29303705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
29313705ce5bSJoe Perches							$good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " ";
29323705ce5bSJoe Perches							$line_fixed = 1;
29333705ce5bSJoe Perches						}
29340a920b5bSAndy Whitcroft					}
293522f2a2efSAndy Whitcroft				}
29364a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
29373705ce5bSJoe Perches
29383705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
29393705ce5bSJoe Perches
29403705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
29410a920b5bSAndy Whitcroft			}
29423705ce5bSJoe Perches
29433705ce5bSJoe Perches			if (($#elements % 2) == 0) {
29443705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
29453705ce5bSJoe Perches			}
29463705ce5bSJoe Perches
29473705ce5bSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
29483705ce5bSJoe Perches				$fixed[$linenr - 1] = $fixed_line;
29493705ce5bSJoe Perches			}
29503705ce5bSJoe Perches
29513705ce5bSJoe Perches
29520a920b5bSAndy Whitcroft		}
29530a920b5bSAndy Whitcroft
2954786b6326SJoe Perches# check for whitespace before a non-naked semicolon
2955786b6326SJoe Perches		if ($line =~ /^\+.*\S\s+;/) {
2956786b6326SJoe Perches			if (WARN("SPACING",
2957786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
2958786b6326SJoe Perches			    $fix) {
2959786b6326SJoe Perches				1 while $fixed[$linenr - 1] =~
2960786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
2961786b6326SJoe Perches			}
2962786b6326SJoe Perches		}
2963786b6326SJoe Perches
2964f0a594c1SAndy Whitcroft# check for multiple assignments
2965f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
2966000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
2967000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
2968f0a594c1SAndy Whitcroft		}
2969f0a594c1SAndy Whitcroft
297022f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
297122f2a2efSAndy Whitcroft## # continuation.
297222f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
297322f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
297422f2a2efSAndy Whitcroft##
297522f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
297622f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
297722f2a2efSAndy Whitcroft## 			my $ln = $line;
297822f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
297922f2a2efSAndy Whitcroft## 			}
298022f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
2981000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
2982000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
298322f2a2efSAndy Whitcroft## 			}
298422f2a2efSAndy Whitcroft## 		}
2985f0a594c1SAndy Whitcroft
29860a920b5bSAndy Whitcroft#need space before brace following if, while, etc
298722f2a2efSAndy Whitcroft		if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
298822f2a2efSAndy Whitcroft		    $line =~ /do{/) {
29893705ce5bSJoe Perches			if (ERROR("SPACING",
29903705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
29913705ce5bSJoe Perches			    $fix) {
29923705ce5bSJoe Perches				$fixed[$linenr - 1] =~
29933705ce5bSJoe Perches				    s/^(\+.*(?:do|\))){/$1 {/;
29943705ce5bSJoe Perches			}
2995de7d4f0eSAndy Whitcroft		}
2996de7d4f0eSAndy Whitcroft
2997c4a62ef9SJoe Perches## # check for blank lines before declarations
2998c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
2999c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
3000c4a62ef9SJoe Perches##			WARN("SPACING",
3001c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
3002c4a62ef9SJoe Perches##		}
3003c4a62ef9SJoe Perches##
3004c4a62ef9SJoe Perches
3005de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
3006de7d4f0eSAndy Whitcroft# on the line
3007de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
3008000d1cc1SJoe Perches			ERROR("SPACING",
3009000d1cc1SJoe Perches			      "space required after that close brace '}'\n" . $herecurr);
30100a920b5bSAndy Whitcroft		}
30110a920b5bSAndy Whitcroft
301222f2a2efSAndy Whitcroft# check spacing on square brackets
301322f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
30143705ce5bSJoe Perches			if (ERROR("SPACING",
30153705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
30163705ce5bSJoe Perches			    $fix) {
30173705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30183705ce5bSJoe Perches				    s/\[\s+/\[/;
30193705ce5bSJoe Perches			}
302022f2a2efSAndy Whitcroft		}
302122f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
30223705ce5bSJoe Perches			if (ERROR("SPACING",
30233705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
30243705ce5bSJoe Perches			    $fix) {
30253705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30263705ce5bSJoe Perches				    s/\s+\]/\]/;
30273705ce5bSJoe Perches			}
302822f2a2efSAndy Whitcroft		}
302922f2a2efSAndy Whitcroft
3030c45dcabdSAndy Whitcroft# check spacing on parentheses
30319c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
30329c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
30333705ce5bSJoe Perches			if (ERROR("SPACING",
30343705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
30353705ce5bSJoe Perches			    $fix) {
30363705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30373705ce5bSJoe Perches				    s/\(\s+/\(/;
30383705ce5bSJoe Perches			}
303922f2a2efSAndy Whitcroft		}
304013214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
3041c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
3042c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
30433705ce5bSJoe Perches			if (ERROR("SPACING",
30443705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
30453705ce5bSJoe Perches			    $fix) {
30463705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30473705ce5bSJoe Perches				    s/\s+\)/\)/;
30483705ce5bSJoe Perches			}
304922f2a2efSAndy Whitcroft		}
305022f2a2efSAndy Whitcroft
30510a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
30524a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
30530a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
30543705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
30553705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
30563705ce5bSJoe Perches			    $fix) {
30573705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30583705ce5bSJoe Perches				    s/^(.)\s+/$1/;
30593705ce5bSJoe Perches			}
30600a920b5bSAndy Whitcroft		}
30610a920b5bSAndy Whitcroft
3062c45dcabdSAndy Whitcroft# Return is not a function.
3063c45dcabdSAndy Whitcroft		if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
3064c45dcabdSAndy Whitcroft			my $spacing = $1;
3065c45dcabdSAndy Whitcroft			my $value = $2;
3066c45dcabdSAndy Whitcroft
306786f9d059SAndy Whitcroft			# Flatten any parentheses
3068fb2d2c1bSAndy Whitcroft			$value =~ s/\(/ \(/g;
3069fb2d2c1bSAndy Whitcroft			$value =~ s/\)/\) /g;
3070e01886adSAndy Whitcroft			while ($value =~ s/\[[^\[\]]*\]/1/ ||
307163f17f89SAndy Whitcroft			       $value !~ /(?:$Ident|-?$Constant)\s*
307263f17f89SAndy Whitcroft					     $Compare\s*
307363f17f89SAndy Whitcroft					     (?:$Ident|-?$Constant)/x &&
307463f17f89SAndy Whitcroft			       $value =~ s/\([^\(\)]*\)/1/) {
3075c45dcabdSAndy Whitcroft			}
3076fb2d2c1bSAndy Whitcroft#print "value<$value>\n";
3077fb2d2c1bSAndy Whitcroft			if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
3078000d1cc1SJoe Perches				ERROR("RETURN_PARENTHESES",
3079000d1cc1SJoe Perches				      "return is not a function, parentheses are not required\n" . $herecurr);
3080c45dcabdSAndy Whitcroft
3081c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
3082000d1cc1SJoe Perches				ERROR("SPACING",
3083000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
3084c45dcabdSAndy Whitcroft			}
3085c45dcabdSAndy Whitcroft		}
308653a3c448SAndy Whitcroft# Return of what appears to be an errno should normally be -'ve
308753a3c448SAndy Whitcroft		if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
308853a3c448SAndy Whitcroft			my $name = $1;
308953a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
3090000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
3091000d1cc1SJoe Perches				     "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
309253a3c448SAndy Whitcroft			}
309353a3c448SAndy Whitcroft		}
3094c45dcabdSAndy Whitcroft
30950a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
30964a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
30973705ce5bSJoe Perches			if (ERROR("SPACING",
30983705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
30993705ce5bSJoe Perches			    $fix) {
31003705ce5bSJoe Perches				$fixed[$linenr - 1] =~
31013705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
31023705ce5bSJoe Perches			}
31030a920b5bSAndy Whitcroft		}
31040a920b5bSAndy Whitcroft
3105f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
3106f5fe35ddSAndy Whitcroft# statements after the conditional.
3107170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
31083e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
31093e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
31103e469cdcSAndy Whitcroft					if (!defined $stat);
3111170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
3112170d3a22SAndy Whitcroft						$remain_next, $off_next);
3113170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
3114170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
3115170d3a22SAndy Whitcroft
3116170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
3117170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
3118170d3a22SAndy Whitcroft				# then count those as offsets.
3119170d3a22SAndy Whitcroft				my ($whitespace) =
3120170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
3121170d3a22SAndy Whitcroft				my $offset =
3122170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
3123170d3a22SAndy Whitcroft
3124170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
3125170d3a22SAndy Whitcroft								$offset} = 1;
3126170d3a22SAndy Whitcroft			}
3127170d3a22SAndy Whitcroft		}
3128170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
3129170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
3130171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
31318905a67cSAndy Whitcroft
3132b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
3133000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
3134000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
31358905a67cSAndy Whitcroft			}
31368905a67cSAndy Whitcroft
31378905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
31388905a67cSAndy Whitcroft			# conditional.
3139773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
31408905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
314113214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
314253210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
314353210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
3144773647a0SAndy Whitcroft			{
3145bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
3146bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
3147bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
314842bdf74cSHidetoshi Seto				my $stat_real = '';
3149bb44ad39SAndy Whitcroft
315042bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
315142bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
3152bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
3153bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
3154bb44ad39SAndy Whitcroft				}
3155bb44ad39SAndy Whitcroft
3156000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3157000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
31588905a67cSAndy Whitcroft			}
31598905a67cSAndy Whitcroft		}
31608905a67cSAndy Whitcroft
316113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
316213214adfSAndy Whitcroft		if ($line =~ /
316313214adfSAndy Whitcroft			(?:
316413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
316513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
316613214adfSAndy Whitcroft				(?:\&\&|\|\|)
316713214adfSAndy Whitcroft			|
316813214adfSAndy Whitcroft				(?:\&\&|\|\|)
316913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
317013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
317113214adfSAndy Whitcroft			)/x)
317213214adfSAndy Whitcroft		{
3173000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
3174000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
317513214adfSAndy Whitcroft		}
317613214adfSAndy Whitcroft
31778905a67cSAndy Whitcroft# if and else should not have general statements after it
317813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
317913214adfSAndy Whitcroft			my $s = $1;
318013214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
318113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3182000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3183000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
31840a920b5bSAndy Whitcroft			}
318513214adfSAndy Whitcroft		}
318639667782SAndy Whitcroft# if should not continue a brace
318739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
3188000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3189000d1cc1SJoe Perches			      "trailing statements should be on next line\n" .
319039667782SAndy Whitcroft				$herecurr);
319139667782SAndy Whitcroft		}
3192a1080bf8SAndy Whitcroft# case and default should not have general statements after them
3193a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3194a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
31953fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3196a1080bf8SAndy Whitcroft			\s*return\s+
3197a1080bf8SAndy Whitcroft		    )/xg)
3198a1080bf8SAndy Whitcroft		{
3199000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3200000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
3201a1080bf8SAndy Whitcroft		}
32020a920b5bSAndy Whitcroft
32030a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
32040a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
32050a920b5bSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
32060a920b5bSAndy Whitcroft						$previndent == $indent) {
3207000d1cc1SJoe Perches			ERROR("ELSE_AFTER_BRACE",
3208000d1cc1SJoe Perches			      "else should follow close brace '}'\n" . $hereprev);
32090a920b5bSAndy Whitcroft		}
32100a920b5bSAndy Whitcroft
3211c2fdda0dSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3212c2fdda0dSAndy Whitcroft						$previndent == $indent) {
3213c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3214c2fdda0dSAndy Whitcroft
3215c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
3216c2fdda0dSAndy Whitcroft			# conditional.
3217773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
3218c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
3219c2fdda0dSAndy Whitcroft
3220c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
3221000d1cc1SJoe Perches				ERROR("WHILE_AFTER_BRACE",
3222000d1cc1SJoe Perches				      "while should follow close brace '}'\n" . $hereprev);
3223c2fdda0dSAndy Whitcroft			}
3224c2fdda0dSAndy Whitcroft		}
3225c2fdda0dSAndy Whitcroft
322695e2c602SJoe Perches#Specific variable tests
3227323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
3228323c1260SJoe Perches			my $var = $1;
322995e2c602SJoe Perches
323095e2c602SJoe Perches#gcc binary extension
323195e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
323295e2c602SJoe Perches				WARN("GCC_BINARY_CONSTANT",
323395e2c602SJoe Perches				     "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr);
323495e2c602SJoe Perches			}
323595e2c602SJoe Perches
323695e2c602SJoe Perches#CamelCase
3237807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
3238be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
323922735ce8SJoe Perches#Ignore Page<foo> variants
3240807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
324122735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
3242*3445686aSJoe Perches			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
3243*3445686aSJoe Perches				seed_camelcase_includes() if ($check);
3244*3445686aSJoe Perches				if (!defined $camelcase{$var}) {
3245323c1260SJoe Perches					$camelcase{$var} = 1;
3246be79794bSJoe Perches					CHK("CAMELCASE",
3247323c1260SJoe Perches					    "Avoid CamelCase: <$var>\n" . $herecurr);
3248323c1260SJoe Perches				}
3249323c1260SJoe Perches			}
3250*3445686aSJoe Perches		}
32510a920b5bSAndy Whitcroft
32520a920b5bSAndy Whitcroft#no spaces allowed after \ in define
3253c45dcabdSAndy Whitcroft		if ($line=~/\#\s*define.*\\\s$/) {
3254000d1cc1SJoe Perches			WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3255000d1cc1SJoe Perches			     "Whitepspace after \\ makes next lines useless\n" . $herecurr);
32560a920b5bSAndy Whitcroft		}
32570a920b5bSAndy Whitcroft
3258653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
3259c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
3260e09dec48SAndy Whitcroft			my $file = "$1.h";
3261e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
3262e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
3263e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
32647840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
3265c45dcabdSAndy Whitcroft			{
3266e09dec48SAndy Whitcroft				if ($realfile =~ m{^arch/}) {
3267000d1cc1SJoe Perches					CHK("ARCH_INCLUDE_LINUX",
3268000d1cc1SJoe Perches					    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3269e09dec48SAndy Whitcroft				} else {
3270000d1cc1SJoe Perches					WARN("INCLUDE_LINUX",
3271000d1cc1SJoe Perches					     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3272e09dec48SAndy Whitcroft				}
32730a920b5bSAndy Whitcroft			}
32740a920b5bSAndy Whitcroft		}
32750a920b5bSAndy Whitcroft
3276653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
3277653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
3278cf655043SAndy Whitcroft# in a known good container
3279b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
3280b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3281d8aaf121SAndy Whitcroft			my $ln = $linenr;
3282d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
3283c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
3284c45dcabdSAndy Whitcroft			my $ctx = '';
3285c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
3286f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3287f74bd194SAndy Whitcroft			$ctx = $dstat;
3288c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3289a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3290c45dcabdSAndy Whitcroft
3291f74bd194SAndy Whitcroft			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3292292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
3293c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
3294c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
3295c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
3296c45dcabdSAndy Whitcroft
3297c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
3298bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3299bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
3300c81769fdSAndy Whitcroft			       $dstat =~ s/\[[^\[\]]*\]/1/)
3301bf30d6edSAndy Whitcroft			{
3302c45dcabdSAndy Whitcroft			}
3303c45dcabdSAndy Whitcroft
3304e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
3305e45bab8eSAndy Whitcroft			while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3306e45bab8eSAndy Whitcroft			       $dstat =~ s/$Ident\s*("X*")/$1/)
3307e45bab8eSAndy Whitcroft			{
3308e45bab8eSAndy Whitcroft			}
3309e45bab8eSAndy Whitcroft
3310c45dcabdSAndy Whitcroft			my $exceptions = qr{
3311c45dcabdSAndy Whitcroft				$Declare|
3312c45dcabdSAndy Whitcroft				module_param_named|
3313a0a0a7a9SKees Cook				MODULE_PARM_DESC|
3314c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
3315c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
3316383099fdSAndy Whitcroft				__typeof__\(|
331722fd2d3eSStefani Seibold				union|
331822fd2d3eSStefani Seibold				struct|
3319ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
3320ea71a0a0SAndy Whitcroft				^\"|\"$
3321c45dcabdSAndy Whitcroft			}x;
33225eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3323f74bd194SAndy Whitcroft			if ($dstat ne '' &&
3324f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
3325f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
33263cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3327b9df76acSAndy Whitcroft			    $dstat !~ /^'X'$/ &&					# character constants
3328f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
3329f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
3330e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
333172f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
3332f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
3333f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
3334f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
3335f74bd194SAndy Whitcroft			    $dstat !~ /^\({/)						# ({...
3336c45dcabdSAndy Whitcroft			{
3337f74bd194SAndy Whitcroft				$ctx =~ s/\n*$//;
3338f74bd194SAndy Whitcroft				my $herectx = $here . "\n";
3339f74bd194SAndy Whitcroft				my $cnt = statement_rawlines($ctx);
3340f74bd194SAndy Whitcroft
3341f74bd194SAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
3342f74bd194SAndy Whitcroft					$herectx .= raw_line($linenr, $n) . "\n";
3343c45dcabdSAndy Whitcroft				}
3344c45dcabdSAndy Whitcroft
3345f74bd194SAndy Whitcroft				if ($dstat =~ /;/) {
3346f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3347f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3348f74bd194SAndy Whitcroft				} else {
3349000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
3350f74bd194SAndy Whitcroft					      "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3351d8aaf121SAndy Whitcroft				}
33520a920b5bSAndy Whitcroft			}
33535023d347SJoe Perches
3354481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
33555023d347SJoe Perches
33565023d347SJoe Perches		} else {
33575023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
3358481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
3359481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
33605023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
33615023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
33625023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
33635023d347SJoe Perches			}
3364653d4876SAndy Whitcroft		}
33650a920b5bSAndy Whitcroft
3366b13edf7fSJoe Perches# do {} while (0) macro tests:
3367b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
3368b13edf7fSJoe Perches# macro should not end with a semicolon
3369b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3370b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
3371b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3372b13edf7fSJoe Perches			my $ln = $linenr;
3373b13edf7fSJoe Perches			my $cnt = $realcnt;
3374b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
3375b13edf7fSJoe Perches			my $ctx = '';
3376b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
3377b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
3378b13edf7fSJoe Perches			$ctx = $dstat;
3379b13edf7fSJoe Perches
3380b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
3381b13edf7fSJoe Perches
3382b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3383b13edf7fSJoe Perches				my $stmts = $2;
3384b13edf7fSJoe Perches				my $semis = $3;
3385b13edf7fSJoe Perches
3386b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
3387b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
3388b13edf7fSJoe Perches				my $herectx = $here . "\n";
3389b13edf7fSJoe Perches
3390b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
3391b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
3392b13edf7fSJoe Perches				}
3393b13edf7fSJoe Perches
3394ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
3395ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
3396b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3397b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3398b13edf7fSJoe Perches				}
3399b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
3400b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3401b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3402b13edf7fSJoe Perches				}
3403b13edf7fSJoe Perches			}
3404b13edf7fSJoe Perches		}
3405b13edf7fSJoe Perches
3406080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
3407080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
3408080ba929SMike Frysinger#	.
3409080ba929SMike Frysinger#	ALIGN(...)
3410080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
3411080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
3412000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
3413000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
3414080ba929SMike Frysinger		}
3415080ba929SMike Frysinger
3416f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
341713214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
341813214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
3419cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
342013214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3421cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3422cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
3423aad4f614SJoe Perches				my @allowed = ();
3424aad4f614SJoe Perches				my $allow = 0;
342513214adfSAndy Whitcroft				my $seen = 0;
3426773647a0SAndy Whitcroft				my $herectx = $here . "\n";
3427cf655043SAndy Whitcroft				my $ln = $linenr - 1;
342813214adfSAndy Whitcroft				for my $chunk (@chunks) {
342913214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
343013214adfSAndy Whitcroft
3431773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
3432773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3433773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
3434773647a0SAndy Whitcroft
3435aad4f614SJoe Perches					$allowed[$allow] = 0;
3436773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3437773647a0SAndy Whitcroft
3438773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
3439773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
3440773647a0SAndy Whitcroft
3441773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3442cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
3443cf655043SAndy Whitcroft
3444773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
344513214adfSAndy Whitcroft
344613214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
344713214adfSAndy Whitcroft
3448aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3449cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
3450cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
3451aad4f614SJoe Perches						$allowed[$allow] = 1;
345213214adfSAndy Whitcroft					}
345313214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
3454cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
3455aad4f614SJoe Perches						$allowed[$allow] = 1;
345613214adfSAndy Whitcroft					}
3457cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
3458cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
3459aad4f614SJoe Perches						$allowed[$allow] = 1;
346013214adfSAndy Whitcroft					}
3461aad4f614SJoe Perches					$allow++;
346213214adfSAndy Whitcroft				}
3463aad4f614SJoe Perches				if ($seen) {
3464aad4f614SJoe Perches					my $sum_allowed = 0;
3465aad4f614SJoe Perches					foreach (@allowed) {
3466aad4f614SJoe Perches						$sum_allowed += $_;
3467aad4f614SJoe Perches					}
3468aad4f614SJoe Perches					if ($sum_allowed == 0) {
3469000d1cc1SJoe Perches						WARN("BRACES",
3470000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
3471aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
3472aad4f614SJoe Perches						 $seen != $allow) {
3473aad4f614SJoe Perches						CHK("BRACES",
3474aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
3475aad4f614SJoe Perches					}
347613214adfSAndy Whitcroft				}
347713214adfSAndy Whitcroft			}
347813214adfSAndy Whitcroft		}
3479773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
348013214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
3481cf655043SAndy Whitcroft			my $allowed = 0;
3482f0a594c1SAndy Whitcroft
3483cf655043SAndy Whitcroft			# Check the pre-context.
3484cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3485cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
3486cf655043SAndy Whitcroft				$allowed = 1;
3487f0a594c1SAndy Whitcroft			}
3488773647a0SAndy Whitcroft
3489773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
3490773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
3491773647a0SAndy Whitcroft
3492cf655043SAndy Whitcroft			# Check the condition.
3493cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
3494773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3495cf655043SAndy Whitcroft			if (defined $cond) {
3496773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
3497cf655043SAndy Whitcroft			}
3498cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
3499cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
3500cf655043SAndy Whitcroft				$allowed = 1;
3501cf655043SAndy Whitcroft			}
3502cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
3503cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
3504cf655043SAndy Whitcroft				$allowed = 1;
3505cf655043SAndy Whitcroft			}
3506cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
3507cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
3508cf655043SAndy Whitcroft				$allowed = 1;
3509cf655043SAndy Whitcroft			}
3510cf655043SAndy Whitcroft			# Check the post-context.
3511cf655043SAndy Whitcroft			if (defined $chunks[1]) {
3512cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
3513cf655043SAndy Whitcroft				if (defined $cond) {
3514773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
3515cf655043SAndy Whitcroft				}
3516cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
3517cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
3518cf655043SAndy Whitcroft					$allowed = 1;
3519cf655043SAndy Whitcroft				}
3520cf655043SAndy Whitcroft			}
3521cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
352269932487SJustin P. Mattock				my $herectx = $here . "\n";
3523f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
3524cf655043SAndy Whitcroft
3525f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
352669932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
3527cf655043SAndy Whitcroft				}
3528cf655043SAndy Whitcroft
3529000d1cc1SJoe Perches				WARN("BRACES",
3530000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
3531f0a594c1SAndy Whitcroft			}
3532f0a594c1SAndy Whitcroft		}
3533f0a594c1SAndy Whitcroft
35340979ae66SJoe Perches# check for unnecessary blank lines around braces
353577b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
35360979ae66SJoe Perches			CHK("BRACES",
35370979ae66SJoe Perches			    "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
35380979ae66SJoe Perches		}
353977b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
35400979ae66SJoe Perches			CHK("BRACES",
35410979ae66SJoe Perches			    "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
35420979ae66SJoe Perches		}
35430979ae66SJoe Perches
35444a0df2efSAndy Whitcroft# no volatiles please
35456c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
35466c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
3547000d1cc1SJoe Perches			WARN("VOLATILE",
3548000d1cc1SJoe Perches			     "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
35494a0df2efSAndy Whitcroft		}
35504a0df2efSAndy Whitcroft
355100df344fSAndy Whitcroft# warn about #if 0
3552c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3553000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
3554000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
3555de7d4f0eSAndy Whitcroft				$herecurr);
35564a0df2efSAndy Whitcroft		}
35574a0df2efSAndy Whitcroft
355803df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
355903df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
356003df4b51SAndy Whitcroft			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
356103df4b51SAndy Whitcroft			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
356203df4b51SAndy Whitcroft				WARN('NEEDLESS_IF',
356303df4b51SAndy Whitcroft				     "$1(NULL) is safe this check is probably not required\n" . $hereprev);
35644c432a8fSGreg Kroah-Hartman			}
35654c432a8fSGreg Kroah-Hartman		}
3566f0a594c1SAndy Whitcroft
35671a15a250SPatrick Pannuto# prefer usleep_range over udelay
356837581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
35691a15a250SPatrick Pannuto			# ignore udelay's < 10, however
357037581c28SBruce Allan			if (! ($1 < 10) ) {
3571000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
3572000d1cc1SJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
35731a15a250SPatrick Pannuto			}
35741a15a250SPatrick Pannuto		}
35751a15a250SPatrick Pannuto
357609ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
357709ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
357809ef8725SPatrick Pannuto			if ($1 < 20) {
3579000d1cc1SJoe Perches				WARN("MSLEEP",
3580000d1cc1SJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
358109ef8725SPatrick Pannuto			}
358209ef8725SPatrick Pannuto		}
358309ef8725SPatrick Pannuto
358436ec1939SJoe Perches# check for comparisons of jiffies
358536ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
358636ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
358736ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
358836ec1939SJoe Perches		}
358936ec1939SJoe Perches
35909d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
35919d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
35929d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
35939d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
35949d7a34a5SJoe Perches		}
35959d7a34a5SJoe Perches
359600df344fSAndy Whitcroft# warn about #ifdefs in C files
3597c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
359800df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
359900df344fSAndy Whitcroft#			print "$herecurr";
360000df344fSAndy Whitcroft#			$clean = 0;
360100df344fSAndy Whitcroft#		}
360200df344fSAndy Whitcroft
360322f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
3604c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
36053705ce5bSJoe Perches			if (ERROR("SPACING",
36063705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
36073705ce5bSJoe Perches			    $fix) {
36083705ce5bSJoe Perches				$fixed[$linenr - 1] =~
36093705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
36103705ce5bSJoe Perches			}
36113705ce5bSJoe Perches
361222f2a2efSAndy Whitcroft		}
361322f2a2efSAndy Whitcroft
36144a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
3615171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
3616171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
36174a0df2efSAndy Whitcroft			my $which = $1;
36184a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3619000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
3620000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
36214a0df2efSAndy Whitcroft			}
36224a0df2efSAndy Whitcroft		}
36234a0df2efSAndy Whitcroft# check for memory barriers without a comment.
36244a0df2efSAndy Whitcroft		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
36254a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3626000d1cc1SJoe Perches				CHK("MEMORY_BARRIER",
3627000d1cc1SJoe Perches				    "memory barrier without comment\n" . $herecurr);
36284a0df2efSAndy Whitcroft			}
36294a0df2efSAndy Whitcroft		}
36304a0df2efSAndy Whitcroft# check of hardware specific defines
3631c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
3632000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
3633000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
36340a920b5bSAndy Whitcroft		}
3635653d4876SAndy Whitcroft
3636d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
3637d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3638000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
3639000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
3640d4977c78STobias Klauser		}
3641d4977c78STobias Klauser
3642de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
3643de7d4f0eSAndy Whitcroft# storage class and type.
36449c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
36459c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
3646000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
3647000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
3648de7d4f0eSAndy Whitcroft		}
3649de7d4f0eSAndy Whitcroft
36508905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
36518905a67cSAndy Whitcroft		if ($line =~ /\b(__inline__|__inline)\b/) {
3652000d1cc1SJoe Perches			WARN("INLINE",
3653000d1cc1SJoe Perches			     "plain inline is preferred over $1\n" . $herecurr);
36548905a67cSAndy Whitcroft		}
36558905a67cSAndy Whitcroft
36563d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
36573d130fd0SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3658000d1cc1SJoe Perches			WARN("PREFER_PACKED",
3659000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
36603d130fd0SJoe Perches		}
36613d130fd0SJoe Perches
366239b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
366339b7e287SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3664000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
3665000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
366639b7e287SJoe Perches		}
366739b7e287SJoe Perches
36685f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
36695f14d3bdSJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
36705f14d3bdSJoe Perches			WARN("PREFER_PRINTF",
36715f14d3bdSJoe Perches			     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
36725f14d3bdSJoe Perches		}
36735f14d3bdSJoe Perches
36746061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
36756061d949SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
36766061d949SJoe Perches			WARN("PREFER_SCANF",
36776061d949SJoe Perches			     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
36786061d949SJoe Perches		}
36796061d949SJoe Perches
36808f53a9b8SJoe Perches# check for sizeof(&)
36818f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
3682000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
3683000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
36848f53a9b8SJoe Perches		}
36858f53a9b8SJoe Perches
368666c80b60SJoe Perches# check for sizeof without parenthesis
368766c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
368866c80b60SJoe Perches			WARN("SIZEOF_PARENTHESIS",
368966c80b60SJoe Perches			     "sizeof $1 should be sizeof($1)\n" . $herecurr);
369066c80b60SJoe Perches		}
369166c80b60SJoe Perches
3692428e2fdcSJoe Perches# check for line continuations in quoted strings with odd counts of "
3693428e2fdcSJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3694000d1cc1SJoe Perches			WARN("LINE_CONTINUATIONS",
3695000d1cc1SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
3696428e2fdcSJoe Perches		}
3697428e2fdcSJoe Perches
369888982feaSJoe Perches# check for struct spinlock declarations
369988982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
370088982feaSJoe Perches			WARN("USE_SPINLOCK_T",
370188982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
370288982feaSJoe Perches		}
370388982feaSJoe Perches
3704a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
3705a6962d72SJoe Perches		if ($line =~ /\bseq_printf\s*\(/) {
3706a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
3707a6962d72SJoe Perches			if ($fmt !~ /[^\\]\%/) {
3708a6962d72SJoe Perches				WARN("PREFER_SEQ_PUTS",
3709a6962d72SJoe Perches				     "Prefer seq_puts to seq_printf\n" . $herecurr);
3710a6962d72SJoe Perches			}
3711a6962d72SJoe Perches		}
3712a6962d72SJoe Perches
3713554e165cSAndy Whitcroft# Check for misused memsets
3714d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3715d1fe9c09SJoe Perches		    defined $stat &&
3716d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3717554e165cSAndy Whitcroft
3718d7c76ba7SJoe Perches			my $ms_addr = $2;
3719d1fe9c09SJoe Perches			my $ms_val = $7;
3720d1fe9c09SJoe Perches			my $ms_size = $12;
3721d7c76ba7SJoe Perches
3722554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
3723554e165cSAndy Whitcroft				ERROR("MEMSET",
3724d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3725554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
3726554e165cSAndy Whitcroft				WARN("MEMSET",
3727d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3728d7c76ba7SJoe Perches			}
3729d7c76ba7SJoe Perches		}
3730d7c76ba7SJoe Perches
3731d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
3732d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3733d1fe9c09SJoe Perches		    defined $stat &&
3734d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3735d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
3736d7c76ba7SJoe Perches				my $call = $1;
3737d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
3738d7c76ba7SJoe Perches				my $arg1 = $3;
3739d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
3740d1fe9c09SJoe Perches				my $arg2 = $8;
3741d7c76ba7SJoe Perches				my $cast;
3742d7c76ba7SJoe Perches
3743d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3744d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
3745d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
3746d7c76ba7SJoe Perches					$cast = $cast1;
3747d7c76ba7SJoe Perches				} else {
3748d7c76ba7SJoe Perches					$cast = $cast2;
3749d7c76ba7SJoe Perches				}
3750d7c76ba7SJoe Perches				WARN("MINMAX",
3751d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3752554e165cSAndy Whitcroft			}
3753554e165cSAndy Whitcroft		}
3754554e165cSAndy Whitcroft
37554a273195SJoe Perches# check usleep_range arguments
37564a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
37574a273195SJoe Perches		    defined $stat &&
37584a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
37594a273195SJoe Perches			my $min = $1;
37604a273195SJoe Perches			my $max = $7;
37614a273195SJoe Perches			if ($min eq $max) {
37624a273195SJoe Perches				WARN("USLEEP_RANGE",
37634a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
37644a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
37654a273195SJoe Perches				 $min > $max) {
37664a273195SJoe Perches				WARN("USLEEP_RANGE",
37674a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
37684a273195SJoe Perches			}
37694a273195SJoe Perches		}
37704a273195SJoe Perches
3771de7d4f0eSAndy Whitcroft# check for new externs in .c files.
3772171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
3773c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
3774171ae1a4SAndy Whitcroft		{
3775c45dcabdSAndy Whitcroft			my $function_name = $1;
3776c45dcabdSAndy Whitcroft			my $paren_space = $2;
3777171ae1a4SAndy Whitcroft
3778171ae1a4SAndy Whitcroft			my $s = $stat;
3779171ae1a4SAndy Whitcroft			if (defined $cond) {
3780171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
3781171ae1a4SAndy Whitcroft			}
3782c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
3783c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
3784c45dcabdSAndy Whitcroft			{
3785000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
3786000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
3787de7d4f0eSAndy Whitcroft			}
3788de7d4f0eSAndy Whitcroft
3789171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
3790000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
3791000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
3792171ae1a4SAndy Whitcroft			}
37939c9ba34eSAndy Whitcroft
37949c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
37959c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
37969c9ba34eSAndy Whitcroft		{
3797000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
3798000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
3799171ae1a4SAndy Whitcroft		}
3800171ae1a4SAndy Whitcroft
3801de7d4f0eSAndy Whitcroft# checks for new __setup's
3802de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
3803de7d4f0eSAndy Whitcroft			my $name = $1;
3804de7d4f0eSAndy Whitcroft
3805de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
3806000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
3807000d1cc1SJoe Perches				    "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
3808de7d4f0eSAndy Whitcroft			}
3809653d4876SAndy Whitcroft		}
38109c0ca6f9SAndy Whitcroft
38119c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
3812caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
3813000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
3814000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
38159c0ca6f9SAndy Whitcroft		}
381613214adfSAndy Whitcroft
3817a640d25cSJoe Perches# alloc style
3818a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
3819a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3820a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
3821a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
3822a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
3823a640d25cSJoe Perches		}
3824a640d25cSJoe Perches
3825972fdea2SJoe Perches# check for krealloc arg reuse
3826972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3827972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
3828972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
3829972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
3830972fdea2SJoe Perches		}
3831972fdea2SJoe Perches
38325ce59ae0SJoe Perches# check for alloc argument mismatch
38335ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
38345ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
38355ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
38365ce59ae0SJoe Perches		}
38375ce59ae0SJoe Perches
3838caf2a54fSJoe Perches# check for multiple semicolons
3839caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
3840000d1cc1SJoe Perches			WARN("ONE_SEMICOLON",
3841000d1cc1SJoe Perches			     "Statements terminations use 1 semicolon\n" . $herecurr);
3842d1e2ad07SJoe Perches		}
3843d1e2ad07SJoe Perches
3844d1e2ad07SJoe Perches# check for switch/default statements without a break;
3845d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3846d1e2ad07SJoe Perches		    defined $stat &&
3847d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
3848d1e2ad07SJoe Perches			my $ctx = '';
3849d1e2ad07SJoe Perches			my $herectx = $here . "\n";
3850d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
3851d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
3852d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
3853d1e2ad07SJoe Perches			}
3854d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
3855d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
3856caf2a54fSJoe Perches		}
3857caf2a54fSJoe Perches
385813214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
385913214adfSAndy Whitcroft		if ($line =~ /__FUNCTION__/) {
3860000d1cc1SJoe Perches			WARN("USE_FUNC",
3861000d1cc1SJoe Perches			     "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
386213214adfSAndy Whitcroft		}
3863773647a0SAndy Whitcroft
38642c92488aSJoe Perches# check for use of yield()
38652c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
38662c92488aSJoe Perches			WARN("YIELD",
38672c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
38682c92488aSJoe Perches		}
38692c92488aSJoe Perches
3870179f8f40SJoe Perches# check for comparisons against true and false
3871179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
3872179f8f40SJoe Perches			my $lead = $1;
3873179f8f40SJoe Perches			my $arg = $2;
3874179f8f40SJoe Perches			my $test = $3;
3875179f8f40SJoe Perches			my $otype = $4;
3876179f8f40SJoe Perches			my $trail = $5;
3877179f8f40SJoe Perches			my $op = "!";
3878179f8f40SJoe Perches
3879179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
3880179f8f40SJoe Perches
3881179f8f40SJoe Perches			my $type = lc($otype);
3882179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
3883179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
3884179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
3885179f8f40SJoe Perches					$op = "";
3886179f8f40SJoe Perches				}
3887179f8f40SJoe Perches
3888179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
3889179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
3890179f8f40SJoe Perches
3891179f8f40SJoe Perches## maybe suggesting a correct construct would better
3892179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
3893179f8f40SJoe Perches
3894179f8f40SJoe Perches			}
3895179f8f40SJoe Perches		}
3896179f8f40SJoe Perches
38974882720bSThomas Gleixner# check for semaphores initialized locked
38984882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
3899000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
3900000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
3901773647a0SAndy Whitcroft		}
39026712d858SJoe Perches
390367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
390467d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
3905000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
390667d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
3907773647a0SAndy Whitcroft		}
39086712d858SJoe Perches
3909f3db6639SMichael Ellerman# check for __initcall(), use device_initcall() explicitly please
3910f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
3911000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
3912000d1cc1SJoe Perches			     "please use device_initcall() instead of __initcall()\n" . $herecurr);
3913f3db6639SMichael Ellerman		}
39146712d858SJoe Perches
391579404849SEmese Revfy# check for various ops structs, ensure they are const.
391679404849SEmese Revfy		my $struct_ops = qr{acpi_dock_ops|
391779404849SEmese Revfy				address_space_operations|
391879404849SEmese Revfy				backlight_ops|
391979404849SEmese Revfy				block_device_operations|
392079404849SEmese Revfy				dentry_operations|
392179404849SEmese Revfy				dev_pm_ops|
392279404849SEmese Revfy				dma_map_ops|
392379404849SEmese Revfy				extent_io_ops|
392479404849SEmese Revfy				file_lock_operations|
392579404849SEmese Revfy				file_operations|
392679404849SEmese Revfy				hv_ops|
392779404849SEmese Revfy				ide_dma_ops|
392879404849SEmese Revfy				intel_dvo_dev_ops|
392979404849SEmese Revfy				item_operations|
393079404849SEmese Revfy				iwl_ops|
393179404849SEmese Revfy				kgdb_arch|
393279404849SEmese Revfy				kgdb_io|
393379404849SEmese Revfy				kset_uevent_ops|
393479404849SEmese Revfy				lock_manager_operations|
393579404849SEmese Revfy				microcode_ops|
393679404849SEmese Revfy				mtrr_ops|
393779404849SEmese Revfy				neigh_ops|
393879404849SEmese Revfy				nlmsvc_binding|
393979404849SEmese Revfy				pci_raw_ops|
394079404849SEmese Revfy				pipe_buf_operations|
394179404849SEmese Revfy				platform_hibernation_ops|
394279404849SEmese Revfy				platform_suspend_ops|
394379404849SEmese Revfy				proto_ops|
394479404849SEmese Revfy				rpc_pipe_ops|
394579404849SEmese Revfy				seq_operations|
394679404849SEmese Revfy				snd_ac97_build_ops|
394779404849SEmese Revfy				soc_pcmcia_socket_ops|
394879404849SEmese Revfy				stacktrace_ops|
394979404849SEmese Revfy				sysfs_ops|
395079404849SEmese Revfy				tty_operations|
395179404849SEmese Revfy				usb_mon_operations|
395279404849SEmese Revfy				wd_ops}x;
39536903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
395479404849SEmese Revfy		    $line =~ /\bstruct\s+($struct_ops)\b/) {
3955000d1cc1SJoe Perches			WARN("CONST_STRUCT",
3956000d1cc1SJoe Perches			     "struct $1 should normally be const\n" .
39576903ffb2SAndy Whitcroft				$herecurr);
39582b6db5cbSAndy Whitcroft		}
3959773647a0SAndy Whitcroft
3960773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
3961773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
3962773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
3963c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
3964c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
3965171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
3966171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
3967171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
3968773647a0SAndy Whitcroft		{
3969000d1cc1SJoe Perches			WARN("NR_CPUS",
3970000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
3971773647a0SAndy Whitcroft		}
39729c9ba34eSAndy Whitcroft
39739c9ba34eSAndy Whitcroft# check for %L{u,d,i} in strings
39749c9ba34eSAndy Whitcroft		my $string;
39759c9ba34eSAndy Whitcroft		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
39769c9ba34eSAndy Whitcroft			$string = substr($rawline, $-[1], $+[1] - $-[1]);
39772a1bc5d5SAndy Whitcroft			$string =~ s/%%/__/g;
39789c9ba34eSAndy Whitcroft			if ($string =~ /(?<!%)%L[udi]/) {
3979000d1cc1SJoe Perches				WARN("PRINTF_L",
3980000d1cc1SJoe Perches				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
39819c9ba34eSAndy Whitcroft				last;
39829c9ba34eSAndy Whitcroft			}
39839c9ba34eSAndy Whitcroft		}
3984691d77b6SAndy Whitcroft
3985691d77b6SAndy Whitcroft# whine mightly about in_atomic
3986691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
3987691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
3988000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
3989000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
3990f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
3991000d1cc1SJoe Perches				WARN("IN_ATOMIC",
3992000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
3993691d77b6SAndy Whitcroft			}
3994691d77b6SAndy Whitcroft		}
39951704f47bSPeter Zijlstra
39961704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
39971704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
39981704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
39991704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
40001704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
40011704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
4002000d1cc1SJoe Perches				ERROR("LOCKDEP",
4003000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
40041704f47bSPeter Zijlstra			}
40051704f47bSPeter Zijlstra		}
400688f8831cSDave Jones
400788f8831cSDave Jones		if ($line =~ /debugfs_create_file.*S_IWUGO/ ||
400888f8831cSDave Jones		    $line =~ /DEVICE_ATTR.*S_IWUGO/ ) {
4009000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
4010000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
401188f8831cSDave Jones		}
401213214adfSAndy Whitcroft	}
401313214adfSAndy Whitcroft
401413214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
401513214adfSAndy Whitcroft	# so just keep quiet.
401613214adfSAndy Whitcroft	if ($#rawlines == -1) {
401713214adfSAndy Whitcroft		exit(0);
40180a920b5bSAndy Whitcroft	}
40190a920b5bSAndy Whitcroft
40208905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
40218905a67cSAndy Whitcroft	# things that appear to be patches.
40228905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
40238905a67cSAndy Whitcroft		exit(0);
40248905a67cSAndy Whitcroft	}
40258905a67cSAndy Whitcroft
40268905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
40278905a67cSAndy Whitcroft	# just keep quiet.
40288905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
40298905a67cSAndy Whitcroft		exit(0);
40308905a67cSAndy Whitcroft	}
40318905a67cSAndy Whitcroft
40328905a67cSAndy Whitcroft	if (!$is_patch) {
4033000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
4034000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
40350a920b5bSAndy Whitcroft	}
40360a920b5bSAndy Whitcroft	if ($is_patch && $chk_signoff && $signoff == 0) {
4037000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
4038000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
40390a920b5bSAndy Whitcroft	}
40400a920b5bSAndy Whitcroft
4041f0a594c1SAndy Whitcroft	print report_dump();
404213214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
404313214adfSAndy Whitcroft		print "$filename " if ($summary_file);
40446c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
40456c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
40466c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
40478905a67cSAndy Whitcroft		print "\n" if ($quiet == 0);
40486c72ffaaSAndy Whitcroft	}
40498905a67cSAndy Whitcroft
4050d2c0a235SAndy Whitcroft	if ($quiet == 0) {
4051d1fe9c09SJoe Perches
4052d1fe9c09SJoe Perches		if ($^V lt 5.10.0) {
4053d1fe9c09SJoe Perches			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
4054d1fe9c09SJoe Perches			print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
4055d1fe9c09SJoe Perches		}
4056d1fe9c09SJoe Perches
4057d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
4058d2c0a235SAndy Whitcroft		# then suggest that.
4059d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
4060d2c0a235SAndy Whitcroft			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
4061d2c0a235SAndy Whitcroft			print "      scripts/cleanfile\n\n";
4062b0781216SMike Frysinger			$rpt_cleaners = 0;
4063d2c0a235SAndy Whitcroft		}
4064d2c0a235SAndy Whitcroft	}
4065d2c0a235SAndy Whitcroft
406611232688SArtem Bityutskiy	if ($quiet == 0 && keys %ignore_type) {
4067000d1cc1SJoe Perches	    print "NOTE: Ignored message types:";
4068000d1cc1SJoe Perches	    foreach my $ignore (sort keys %ignore_type) {
4069000d1cc1SJoe Perches		print " $ignore";
4070000d1cc1SJoe Perches	    }
407111232688SArtem Bityutskiy	    print "\n\n";
4072000d1cc1SJoe Perches	}
4073000d1cc1SJoe Perches
40743705ce5bSJoe Perches	if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
40753705ce5bSJoe Perches		my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes";
40763705ce5bSJoe Perches		my $linecount = 0;
40773705ce5bSJoe Perches		my $f;
40783705ce5bSJoe Perches
40793705ce5bSJoe Perches		open($f, '>', $newfile)
40803705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
40813705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
40823705ce5bSJoe Perches			$linecount++;
40833705ce5bSJoe Perches			if ($file) {
40843705ce5bSJoe Perches				if ($linecount > 3) {
40853705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
40863705ce5bSJoe Perches					print $f $fixed_line. "\n";
40873705ce5bSJoe Perches				}
40883705ce5bSJoe Perches			} else {
40893705ce5bSJoe Perches				print $f $fixed_line . "\n";
40903705ce5bSJoe Perches			}
40913705ce5bSJoe Perches		}
40923705ce5bSJoe Perches		close($f);
40933705ce5bSJoe Perches
40943705ce5bSJoe Perches		if (!$quiet) {
40953705ce5bSJoe Perches			print << "EOM";
40963705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
40973705ce5bSJoe Perches
40983705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
40993705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
41003705ce5bSJoe Perches
41013705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
41023705ce5bSJoe PerchesNo warranties, expressed or implied...
41033705ce5bSJoe Perches
41043705ce5bSJoe PerchesEOM
41053705ce5bSJoe Perches		}
41063705ce5bSJoe Perches	}
41073705ce5bSJoe Perches
41080a920b5bSAndy Whitcroft	if ($clean == 1 && $quiet == 0) {
4109c2fdda0dSAndy Whitcroft		print "$vname has no obvious style problems and is ready for submission.\n"
41100a920b5bSAndy Whitcroft	}
41110a920b5bSAndy Whitcroft	if ($clean == 0 && $quiet == 0) {
4112000d1cc1SJoe Perches		print << "EOM";
4113000d1cc1SJoe Perches$vname has style problems, please review.
4114000d1cc1SJoe Perches
4115000d1cc1SJoe PerchesIf any of these errors are false positives, please report
4116000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS.
4117000d1cc1SJoe PerchesEOM
41180a920b5bSAndy Whitcroft	}
411913214adfSAndy Whitcroft
41200a920b5bSAndy Whitcroft	return $clean;
41210a920b5bSAndy Whitcroft}
4122