xref: /linux-6.15/scripts/checkpatch.pl (revision 3705ce5b)
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;
30*3705ce5bSJoe Perchesmy $fix = 0;
316c72ffaaSAndy Whitcroftmy $root;
32c2fdda0dSAndy Whitcroftmy %debug;
33000d1cc1SJoe Perchesmy %ignore_type = ();
34000d1cc1SJoe Perchesmy @ignore = ();
3577f5b10aSHannes Edermy $help = 0;
36000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
376cd7f386SJoe Perchesmy $max_line_length = 80;
3877f5b10aSHannes Eder
3977f5b10aSHannes Edersub help {
4077f5b10aSHannes Eder	my ($exitcode) = @_;
4177f5b10aSHannes Eder
4277f5b10aSHannes Eder	print << "EOM";
4377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
4477f5b10aSHannes EderVersion: $V
4577f5b10aSHannes Eder
4677f5b10aSHannes EderOptions:
4777f5b10aSHannes Eder  -q, --quiet                quiet
4877f5b10aSHannes Eder  --no-tree                  run without a kernel tree
4977f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
5077f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
5177f5b10aSHannes Eder  --emacs                    emacs compile window format
5277f5b10aSHannes Eder  --terse                    one line per report
5377f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
5477f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
55000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
566cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
57000d1cc1SJoe Perches  --show-types               show the message "types" in the output
5877f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
5977f5b10aSHannes Eder  --no-summary               suppress the per-file summary
6077f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
6177f5b10aSHannes Eder  --summary-file             include the filename in summary
6277f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
6377f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
6477f5b10aSHannes Eder                             is all off)
6577f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
6677f5b10aSHannes Eder                             literally
67*3705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
68*3705ce5bSJoe Perches                             If correctable single-line errors exist, create
69*3705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
70*3705ce5bSJoe Perches                             with potential errors corrected to the preferred
71*3705ce5bSJoe Perches                             checkpatch style
7277f5b10aSHannes Eder  -h, --help, --version      display this help and exit
7377f5b10aSHannes Eder
7477f5b10aSHannes EderWhen FILE is - read standard input.
7577f5b10aSHannes EderEOM
7677f5b10aSHannes Eder
7777f5b10aSHannes Eder	exit($exitcode);
7877f5b10aSHannes Eder}
7977f5b10aSHannes Eder
80000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
81000d1cc1SJoe Perchesif (-f $conf) {
82000d1cc1SJoe Perches	my @conf_args;
83000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
84000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
85000d1cc1SJoe Perches
86000d1cc1SJoe Perches	while (<$conffile>) {
87000d1cc1SJoe Perches		my $line = $_;
88000d1cc1SJoe Perches
89000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
90000d1cc1SJoe Perches		$line =~ s/^\s*//g;
91000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
92000d1cc1SJoe Perches
93000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
94000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
95000d1cc1SJoe Perches
96000d1cc1SJoe Perches		my @words = split(" ", $line);
97000d1cc1SJoe Perches		foreach my $word (@words) {
98000d1cc1SJoe Perches			last if ($word =~ m/^#/);
99000d1cc1SJoe Perches			push (@conf_args, $word);
100000d1cc1SJoe Perches		}
101000d1cc1SJoe Perches	}
102000d1cc1SJoe Perches	close($conffile);
103000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
104000d1cc1SJoe Perches}
105000d1cc1SJoe Perches
1060a920b5bSAndy WhitcroftGetOptions(
1076c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1080a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1090a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1100a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1116c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1128905a67cSAndy Whitcroft	'terse!'	=> \$terse,
11377f5b10aSHannes Eder	'f|file!'	=> \$file,
1146c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1156c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
116000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
117000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
1186cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
1196c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
1208905a67cSAndy Whitcroft	'summary!'	=> \$summary,
1218905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
12213214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
123*3705ce5bSJoe Perches	'fix!'		=> \$fix,
124c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
125773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
12677f5b10aSHannes Eder	'h|help'	=> \$help,
12777f5b10aSHannes Eder	'version'	=> \$help
12877f5b10aSHannes Eder) or help(1);
12977f5b10aSHannes Eder
13077f5b10aSHannes Ederhelp(0) if ($help);
1310a920b5bSAndy Whitcroft
1320a920b5bSAndy Whitcroftmy $exit = 0;
1330a920b5bSAndy Whitcroft
1340a920b5bSAndy Whitcroftif ($#ARGV < 0) {
13577f5b10aSHannes Eder	print "$P: no input files\n";
1360a920b5bSAndy Whitcroft	exit(1);
1370a920b5bSAndy Whitcroft}
1380a920b5bSAndy Whitcroft
139000d1cc1SJoe Perches@ignore = split(/,/, join(',',@ignore));
140000d1cc1SJoe Perchesforeach my $word (@ignore) {
141000d1cc1SJoe Perches	$word =~ s/\s*\n?$//g;
142000d1cc1SJoe Perches	$word =~ s/^\s*//g;
143000d1cc1SJoe Perches	$word =~ s/\s+/ /g;
144000d1cc1SJoe Perches	$word =~ tr/[a-z]/[A-Z]/;
145000d1cc1SJoe Perches
146000d1cc1SJoe Perches	next if ($word =~ m/^\s*#/);
147000d1cc1SJoe Perches	next if ($word =~ m/^\s*$/);
148000d1cc1SJoe Perches
149000d1cc1SJoe Perches	$ignore_type{$word}++;
150000d1cc1SJoe Perches}
151000d1cc1SJoe Perches
152c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
153c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
1547429c690SAndy Whitcroftmy $dbg_type = 0;
155a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
156c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
15721caa13cSAndy Whitcroft	## no critic
15821caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
15921caa13cSAndy Whitcroft	die "$@" if ($@);
160c2fdda0dSAndy Whitcroft}
161c2fdda0dSAndy Whitcroft
162d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
163d2c0a235SAndy Whitcroft
1648905a67cSAndy Whitcroftif ($terse) {
1658905a67cSAndy Whitcroft	$emacs = 1;
1668905a67cSAndy Whitcroft	$quiet++;
1678905a67cSAndy Whitcroft}
1688905a67cSAndy Whitcroft
1696c72ffaaSAndy Whitcroftif ($tree) {
1706c72ffaaSAndy Whitcroft	if (defined $root) {
1716c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
1726c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
1736c72ffaaSAndy Whitcroft		}
1746c72ffaaSAndy Whitcroft	} else {
1756c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
1766c72ffaaSAndy Whitcroft			$root = '.';
1776c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
1786c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
1796c72ffaaSAndy Whitcroft			$root = $1;
1806c72ffaaSAndy Whitcroft		}
1816c72ffaaSAndy Whitcroft	}
1826c72ffaaSAndy Whitcroft
1836c72ffaaSAndy Whitcroft	if (!defined $root) {
1840a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
1850a920b5bSAndy Whitcroft		exit(2);
1860a920b5bSAndy Whitcroft	}
1876c72ffaaSAndy Whitcroft}
1886c72ffaaSAndy Whitcroft
1896c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
1906c72ffaaSAndy Whitcroft
1912ceb532bSAndy Whitcroftour $Ident	= qr{
1922ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
1932ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
1942ceb532bSAndy Whitcroft		}x;
1956c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
1966c72ffaaSAndy Whitcroftour $Sparse	= qr{
1976c72ffaaSAndy Whitcroft			__user|
1986c72ffaaSAndy Whitcroft			__kernel|
1996c72ffaaSAndy Whitcroft			__force|
2006c72ffaaSAndy Whitcroft			__iomem|
2016c72ffaaSAndy Whitcroft			__must_check|
2026c72ffaaSAndy Whitcroft			__init_refok|
203417495edSAndy Whitcroft			__kprobes|
204165e72a6SSven Eckelmann			__ref|
205165e72a6SSven Eckelmann			__rcu
2066c72ffaaSAndy Whitcroft		}x;
20752131292SWolfram Sang
20852131292SWolfram Sang# Notes to $Attribute:
20952131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
2106c72ffaaSAndy Whitcroftour $Attribute	= qr{
2116c72ffaaSAndy Whitcroft			const|
21203f1df7dSJoe Perches			__percpu|
21303f1df7dSJoe Perches			__nocast|
21403f1df7dSJoe Perches			__safe|
21503f1df7dSJoe Perches			__bitwise__|
21603f1df7dSJoe Perches			__packed__|
21703f1df7dSJoe Perches			__packed2__|
21803f1df7dSJoe Perches			__naked|
21903f1df7dSJoe Perches			__maybe_unused|
22003f1df7dSJoe Perches			__always_unused|
22103f1df7dSJoe Perches			__noreturn|
22203f1df7dSJoe Perches			__used|
22303f1df7dSJoe Perches			__cold|
22403f1df7dSJoe Perches			__noclone|
22503f1df7dSJoe Perches			__deprecated|
2266c72ffaaSAndy Whitcroft			__read_mostly|
2276c72ffaaSAndy Whitcroft			__kprobes|
22852131292SWolfram Sang			__(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
22924e1d81aSAndy Whitcroft			____cacheline_aligned|
23024e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
2315fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
2325fe3af11SAndy Whitcroft			__weak
2336c72ffaaSAndy Whitcroft		  }x;
234c45dcabdSAndy Whitcroftour $Modifier;
2356c72ffaaSAndy Whitcroftour $Inline	= qr{inline|__always_inline|noinline};
2366c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
2376c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
2386c72ffaaSAndy Whitcroft
23995e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
24095e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
24195e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
24295e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
243326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
244326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
245326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
24674349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
24795e2c602SJoe Perchesour $Constant	= qr{$Float|$Binary|$Hex|$Int};
248326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
24986f9d059SAndy Whitcroftour $Compare    = qr{<=|>=|==|!=|<|>};
25023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
2516c72ffaaSAndy Whitcroftour $Operators	= qr{
2526c72ffaaSAndy Whitcroft			<=|>=|==|!=|
2536c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
25423f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
2556c72ffaaSAndy Whitcroft		  }x;
2566c72ffaaSAndy Whitcroft
2578905a67cSAndy Whitcroftour $NonptrType;
2588905a67cSAndy Whitcroftour $Type;
2598905a67cSAndy Whitcroftour $Declare;
2608905a67cSAndy Whitcroft
26115662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
26215662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
263171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
264171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
265171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
266171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
267171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
268171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
269171ae1a4SAndy Whitcroft}x;
270171ae1a4SAndy Whitcroft
27115662b3eSJoe Perchesour $UTF8	= qr{
27215662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
27315662b3eSJoe Perches	| $NON_ASCII_UTF8
27415662b3eSJoe Perches}x;
27515662b3eSJoe Perches
2768ed22cadSAndy Whitcroftour $typeTypedefs = qr{(?x:
277fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
2788ed22cadSAndy Whitcroft	atomic_t
2798ed22cadSAndy Whitcroft)};
2808ed22cadSAndy Whitcroft
281691e669bSJoe Perchesour $logFunctions = qr{(?x:
2826e60c02eSJoe Perches	printk(?:_ratelimited|_once|)|
2836e60c02eSJoe Perches	[a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
2846e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
285b0531722SJoe Perches	panic|
286b0531722SJoe Perches	MODULE_[A-Z_]+
287691e669bSJoe Perches)};
288691e669bSJoe Perches
28920112475SJoe Perchesour $signature_tags = qr{(?xi:
29020112475SJoe Perches	Signed-off-by:|
29120112475SJoe Perches	Acked-by:|
29220112475SJoe Perches	Tested-by:|
29320112475SJoe Perches	Reviewed-by:|
29420112475SJoe Perches	Reported-by:|
2958543ae12SMugunthan V N	Suggested-by:|
29620112475SJoe Perches	To:|
29720112475SJoe Perches	Cc:
29820112475SJoe Perches)};
29920112475SJoe Perches
3008905a67cSAndy Whitcroftour @typeList = (
3018905a67cSAndy Whitcroft	qr{void},
302c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?char},
303c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?short},
304c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?int},
305c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long},
306c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+int},
307c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long},
308c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long\s+int},
3098905a67cSAndy Whitcroft	qr{unsigned},
3108905a67cSAndy Whitcroft	qr{float},
3118905a67cSAndy Whitcroft	qr{double},
3128905a67cSAndy Whitcroft	qr{bool},
3138905a67cSAndy Whitcroft	qr{struct\s+$Ident},
3148905a67cSAndy Whitcroft	qr{union\s+$Ident},
3158905a67cSAndy Whitcroft	qr{enum\s+$Ident},
3168905a67cSAndy Whitcroft	qr{${Ident}_t},
3178905a67cSAndy Whitcroft	qr{${Ident}_handler},
3188905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
3198905a67cSAndy Whitcroft);
320c45dcabdSAndy Whitcroftour @modifierList = (
321c45dcabdSAndy Whitcroft	qr{fastcall},
322c45dcabdSAndy Whitcroft);
3238905a67cSAndy Whitcroft
3247840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
3257840a94cSWolfram Sang	irq|
3267840a94cSWolfram Sang	memory
3277840a94cSWolfram Sang)};
3287840a94cSWolfram Sang# memory.h: ARM has a custom one
3297840a94cSWolfram Sang
3308905a67cSAndy Whitcroftsub build_types {
331d2172eb5SAndy Whitcroft	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
332d2172eb5SAndy Whitcroft	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
333c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
3348905a67cSAndy Whitcroft	$NonptrType	= qr{
335d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
336cf655043SAndy Whitcroft			(?:
3376b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
3388ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
339c45dcabdSAndy Whitcroft				(?:${all}\b)
340cf655043SAndy Whitcroft			)
341c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
3428905a67cSAndy Whitcroft		  }x;
3438905a67cSAndy Whitcroft	$Type	= qr{
344c45dcabdSAndy Whitcroft			$NonptrType
345b337d8b8SAndy Whitcroft			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
346c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
3478905a67cSAndy Whitcroft		  }x;
3488905a67cSAndy Whitcroft	$Declare	= qr{(?:$Storage\s+)?$Type};
3498905a67cSAndy Whitcroft}
3508905a67cSAndy Whitcroftbuild_types();
3516c72ffaaSAndy Whitcroft
3527d2367afSJoe Perches
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
3726c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
3730a920b5bSAndy Whitcroft
37400df344fSAndy Whitcroftmy @rawlines = ();
375c2fdda0dSAndy Whitcroftmy @lines = ();
376*3705ce5bSJoe Perchesmy @fixed = ();
377c2fdda0dSAndy Whitcroftmy $vname;
3786c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
37921caa13cSAndy Whitcroft	my $FILE;
3806c72ffaaSAndy Whitcroft	if ($file) {
38121caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
3826c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
38321caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
38421caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
3856c72ffaaSAndy Whitcroft	} else {
38621caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
3876c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
3886c72ffaaSAndy Whitcroft	}
389c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
390c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
391c2fdda0dSAndy Whitcroft	} else {
392c2fdda0dSAndy Whitcroft		$vname = $filename;
393c2fdda0dSAndy Whitcroft	}
39421caa13cSAndy Whitcroft	while (<$FILE>) {
3950a920b5bSAndy Whitcroft		chomp;
39600df344fSAndy Whitcroft		push(@rawlines, $_);
3976c72ffaaSAndy Whitcroft	}
39821caa13cSAndy Whitcroft	close($FILE);
399c2fdda0dSAndy Whitcroft	if (!process($filename)) {
4000a920b5bSAndy Whitcroft		$exit = 1;
4010a920b5bSAndy Whitcroft	}
40200df344fSAndy Whitcroft	@rawlines = ();
40313214adfSAndy Whitcroft	@lines = ();
404*3705ce5bSJoe Perches	@fixed = ();
4050a920b5bSAndy Whitcroft}
4060a920b5bSAndy Whitcroft
4070a920b5bSAndy Whitcroftexit($exit);
4080a920b5bSAndy Whitcroft
4090a920b5bSAndy Whitcroftsub top_of_kernel_tree {
4106c72ffaaSAndy Whitcroft	my ($root) = @_;
4116c72ffaaSAndy Whitcroft
4126c72ffaaSAndy Whitcroft	my @tree_check = (
4136c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
4146c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
4156c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
4166c72ffaaSAndy Whitcroft	);
4176c72ffaaSAndy Whitcroft
4186c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
4196c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
4200a920b5bSAndy Whitcroft			return 0;
4210a920b5bSAndy Whitcroft		}
4226c72ffaaSAndy Whitcroft	}
4236c72ffaaSAndy Whitcroft	return 1;
4246c72ffaaSAndy Whitcroft}
4250a920b5bSAndy Whitcroft
42620112475SJoe Perchessub parse_email {
42720112475SJoe Perches	my ($formatted_email) = @_;
42820112475SJoe Perches
42920112475SJoe Perches	my $name = "";
43020112475SJoe Perches	my $address = "";
43120112475SJoe Perches	my $comment = "";
43220112475SJoe Perches
43320112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
43420112475SJoe Perches		$name = $1;
43520112475SJoe Perches		$address = $2;
43620112475SJoe Perches		$comment = $3 if defined $3;
43720112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
43820112475SJoe Perches		$address = $1;
43920112475SJoe Perches		$comment = $2 if defined $2;
44020112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
44120112475SJoe Perches		$address = $1;
44220112475SJoe Perches		$comment = $2 if defined $2;
44320112475SJoe Perches		$formatted_email =~ s/$address.*$//;
44420112475SJoe Perches		$name = $formatted_email;
445*3705ce5bSJoe Perches		$name = trim($name);
44620112475SJoe Perches		$name =~ s/^\"|\"$//g;
44720112475SJoe Perches		# If there's a name left after stripping spaces and
44820112475SJoe Perches		# leading quotes, and the address doesn't have both
44920112475SJoe Perches		# leading and trailing angle brackets, the address
45020112475SJoe Perches		# is invalid. ie:
45120112475SJoe Perches		#   "joe smith [email protected]" bad
45220112475SJoe Perches		#   "joe smith <[email protected]" bad
45320112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
45420112475SJoe Perches			$name = "";
45520112475SJoe Perches			$address = "";
45620112475SJoe Perches			$comment = "";
45720112475SJoe Perches		}
45820112475SJoe Perches	}
45920112475SJoe Perches
460*3705ce5bSJoe Perches	$name = trim($name);
46120112475SJoe Perches	$name =~ s/^\"|\"$//g;
462*3705ce5bSJoe Perches	$address = trim($address);
46320112475SJoe Perches	$address =~ s/^\<|\>$//g;
46420112475SJoe Perches
46520112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
46620112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
46720112475SJoe Perches		$name = "\"$name\"";
46820112475SJoe Perches	}
46920112475SJoe Perches
47020112475SJoe Perches	return ($name, $address, $comment);
47120112475SJoe Perches}
47220112475SJoe Perches
47320112475SJoe Perchessub format_email {
47420112475SJoe Perches	my ($name, $address) = @_;
47520112475SJoe Perches
47620112475SJoe Perches	my $formatted_email;
47720112475SJoe Perches
478*3705ce5bSJoe Perches	$name = trim($name);
47920112475SJoe Perches	$name =~ s/^\"|\"$//g;
480*3705ce5bSJoe Perches	$address = trim($address);
48120112475SJoe Perches
48220112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
48320112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
48420112475SJoe Perches		$name = "\"$name\"";
48520112475SJoe Perches	}
48620112475SJoe Perches
48720112475SJoe Perches	if ("$name" eq "") {
48820112475SJoe Perches		$formatted_email = "$address";
48920112475SJoe Perches	} else {
49020112475SJoe Perches		$formatted_email = "$name <$address>";
49120112475SJoe Perches	}
49220112475SJoe Perches
49320112475SJoe Perches	return $formatted_email;
49420112475SJoe Perches}
49520112475SJoe Perches
496000d1cc1SJoe Perchessub which_conf {
497000d1cc1SJoe Perches	my ($conf) = @_;
498000d1cc1SJoe Perches
499000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
500000d1cc1SJoe Perches		if (-e "$path/$conf") {
501000d1cc1SJoe Perches			return "$path/$conf";
502000d1cc1SJoe Perches		}
503000d1cc1SJoe Perches	}
504000d1cc1SJoe Perches
505000d1cc1SJoe Perches	return "";
506000d1cc1SJoe Perches}
507000d1cc1SJoe Perches
5080a920b5bSAndy Whitcroftsub expand_tabs {
5090a920b5bSAndy Whitcroft	my ($str) = @_;
5100a920b5bSAndy Whitcroft
5110a920b5bSAndy Whitcroft	my $res = '';
5120a920b5bSAndy Whitcroft	my $n = 0;
5130a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
5140a920b5bSAndy Whitcroft		if ($c eq "\t") {
5150a920b5bSAndy Whitcroft			$res .= ' ';
5160a920b5bSAndy Whitcroft			$n++;
5170a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
5180a920b5bSAndy Whitcroft				$res .= ' ';
5190a920b5bSAndy Whitcroft			}
5200a920b5bSAndy Whitcroft			next;
5210a920b5bSAndy Whitcroft		}
5220a920b5bSAndy Whitcroft		$res .= $c;
5230a920b5bSAndy Whitcroft		$n++;
5240a920b5bSAndy Whitcroft	}
5250a920b5bSAndy Whitcroft
5260a920b5bSAndy Whitcroft	return $res;
5270a920b5bSAndy Whitcroft}
5286c72ffaaSAndy Whitcroftsub copy_spacing {
529773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
5306c72ffaaSAndy Whitcroft	return $res;
5316c72ffaaSAndy Whitcroft}
5320a920b5bSAndy Whitcroft
5334a0df2efSAndy Whitcroftsub line_stats {
5344a0df2efSAndy Whitcroft	my ($line) = @_;
5354a0df2efSAndy Whitcroft
5364a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
5374a0df2efSAndy Whitcroft	$line =~ s/^.//;
5384a0df2efSAndy Whitcroft	$line = expand_tabs($line);
5394a0df2efSAndy Whitcroft
5404a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
5414a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
5424a0df2efSAndy Whitcroft
5434a0df2efSAndy Whitcroft	return (length($line), length($white));
5444a0df2efSAndy Whitcroft}
5454a0df2efSAndy Whitcroft
546773647a0SAndy Whitcroftmy $sanitise_quote = '';
547773647a0SAndy Whitcroft
548773647a0SAndy Whitcroftsub sanitise_line_reset {
549773647a0SAndy Whitcroft	my ($in_comment) = @_;
550773647a0SAndy Whitcroft
551773647a0SAndy Whitcroft	if ($in_comment) {
552773647a0SAndy Whitcroft		$sanitise_quote = '*/';
553773647a0SAndy Whitcroft	} else {
554773647a0SAndy Whitcroft		$sanitise_quote = '';
555773647a0SAndy Whitcroft	}
556773647a0SAndy Whitcroft}
55700df344fSAndy Whitcroftsub sanitise_line {
55800df344fSAndy Whitcroft	my ($line) = @_;
55900df344fSAndy Whitcroft
56000df344fSAndy Whitcroft	my $res = '';
56100df344fSAndy Whitcroft	my $l = '';
56200df344fSAndy Whitcroft
563c2fdda0dSAndy Whitcroft	my $qlen = 0;
564773647a0SAndy Whitcroft	my $off = 0;
565773647a0SAndy Whitcroft	my $c;
56600df344fSAndy Whitcroft
567773647a0SAndy Whitcroft	# Always copy over the diff marker.
568773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
569773647a0SAndy Whitcroft
570773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
571773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
572773647a0SAndy Whitcroft
573773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
574773647a0SAndy Whitcroft		# and end, all to $;.
575773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
576773647a0SAndy Whitcroft			$sanitise_quote = '*/';
577773647a0SAndy Whitcroft
578773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
579773647a0SAndy Whitcroft			$off++;
58000df344fSAndy Whitcroft			next;
581773647a0SAndy Whitcroft		}
58281bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
583773647a0SAndy Whitcroft			$sanitise_quote = '';
584773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
585773647a0SAndy Whitcroft			$off++;
586773647a0SAndy Whitcroft			next;
587773647a0SAndy Whitcroft		}
588113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
589113f04a8SDaniel Walker			$sanitise_quote = '//';
590113f04a8SDaniel Walker
591113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
592113f04a8SDaniel Walker			$off++;
593113f04a8SDaniel Walker			next;
594113f04a8SDaniel Walker		}
595773647a0SAndy Whitcroft
596773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
597773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
598773647a0SAndy Whitcroft		    $c eq "\\") {
599773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
600773647a0SAndy Whitcroft			$off++;
601773647a0SAndy Whitcroft			next;
602773647a0SAndy Whitcroft		}
603773647a0SAndy Whitcroft		# Regular quotes.
604773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
605773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
606773647a0SAndy Whitcroft				$sanitise_quote = $c;
607773647a0SAndy Whitcroft
608773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
609773647a0SAndy Whitcroft				next;
610773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
611773647a0SAndy Whitcroft				$sanitise_quote = '';
61200df344fSAndy Whitcroft			}
61300df344fSAndy Whitcroft		}
614773647a0SAndy Whitcroft
615fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
616773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
617773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
618113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
619113f04a8SDaniel Walker			substr($res, $off, 1, $;);
620773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
621773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
62200df344fSAndy Whitcroft		} else {
623773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
62400df344fSAndy Whitcroft		}
625c2fdda0dSAndy Whitcroft	}
626c2fdda0dSAndy Whitcroft
627113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
628113f04a8SDaniel Walker		$sanitise_quote = '';
629113f04a8SDaniel Walker	}
630113f04a8SDaniel Walker
631c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
632c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
633c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
634c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
635c2fdda0dSAndy Whitcroft
636c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
637c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
638c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
639c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
640c2fdda0dSAndy Whitcroft	}
641c2fdda0dSAndy Whitcroft
64200df344fSAndy Whitcroft	return $res;
64300df344fSAndy Whitcroft}
64400df344fSAndy Whitcroft
645a6962d72SJoe Perchessub get_quoted_string {
646a6962d72SJoe Perches	my ($line, $rawline) = @_;
647a6962d72SJoe Perches
648a6962d72SJoe Perches	return "" if ($line !~ m/(\"[X]+\")/g);
649a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
650a6962d72SJoe Perches}
651a6962d72SJoe Perches
6528905a67cSAndy Whitcroftsub ctx_statement_block {
6538905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
6548905a67cSAndy Whitcroft	my $line = $linenr - 1;
6558905a67cSAndy Whitcroft	my $blk = '';
6568905a67cSAndy Whitcroft	my $soff = $off;
6578905a67cSAndy Whitcroft	my $coff = $off - 1;
658773647a0SAndy Whitcroft	my $coff_set = 0;
6598905a67cSAndy Whitcroft
66013214adfSAndy Whitcroft	my $loff = 0;
66113214adfSAndy Whitcroft
6628905a67cSAndy Whitcroft	my $type = '';
6638905a67cSAndy Whitcroft	my $level = 0;
664a2750645SAndy Whitcroft	my @stack = ();
665cf655043SAndy Whitcroft	my $p;
6668905a67cSAndy Whitcroft	my $c;
6678905a67cSAndy Whitcroft	my $len = 0;
66813214adfSAndy Whitcroft
66913214adfSAndy Whitcroft	my $remainder;
6708905a67cSAndy Whitcroft	while (1) {
671a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
672a2750645SAndy Whitcroft
673773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
6748905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
6758905a67cSAndy Whitcroft		# context.
6768905a67cSAndy Whitcroft		if ($off >= $len) {
6778905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
678dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
679c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
6808905a67cSAndy Whitcroft				$remain--;
68113214adfSAndy Whitcroft				$loff = $len;
682c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
6838905a67cSAndy Whitcroft				$len = length($blk);
6848905a67cSAndy Whitcroft				$line++;
6858905a67cSAndy Whitcroft				last;
6868905a67cSAndy Whitcroft			}
6878905a67cSAndy Whitcroft			# Bail if there is no further context.
6888905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
68913214adfSAndy Whitcroft			if ($off >= $len) {
6908905a67cSAndy Whitcroft				last;
6918905a67cSAndy Whitcroft			}
692f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
693f74bd194SAndy Whitcroft				$level++;
694f74bd194SAndy Whitcroft				$type = '#';
695f74bd194SAndy Whitcroft			}
6968905a67cSAndy Whitcroft		}
697cf655043SAndy Whitcroft		$p = $c;
6988905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
69913214adfSAndy Whitcroft		$remainder = substr($blk, $off);
7008905a67cSAndy Whitcroft
701773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
7024635f4fbSAndy Whitcroft
7034635f4fbSAndy Whitcroft		# Handle nested #if/#else.
7044635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
7054635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
7064635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
7074635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
7084635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
7094635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
7104635f4fbSAndy Whitcroft		}
7114635f4fbSAndy Whitcroft
7128905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
7138905a67cSAndy Whitcroft		# outermost level.
7148905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
7158905a67cSAndy Whitcroft			last;
7168905a67cSAndy Whitcroft		}
7178905a67cSAndy Whitcroft
71813214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
719773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
720773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
721773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
722773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
723773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
724773647a0SAndy Whitcroft			$coff_set = 1;
725773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
726773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
72713214adfSAndy Whitcroft		}
72813214adfSAndy Whitcroft
7298905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
7308905a67cSAndy Whitcroft			$level++;
7318905a67cSAndy Whitcroft			$type = '(';
7328905a67cSAndy Whitcroft		}
7338905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
7348905a67cSAndy Whitcroft			$level--;
7358905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
7368905a67cSAndy Whitcroft
7378905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
7388905a67cSAndy Whitcroft				$coff = $off;
739773647a0SAndy Whitcroft				$coff_set = 1;
740773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
7418905a67cSAndy Whitcroft			}
7428905a67cSAndy Whitcroft		}
7438905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
7448905a67cSAndy Whitcroft			$level++;
7458905a67cSAndy Whitcroft			$type = '{';
7468905a67cSAndy Whitcroft		}
7478905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
7488905a67cSAndy Whitcroft			$level--;
7498905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
7508905a67cSAndy Whitcroft
7518905a67cSAndy Whitcroft			if ($level == 0) {
752b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
753b998e001SPatrick Pannuto					$off++;
754b998e001SPatrick Pannuto				}
7558905a67cSAndy Whitcroft				last;
7568905a67cSAndy Whitcroft			}
7578905a67cSAndy Whitcroft		}
758f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
759f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
760f74bd194SAndy Whitcroft			$level--;
761f74bd194SAndy Whitcroft			$type = '';
762f74bd194SAndy Whitcroft			$off++;
763f74bd194SAndy Whitcroft			last;
764f74bd194SAndy Whitcroft		}
7658905a67cSAndy Whitcroft		$off++;
7668905a67cSAndy Whitcroft	}
767a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
76813214adfSAndy Whitcroft	if ($off == $len) {
769a3bb97a7SAndy Whitcroft		$loff = $len + 1;
77013214adfSAndy Whitcroft		$line++;
77113214adfSAndy Whitcroft		$remain--;
77213214adfSAndy Whitcroft	}
7738905a67cSAndy Whitcroft
7748905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
7758905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
7768905a67cSAndy Whitcroft
7778905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
7788905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
7798905a67cSAndy Whitcroft
780773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
78113214adfSAndy Whitcroft
78213214adfSAndy Whitcroft	return ($statement, $condition,
78313214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
78413214adfSAndy Whitcroft}
78513214adfSAndy Whitcroft
786cf655043SAndy Whitcroftsub statement_lines {
787cf655043SAndy Whitcroft	my ($stmt) = @_;
788cf655043SAndy Whitcroft
789cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
790cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
791cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
792cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
793cf655043SAndy Whitcroft
794cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
795cf655043SAndy Whitcroft
796cf655043SAndy Whitcroft	return $#stmt_lines + 2;
797cf655043SAndy Whitcroft}
798cf655043SAndy Whitcroft
799cf655043SAndy Whitcroftsub statement_rawlines {
800cf655043SAndy Whitcroft	my ($stmt) = @_;
801cf655043SAndy Whitcroft
802cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
803cf655043SAndy Whitcroft
804cf655043SAndy Whitcroft	return $#stmt_lines + 2;
805cf655043SAndy Whitcroft}
806cf655043SAndy Whitcroft
807cf655043SAndy Whitcroftsub statement_block_size {
808cf655043SAndy Whitcroft	my ($stmt) = @_;
809cf655043SAndy Whitcroft
810cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
811cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
812cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
813cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
814cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
815cf655043SAndy Whitcroft
816cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
817cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
818cf655043SAndy Whitcroft
819cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
820cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
821cf655043SAndy Whitcroft
822cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
823cf655043SAndy Whitcroft		return $stmt_lines;
824cf655043SAndy Whitcroft	} else {
825cf655043SAndy Whitcroft		return $stmt_statements;
826cf655043SAndy Whitcroft	}
827cf655043SAndy Whitcroft}
828cf655043SAndy Whitcroft
82913214adfSAndy Whitcroftsub ctx_statement_full {
83013214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
83113214adfSAndy Whitcroft	my ($statement, $condition, $level);
83213214adfSAndy Whitcroft
83313214adfSAndy Whitcroft	my (@chunks);
83413214adfSAndy Whitcroft
835cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
83613214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
83713214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
838773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
83913214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
840cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
841cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
842cf655043SAndy Whitcroft	}
843cf655043SAndy Whitcroft
844cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
845cf655043SAndy Whitcroft	# could continue the statement.
846cf655043SAndy Whitcroft	for (;;) {
84713214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
84813214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
849cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
850773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
851cf655043SAndy Whitcroft		#print "C: push\n";
852cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
85313214adfSAndy Whitcroft	}
85413214adfSAndy Whitcroft
85513214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
8568905a67cSAndy Whitcroft}
8578905a67cSAndy Whitcroft
8584a0df2efSAndy Whitcroftsub ctx_block_get {
859f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
8604a0df2efSAndy Whitcroft	my $line;
8614a0df2efSAndy Whitcroft	my $start = $linenr - 1;
8624a0df2efSAndy Whitcroft	my $blk = '';
8634a0df2efSAndy Whitcroft	my @o;
8644a0df2efSAndy Whitcroft	my @c;
8654a0df2efSAndy Whitcroft	my @res = ();
8664a0df2efSAndy Whitcroft
867f0a594c1SAndy Whitcroft	my $level = 0;
8684635f4fbSAndy Whitcroft	my @stack = ($level);
86900df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
87000df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
87100df344fSAndy Whitcroft		$remain--;
87200df344fSAndy Whitcroft
87300df344fSAndy Whitcroft		$blk .= $rawlines[$line];
8744635f4fbSAndy Whitcroft
8754635f4fbSAndy Whitcroft		# Handle nested #if/#else.
87601464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
8774635f4fbSAndy Whitcroft			push(@stack, $level);
87801464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
8794635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
88001464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
8814635f4fbSAndy Whitcroft			$level = pop(@stack);
8824635f4fbSAndy Whitcroft		}
8834635f4fbSAndy Whitcroft
88401464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
885f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
886f0a594c1SAndy Whitcroft			if ($off > 0) {
887f0a594c1SAndy Whitcroft				$off--;
888f0a594c1SAndy Whitcroft				next;
889f0a594c1SAndy Whitcroft			}
8904a0df2efSAndy Whitcroft
891f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
892f0a594c1SAndy Whitcroft				$level--;
893f0a594c1SAndy Whitcroft				last if ($level == 0);
894f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
895f0a594c1SAndy Whitcroft				$level++;
896f0a594c1SAndy Whitcroft			}
897f0a594c1SAndy Whitcroft		}
8984a0df2efSAndy Whitcroft
899f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
90000df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
9014a0df2efSAndy Whitcroft		}
9024a0df2efSAndy Whitcroft
903f0a594c1SAndy Whitcroft		last if ($level == 0);
9044a0df2efSAndy Whitcroft	}
9054a0df2efSAndy Whitcroft
906f0a594c1SAndy Whitcroft	return ($level, @res);
9074a0df2efSAndy Whitcroft}
9084a0df2efSAndy Whitcroftsub ctx_block_outer {
9094a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
9104a0df2efSAndy Whitcroft
911f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
912f0a594c1SAndy Whitcroft	return @r;
9134a0df2efSAndy Whitcroft}
9144a0df2efSAndy Whitcroftsub ctx_block {
9154a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
9164a0df2efSAndy Whitcroft
917f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
918f0a594c1SAndy Whitcroft	return @r;
919653d4876SAndy Whitcroft}
920653d4876SAndy Whitcroftsub ctx_statement {
921f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
922f0a594c1SAndy Whitcroft
923f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
924f0a594c1SAndy Whitcroft	return @r;
925f0a594c1SAndy Whitcroft}
926f0a594c1SAndy Whitcroftsub ctx_block_level {
927653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
928653d4876SAndy Whitcroft
929f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
9304a0df2efSAndy Whitcroft}
9319c0ca6f9SAndy Whitcroftsub ctx_statement_level {
9329c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
9339c0ca6f9SAndy Whitcroft
9349c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
9359c0ca6f9SAndy Whitcroft}
9364a0df2efSAndy Whitcroft
9374a0df2efSAndy Whitcroftsub ctx_locate_comment {
9384a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
9394a0df2efSAndy Whitcroft
9404a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
941beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
9424a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
9434a0df2efSAndy Whitcroft
9444a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
9454a0df2efSAndy Whitcroft	# comment.
9464a0df2efSAndy Whitcroft	my $in_comment = 0;
9474a0df2efSAndy Whitcroft	$current_comment = '';
9484a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
94900df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
95000df344fSAndy Whitcroft		#warn "           $line\n";
9514a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
9524a0df2efSAndy Whitcroft			$in_comment = 1;
9534a0df2efSAndy Whitcroft		}
9544a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
9554a0df2efSAndy Whitcroft			$in_comment = 1;
9564a0df2efSAndy Whitcroft		}
9574a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
9584a0df2efSAndy Whitcroft			$current_comment = '';
9594a0df2efSAndy Whitcroft		}
9604a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
9614a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
9624a0df2efSAndy Whitcroft			$in_comment = 0;
9634a0df2efSAndy Whitcroft		}
9644a0df2efSAndy Whitcroft	}
9654a0df2efSAndy Whitcroft
9664a0df2efSAndy Whitcroft	chomp($current_comment);
9674a0df2efSAndy Whitcroft	return($current_comment);
9684a0df2efSAndy Whitcroft}
9694a0df2efSAndy Whitcroftsub ctx_has_comment {
9704a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
9714a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
9724a0df2efSAndy Whitcroft
97300df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
9744a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
9754a0df2efSAndy Whitcroft
9764a0df2efSAndy Whitcroft	return ($cmt ne '');
9774a0df2efSAndy Whitcroft}
9784a0df2efSAndy Whitcroft
9794d001e4dSAndy Whitcroftsub raw_line {
9804d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
9814d001e4dSAndy Whitcroft
9824d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
9834d001e4dSAndy Whitcroft	$cnt++;
9844d001e4dSAndy Whitcroft
9854d001e4dSAndy Whitcroft	my $line;
9864d001e4dSAndy Whitcroft	while ($cnt) {
9874d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
9884d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
9894d001e4dSAndy Whitcroft		$cnt--;
9904d001e4dSAndy Whitcroft	}
9914d001e4dSAndy Whitcroft
9924d001e4dSAndy Whitcroft	return $line;
9934d001e4dSAndy Whitcroft}
9944d001e4dSAndy Whitcroft
9950a920b5bSAndy Whitcroftsub cat_vet {
9960a920b5bSAndy Whitcroft	my ($vet) = @_;
9979c0ca6f9SAndy Whitcroft	my ($res, $coded);
9980a920b5bSAndy Whitcroft
9999c0ca6f9SAndy Whitcroft	$res = '';
10006c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
10016c72ffaaSAndy Whitcroft		$res .= $1;
10026c72ffaaSAndy Whitcroft		if ($2 ne '') {
10039c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
10046c72ffaaSAndy Whitcroft			$res .= $coded;
10056c72ffaaSAndy Whitcroft		}
10069c0ca6f9SAndy Whitcroft	}
10079c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
10080a920b5bSAndy Whitcroft
10099c0ca6f9SAndy Whitcroft	return $res;
10100a920b5bSAndy Whitcroft}
10110a920b5bSAndy Whitcroft
1012c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1013cf655043SAndy Whitcroftmy $av_pending;
1014c2fdda0dSAndy Whitcroftmy @av_paren_type;
10151f65f947SAndy Whitcroftmy $av_pend_colon;
1016c2fdda0dSAndy Whitcroft
1017c2fdda0dSAndy Whitcroftsub annotate_reset {
1018c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1019cf655043SAndy Whitcroft	$av_pending = '_';
1020cf655043SAndy Whitcroft	@av_paren_type = ('E');
10211f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1022c2fdda0dSAndy Whitcroft}
1023c2fdda0dSAndy Whitcroft
10246c72ffaaSAndy Whitcroftsub annotate_values {
10256c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
10266c72ffaaSAndy Whitcroft
10276c72ffaaSAndy Whitcroft	my $res;
10281f65f947SAndy Whitcroft	my $var = '_' x length($stream);
10296c72ffaaSAndy Whitcroft	my $cur = $stream;
10306c72ffaaSAndy Whitcroft
1031c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
10326c72ffaaSAndy Whitcroft
10336c72ffaaSAndy Whitcroft	while (length($cur)) {
1034773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1035cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1036171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
10376c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1038c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1039c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1040cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1041c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
10426c72ffaaSAndy Whitcroft			}
10436c72ffaaSAndy Whitcroft
1044c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
10459446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
10469446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1047addcdceaSAndy Whitcroft			$type = 'c';
10489446ef56SAndy Whitcroft
1049e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1050c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
10516c72ffaaSAndy Whitcroft			$type = 'T';
10526c72ffaaSAndy Whitcroft
1053389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1054389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1055389a2fe5SAndy Whitcroft			$type = 'T';
1056389a2fe5SAndy Whitcroft
1057c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1058171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1059c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1060171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1061171ae1a4SAndy Whitcroft			if ($2 ne '') {
1062cf655043SAndy Whitcroft				$av_pending = 'N';
1063171ae1a4SAndy Whitcroft			}
1064171ae1a4SAndy Whitcroft			$type = 'E';
1065171ae1a4SAndy Whitcroft
1066c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1067171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1068171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1069171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
10706c72ffaaSAndy Whitcroft
1071c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1072cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1073c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1074cf655043SAndy Whitcroft
1075cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1076cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1077171ae1a4SAndy Whitcroft			$type = 'E';
1078cf655043SAndy Whitcroft
1079c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1080cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1081cf655043SAndy Whitcroft			$av_preprocessor = 1;
1082cf655043SAndy Whitcroft
1083cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1084cf655043SAndy Whitcroft
1085171ae1a4SAndy Whitcroft			$type = 'E';
1086cf655043SAndy Whitcroft
1087c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1088cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1089cf655043SAndy Whitcroft
1090cf655043SAndy Whitcroft			$av_preprocessor = 1;
1091cf655043SAndy Whitcroft
1092cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1093cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1094cf655043SAndy Whitcroft			pop(@av_paren_type);
1095cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1096171ae1a4SAndy Whitcroft			$type = 'E';
10976c72ffaaSAndy Whitcroft
10986c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1099c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
11006c72ffaaSAndy Whitcroft
1101171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1102171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1103171ae1a4SAndy Whitcroft			$av_pending = $type;
1104171ae1a4SAndy Whitcroft			$type = 'N';
1105171ae1a4SAndy Whitcroft
11066c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1107c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
11086c72ffaaSAndy Whitcroft			if (defined $2) {
1109cf655043SAndy Whitcroft				$av_pending = 'V';
11106c72ffaaSAndy Whitcroft			}
11116c72ffaaSAndy Whitcroft			$type = 'N';
11126c72ffaaSAndy Whitcroft
111314b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1114c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
111514b111c1SAndy Whitcroft			$av_pending = 'E';
11166c72ffaaSAndy Whitcroft			$type = 'N';
11176c72ffaaSAndy Whitcroft
11181f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
11191f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
11201f65f947SAndy Whitcroft			$av_pend_colon = 'C';
11211f65f947SAndy Whitcroft			$type = 'N';
11221f65f947SAndy Whitcroft
112314b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1124c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
11256c72ffaaSAndy Whitcroft			$type = 'N';
11266c72ffaaSAndy Whitcroft
11276c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1128c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1129cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1130cf655043SAndy Whitcroft			$av_pending = '_';
11316c72ffaaSAndy Whitcroft			$type = 'N';
11326c72ffaaSAndy Whitcroft
11336c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1134cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1135cf655043SAndy Whitcroft			if ($new_type ne '_') {
1136cf655043SAndy Whitcroft				$type = $new_type;
1137c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1138c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
11396c72ffaaSAndy Whitcroft			} else {
1140c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
11416c72ffaaSAndy Whitcroft			}
11426c72ffaaSAndy Whitcroft
1143c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1144c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1145c8cb2ca3SAndy Whitcroft			$type = 'V';
1146cf655043SAndy Whitcroft			$av_pending = 'V';
11476c72ffaaSAndy Whitcroft
11488e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
11498e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
11501f65f947SAndy Whitcroft				$av_pend_colon = 'B';
11518e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
11528e761b04SAndy Whitcroft				$av_pend_colon = 'L';
11531f65f947SAndy Whitcroft			}
11541f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
11551f65f947SAndy Whitcroft			$type = 'V';
11561f65f947SAndy Whitcroft
11576c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1158c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
11596c72ffaaSAndy Whitcroft			$type = 'V';
11606c72ffaaSAndy Whitcroft
11616c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1162c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
11636c72ffaaSAndy Whitcroft			$type = 'N';
11646c72ffaaSAndy Whitcroft
1165cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1166c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
116713214adfSAndy Whitcroft			$type = 'E';
11681f65f947SAndy Whitcroft			$av_pend_colon = 'O';
116913214adfSAndy Whitcroft
11708e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
11718e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
11728e761b04SAndy Whitcroft			$type = 'C';
11738e761b04SAndy Whitcroft
11741f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
11751f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
11761f65f947SAndy Whitcroft			$type = 'N';
11771f65f947SAndy Whitcroft
11781f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
11791f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
11801f65f947SAndy Whitcroft
11811f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
11821f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
11831f65f947SAndy Whitcroft				$type = 'E';
11841f65f947SAndy Whitcroft			} else {
11851f65f947SAndy Whitcroft				$type = 'N';
11861f65f947SAndy Whitcroft			}
11871f65f947SAndy Whitcroft			$av_pend_colon = 'O';
11881f65f947SAndy Whitcroft
11898e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
119013214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
11916c72ffaaSAndy Whitcroft			$type = 'N';
11926c72ffaaSAndy Whitcroft
11930d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
119474048ed8SAndy Whitcroft			my $variant;
119574048ed8SAndy Whitcroft
119674048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
119774048ed8SAndy Whitcroft			if ($type eq 'V') {
119874048ed8SAndy Whitcroft				$variant = 'B';
119974048ed8SAndy Whitcroft			} else {
120074048ed8SAndy Whitcroft				$variant = 'U';
120174048ed8SAndy Whitcroft			}
120274048ed8SAndy Whitcroft
120374048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
120474048ed8SAndy Whitcroft			$type = 'N';
120574048ed8SAndy Whitcroft
12066c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1207c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
12086c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
12096c72ffaaSAndy Whitcroft				$type = 'N';
12106c72ffaaSAndy Whitcroft			}
12116c72ffaaSAndy Whitcroft
12126c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1213c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
12146c72ffaaSAndy Whitcroft		}
12156c72ffaaSAndy Whitcroft		if (defined $1) {
12166c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
12176c72ffaaSAndy Whitcroft			$res .= $type x length($1);
12186c72ffaaSAndy Whitcroft		}
12196c72ffaaSAndy Whitcroft	}
12206c72ffaaSAndy Whitcroft
12211f65f947SAndy Whitcroft	return ($res, $var);
12226c72ffaaSAndy Whitcroft}
12236c72ffaaSAndy Whitcroft
12248905a67cSAndy Whitcroftsub possible {
122513214adfSAndy Whitcroft	my ($possible, $line) = @_;
12269a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
12270776e594SAndy Whitcroft		^(?:
12280776e594SAndy Whitcroft			$Modifier|
12290776e594SAndy Whitcroft			$Storage|
12300776e594SAndy Whitcroft			$Type|
12319a974fdbSAndy Whitcroft			DEFINE_\S+
12329a974fdbSAndy Whitcroft		)$|
12339a974fdbSAndy Whitcroft		^(?:
12340776e594SAndy Whitcroft			goto|
12350776e594SAndy Whitcroft			return|
12360776e594SAndy Whitcroft			case|
12370776e594SAndy Whitcroft			else|
12380776e594SAndy Whitcroft			asm|__asm__|
123989a88353SAndy Whitcroft			do|
124089a88353SAndy Whitcroft			\#|
124189a88353SAndy Whitcroft			\#\#|
12429a974fdbSAndy Whitcroft		)(?:\s|$)|
12430776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
12449a974fdbSAndy Whitcroft	    )}x;
12459a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
12469a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1247c45dcabdSAndy Whitcroft		# Check for modifiers.
1248c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1249c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1250c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1251c45dcabdSAndy Whitcroft
1252c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1253c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1254d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
12559a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1256d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1257d2506586SAndy Whitcroft					push(@modifierList, $modifier);
1258d2506586SAndy Whitcroft				}
12599a974fdbSAndy Whitcroft			}
1260c45dcabdSAndy Whitcroft
1261c45dcabdSAndy Whitcroft		} else {
126213214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
12638905a67cSAndy Whitcroft			push(@typeList, $possible);
1264c45dcabdSAndy Whitcroft		}
12658905a67cSAndy Whitcroft		build_types();
12660776e594SAndy Whitcroft	} else {
12670776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
12688905a67cSAndy Whitcroft	}
12698905a67cSAndy Whitcroft}
12708905a67cSAndy Whitcroft
12716c72ffaaSAndy Whitcroftmy $prefix = '';
12726c72ffaaSAndy Whitcroft
1273000d1cc1SJoe Perchessub show_type {
1274000d1cc1SJoe Perches       return !defined $ignore_type{$_[0]};
1275000d1cc1SJoe Perches}
1276000d1cc1SJoe Perches
1277f0a594c1SAndy Whitcroftsub report {
1278000d1cc1SJoe Perches	if (!show_type($_[1]) ||
1279000d1cc1SJoe Perches	    (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) {
1280773647a0SAndy Whitcroft		return 0;
1281773647a0SAndy Whitcroft	}
1282000d1cc1SJoe Perches	my $line;
1283000d1cc1SJoe Perches	if ($show_types) {
1284000d1cc1SJoe Perches		$line = "$prefix$_[0]:$_[1]: $_[2]\n";
1285000d1cc1SJoe Perches	} else {
1286000d1cc1SJoe Perches		$line = "$prefix$_[0]: $_[2]\n";
1287000d1cc1SJoe Perches	}
12888905a67cSAndy Whitcroft	$line = (split('\n', $line))[0] . "\n" if ($terse);
12898905a67cSAndy Whitcroft
129013214adfSAndy Whitcroft	push(our @report, $line);
1291773647a0SAndy Whitcroft
1292773647a0SAndy Whitcroft	return 1;
1293f0a594c1SAndy Whitcroft}
1294f0a594c1SAndy Whitcroftsub report_dump {
129513214adfSAndy Whitcroft	our @report;
1296f0a594c1SAndy Whitcroft}
1297000d1cc1SJoe Perches
1298de7d4f0eSAndy Whitcroftsub ERROR {
1299000d1cc1SJoe Perches	if (report("ERROR", $_[0], $_[1])) {
1300de7d4f0eSAndy Whitcroft		our $clean = 0;
13016c72ffaaSAndy Whitcroft		our $cnt_error++;
1302*3705ce5bSJoe Perches		return 1;
1303de7d4f0eSAndy Whitcroft	}
1304*3705ce5bSJoe Perches	return 0;
1305773647a0SAndy Whitcroft}
1306de7d4f0eSAndy Whitcroftsub WARN {
1307000d1cc1SJoe Perches	if (report("WARNING", $_[0], $_[1])) {
1308de7d4f0eSAndy Whitcroft		our $clean = 0;
13096c72ffaaSAndy Whitcroft		our $cnt_warn++;
1310*3705ce5bSJoe Perches		return 1;
1311de7d4f0eSAndy Whitcroft	}
1312*3705ce5bSJoe Perches	return 0;
1313773647a0SAndy Whitcroft}
1314de7d4f0eSAndy Whitcroftsub CHK {
1315000d1cc1SJoe Perches	if ($check && report("CHECK", $_[0], $_[1])) {
1316de7d4f0eSAndy Whitcroft		our $clean = 0;
13176c72ffaaSAndy Whitcroft		our $cnt_chk++;
1318*3705ce5bSJoe Perches		return 1;
13196c72ffaaSAndy Whitcroft	}
1320*3705ce5bSJoe Perches	return 0;
1321de7d4f0eSAndy Whitcroft}
1322de7d4f0eSAndy Whitcroft
13236ecd9674SAndy Whitcroftsub check_absolute_file {
13246ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
13256ecd9674SAndy Whitcroft	my $file = $absolute;
13266ecd9674SAndy Whitcroft
13276ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
13286ecd9674SAndy Whitcroft
13296ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
13306ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
13316ecd9674SAndy Whitcroft		if (-f "$root/$file") {
13326ecd9674SAndy Whitcroft			##print "file<$file>\n";
13336ecd9674SAndy Whitcroft			last;
13346ecd9674SAndy Whitcroft		}
13356ecd9674SAndy Whitcroft	}
13366ecd9674SAndy Whitcroft	if (! -f _)  {
13376ecd9674SAndy Whitcroft		return 0;
13386ecd9674SAndy Whitcroft	}
13396ecd9674SAndy Whitcroft
13406ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
13416ecd9674SAndy Whitcroft	my $prefix = $absolute;
13426ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
13436ecd9674SAndy Whitcroft
13446ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
13456ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
1346000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
1347000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
13486ecd9674SAndy Whitcroft	}
13496ecd9674SAndy Whitcroft}
13506ecd9674SAndy Whitcroft
1351*3705ce5bSJoe Perchessub trim {
1352*3705ce5bSJoe Perches	my ($string) = @_;
1353*3705ce5bSJoe Perches
1354*3705ce5bSJoe Perches	$string =~ s/(^\s+|\s+$)//g;
1355*3705ce5bSJoe Perches
1356*3705ce5bSJoe Perches	return $string;
1357*3705ce5bSJoe Perches}
1358*3705ce5bSJoe Perches
1359*3705ce5bSJoe Perchessub tabify {
1360*3705ce5bSJoe Perches	my ($leading) = @_;
1361*3705ce5bSJoe Perches
1362*3705ce5bSJoe Perches	my $source_indent = 8;
1363*3705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
1364*3705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
1365*3705ce5bSJoe Perches
1366*3705ce5bSJoe Perches	#convert leading spaces to tabs
1367*3705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
1368*3705ce5bSJoe Perches	#Remove spaces before a tab
1369*3705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
1370*3705ce5bSJoe Perches
1371*3705ce5bSJoe Perches	return "$leading";
1372*3705ce5bSJoe Perches}
1373*3705ce5bSJoe Perches
1374d1fe9c09SJoe Perchessub pos_last_openparen {
1375d1fe9c09SJoe Perches	my ($line) = @_;
1376d1fe9c09SJoe Perches
1377d1fe9c09SJoe Perches	my $pos = 0;
1378d1fe9c09SJoe Perches
1379d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
1380d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
1381d1fe9c09SJoe Perches
1382d1fe9c09SJoe Perches	my $last_openparen = 0;
1383d1fe9c09SJoe Perches
1384d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
1385d1fe9c09SJoe Perches		return -1;
1386d1fe9c09SJoe Perches	}
1387d1fe9c09SJoe Perches
1388d1fe9c09SJoe Perches	my $len = length($line);
1389d1fe9c09SJoe Perches
1390d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
1391d1fe9c09SJoe Perches		my $string = substr($line, $pos);
1392d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
1393d1fe9c09SJoe Perches			$pos += length($1) - 1;
1394d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
1395d1fe9c09SJoe Perches			$last_openparen = $pos;
1396d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
1397d1fe9c09SJoe Perches			last;
1398d1fe9c09SJoe Perches		}
1399d1fe9c09SJoe Perches	}
1400d1fe9c09SJoe Perches
1401d1fe9c09SJoe Perches	return $last_openparen + 1;
1402d1fe9c09SJoe Perches}
1403d1fe9c09SJoe Perches
14040a920b5bSAndy Whitcroftsub process {
14050a920b5bSAndy Whitcroft	my $filename = shift;
14060a920b5bSAndy Whitcroft
14070a920b5bSAndy Whitcroft	my $linenr=0;
14080a920b5bSAndy Whitcroft	my $prevline="";
1409c2fdda0dSAndy Whitcroft	my $prevrawline="";
14100a920b5bSAndy Whitcroft	my $stashline="";
1411c2fdda0dSAndy Whitcroft	my $stashrawline="";
14120a920b5bSAndy Whitcroft
14134a0df2efSAndy Whitcroft	my $length;
14140a920b5bSAndy Whitcroft	my $indent;
14150a920b5bSAndy Whitcroft	my $previndent=0;
14160a920b5bSAndy Whitcroft	my $stashindent=0;
14170a920b5bSAndy Whitcroft
1418de7d4f0eSAndy Whitcroft	our $clean = 1;
14190a920b5bSAndy Whitcroft	my $signoff = 0;
14200a920b5bSAndy Whitcroft	my $is_patch = 0;
14210a920b5bSAndy Whitcroft
142215662b3eSJoe Perches	my $in_header_lines = 1;
142315662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
142415662b3eSJoe Perches
1425fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
1426fa64205dSPasi Savanainen
142713214adfSAndy Whitcroft	our @report = ();
14286c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
14296c72ffaaSAndy Whitcroft	our $cnt_error = 0;
14306c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
14316c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
14326c72ffaaSAndy Whitcroft
14330a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
14340a920b5bSAndy Whitcroft	my $realfile = '';
14350a920b5bSAndy Whitcroft	my $realline = 0;
14360a920b5bSAndy Whitcroft	my $realcnt = 0;
14370a920b5bSAndy Whitcroft	my $here = '';
14380a920b5bSAndy Whitcroft	my $in_comment = 0;
1439c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
14400a920b5bSAndy Whitcroft	my $first_line = 0;
14411e855726SWolfram Sang	my $p1_prefix = '';
14420a920b5bSAndy Whitcroft
144313214adfSAndy Whitcroft	my $prev_values = 'E';
144413214adfSAndy Whitcroft
144513214adfSAndy Whitcroft	# suppression flags
1446773647a0SAndy Whitcroft	my %suppress_ifbraces;
1447170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
14482b474a1aSAndy Whitcroft	my %suppress_export;
14493e469cdcSAndy Whitcroft	my $suppress_statement = 0;
1450653d4876SAndy Whitcroft
1451323c1260SJoe Perches	my %camelcase = ();
1452323c1260SJoe Perches
1453c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
1454de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
1455c2fdda0dSAndy Whitcroft	#
1456de7d4f0eSAndy Whitcroft	my @setup_docs = ();
1457de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
1458773647a0SAndy Whitcroft
1459773647a0SAndy Whitcroft	sanitise_line_reset();
1460c2fdda0dSAndy Whitcroft	my $line;
1461c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
1462773647a0SAndy Whitcroft		$linenr++;
1463773647a0SAndy Whitcroft		$line = $rawline;
1464c2fdda0dSAndy Whitcroft
1465*3705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
1466*3705ce5bSJoe Perches
1467773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1468de7d4f0eSAndy Whitcroft			$setup_docs = 0;
1469de7d4f0eSAndy Whitcroft			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1470de7d4f0eSAndy Whitcroft				$setup_docs = 1;
1471de7d4f0eSAndy Whitcroft			}
1472773647a0SAndy Whitcroft			#next;
1473de7d4f0eSAndy Whitcroft		}
1474773647a0SAndy Whitcroft		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1475773647a0SAndy Whitcroft			$realline=$1-1;
1476773647a0SAndy Whitcroft			if (defined $2) {
1477773647a0SAndy Whitcroft				$realcnt=$3+1;
1478773647a0SAndy Whitcroft			} else {
1479773647a0SAndy Whitcroft				$realcnt=1+1;
1480773647a0SAndy Whitcroft			}
1481c45dcabdSAndy Whitcroft			$in_comment = 0;
1482773647a0SAndy Whitcroft
1483773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
1484773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
1485773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
1486773647a0SAndy Whitcroft			# at context start.
1487773647a0SAndy Whitcroft			my $edge;
148801fa9147SAndy Whitcroft			my $cnt = $realcnt;
148901fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
149001fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
149101fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
149201fa9147SAndy Whitcroft				$cnt--;
149301fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
1494721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
1495fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1496fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1497fae17daeSAndy Whitcroft					($edge) = $1;
1498fae17daeSAndy Whitcroft					last;
1499fae17daeSAndy Whitcroft				}
1500773647a0SAndy Whitcroft			}
1501773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
1502773647a0SAndy Whitcroft				$in_comment = 1;
1503773647a0SAndy Whitcroft			}
1504773647a0SAndy Whitcroft
1505773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
1506773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
1507773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
1508773647a0SAndy Whitcroft			if (!defined $edge &&
150983242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1510773647a0SAndy Whitcroft			{
1511773647a0SAndy Whitcroft				$in_comment = 1;
1512773647a0SAndy Whitcroft			}
1513773647a0SAndy Whitcroft
1514773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1515773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
1516773647a0SAndy Whitcroft
1517171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1518773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
1519171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
1520773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
1521773647a0SAndy Whitcroft		}
1522773647a0SAndy Whitcroft		push(@lines, $line);
1523773647a0SAndy Whitcroft
1524773647a0SAndy Whitcroft		if ($realcnt > 1) {
1525773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
1526773647a0SAndy Whitcroft		} else {
1527773647a0SAndy Whitcroft			$realcnt = 0;
1528773647a0SAndy Whitcroft		}
1529773647a0SAndy Whitcroft
1530773647a0SAndy Whitcroft		#print "==>$rawline\n";
1531773647a0SAndy Whitcroft		#print "-->$line\n";
1532de7d4f0eSAndy Whitcroft
1533de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
1534de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
1535de7d4f0eSAndy Whitcroft		}
1536de7d4f0eSAndy Whitcroft	}
1537de7d4f0eSAndy Whitcroft
15386c72ffaaSAndy Whitcroft	$prefix = '';
15396c72ffaaSAndy Whitcroft
1540773647a0SAndy Whitcroft	$realcnt = 0;
1541773647a0SAndy Whitcroft	$linenr = 0;
15420a920b5bSAndy Whitcroft	foreach my $line (@lines) {
15430a920b5bSAndy Whitcroft		$linenr++;
15440a920b5bSAndy Whitcroft
1545c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
15466c72ffaaSAndy Whitcroft
15470a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
15486c72ffaaSAndy Whitcroft		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
15490a920b5bSAndy Whitcroft			$is_patch = 1;
15504a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
15510a920b5bSAndy Whitcroft			$realline=$1-1;
15520a920b5bSAndy Whitcroft			if (defined $2) {
15530a920b5bSAndy Whitcroft				$realcnt=$3+1;
15540a920b5bSAndy Whitcroft			} else {
15550a920b5bSAndy Whitcroft				$realcnt=1+1;
15560a920b5bSAndy Whitcroft			}
1557c2fdda0dSAndy Whitcroft			annotate_reset();
155813214adfSAndy Whitcroft			$prev_values = 'E';
155913214adfSAndy Whitcroft
1560773647a0SAndy Whitcroft			%suppress_ifbraces = ();
1561170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
15622b474a1aSAndy Whitcroft			%suppress_export = ();
15633e469cdcSAndy Whitcroft			$suppress_statement = 0;
15640a920b5bSAndy Whitcroft			next;
15650a920b5bSAndy Whitcroft
15664a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
15674a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
15684a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
1569773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
15700a920b5bSAndy Whitcroft			$realline++;
1571d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
15720a920b5bSAndy Whitcroft
15734a0df2efSAndy Whitcroft			# Measure the line length and indent.
1574c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
15750a920b5bSAndy Whitcroft
15760a920b5bSAndy Whitcroft			# Track the previous line.
15770a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
15780a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
1579c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1580c2fdda0dSAndy Whitcroft
1581773647a0SAndy Whitcroft			#warn "line<$line>\n";
15826c72ffaaSAndy Whitcroft
1583d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
1584d8aaf121SAndy Whitcroft			$realcnt--;
15850a920b5bSAndy Whitcroft		}
15860a920b5bSAndy Whitcroft
1587cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
1588cc77cdcaSAndy Whitcroft
15890a920b5bSAndy Whitcroft#make up the handle for any error we report on this line
1590773647a0SAndy Whitcroft		$prefix = "$filename:$realline: " if ($emacs && $file);
1591773647a0SAndy Whitcroft		$prefix = "$filename:$linenr: " if ($emacs && !$file);
1592773647a0SAndy Whitcroft
15936c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
15946c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
1595773647a0SAndy Whitcroft
1596773647a0SAndy Whitcroft		# extract the filename as it passes
15973bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
15983bf9a009SRabin Vincent			$realfile = $1;
15993bf9a009SRabin Vincent			$realfile =~ s@^([^/]*)/@@;
1600270c49a0SJoe Perches			$in_commit_log = 0;
16013bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1602773647a0SAndy Whitcroft			$realfile = $1;
16031e855726SWolfram Sang			$realfile =~ s@^([^/]*)/@@;
1604270c49a0SJoe Perches			$in_commit_log = 0;
16051e855726SWolfram Sang
16061e855726SWolfram Sang			$p1_prefix = $1;
1607e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
1608e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
1609000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
1610000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
16111e855726SWolfram Sang			}
1612773647a0SAndy Whitcroft
1613c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
1614000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
1615000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1616773647a0SAndy Whitcroft			}
1617773647a0SAndy Whitcroft			next;
1618773647a0SAndy Whitcroft		}
1619773647a0SAndy Whitcroft
1620389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
16210a920b5bSAndy Whitcroft
1622c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
1623c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
1624c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
16250a920b5bSAndy Whitcroft
16266c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
16276c72ffaaSAndy Whitcroft
16283bf9a009SRabin Vincent# Check for incorrect file permissions
16293bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
16303bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
163104db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
163204db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
1633000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
1634000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
16353bf9a009SRabin Vincent			}
16363bf9a009SRabin Vincent		}
16373bf9a009SRabin Vincent
163820112475SJoe Perches# Check the patch for a signoff:
1639d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
16404a0df2efSAndy Whitcroft			$signoff++;
164115662b3eSJoe Perches			$in_commit_log = 0;
16420a920b5bSAndy Whitcroft		}
164320112475SJoe Perches
164420112475SJoe Perches# Check signature styles
1645270c49a0SJoe Perches		if (!$in_header_lines &&
1646ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
164720112475SJoe Perches			my $space_before = $1;
164820112475SJoe Perches			my $sign_off = $2;
164920112475SJoe Perches			my $space_after = $3;
165020112475SJoe Perches			my $email = $4;
165120112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
165220112475SJoe Perches
1653ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
1654ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
1655ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
1656ce0338dfSJoe Perches			}
165720112475SJoe Perches			if (defined $space_before && $space_before ne "") {
1658*3705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
1659*3705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
1660*3705ce5bSJoe Perches				    $fix) {
1661*3705ce5bSJoe Perches					$fixed[$linenr - 1] =
1662*3705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
1663*3705ce5bSJoe Perches				}
166420112475SJoe Perches			}
166520112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
1666*3705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
1667*3705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
1668*3705ce5bSJoe Perches				    $fix) {
1669*3705ce5bSJoe Perches					$fixed[$linenr - 1] =
1670*3705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
1671*3705ce5bSJoe Perches				}
1672*3705ce5bSJoe Perches
167320112475SJoe Perches			}
167420112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
1675*3705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
1676*3705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
1677*3705ce5bSJoe Perches				    $fix) {
1678*3705ce5bSJoe Perches					$fixed[$linenr - 1] =
1679*3705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
1680*3705ce5bSJoe Perches				}
168120112475SJoe Perches			}
168220112475SJoe Perches
168320112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
168420112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
168520112475SJoe Perches			if ($suggested_email eq "") {
1686000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
1687000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
168820112475SJoe Perches			} else {
168920112475SJoe Perches				my $dequoted = $suggested_email;
169020112475SJoe Perches				$dequoted =~ s/^"//;
169120112475SJoe Perches				$dequoted =~ s/" </ </;
169220112475SJoe Perches				# Don't force email to have quotes
169320112475SJoe Perches				# Allow just an angle bracketed address
169420112475SJoe Perches				if ("$dequoted$comment" ne $email &&
169520112475SJoe Perches				    "<$email_address>$comment" ne $email &&
169620112475SJoe Perches				    "$suggested_email$comment" ne $email) {
1697000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
1698000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
169920112475SJoe Perches				}
17000a920b5bSAndy Whitcroft			}
17010a920b5bSAndy Whitcroft		}
17020a920b5bSAndy Whitcroft
170300df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
17048905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1705000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
1706000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
17076c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
1708de7d4f0eSAndy Whitcroft		}
1709de7d4f0eSAndy Whitcroft
17106ecd9674SAndy Whitcroft# Check for absolute kernel paths.
17116ecd9674SAndy Whitcroft		if ($tree) {
17126ecd9674SAndy Whitcroft			while ($line =~ m{(?:^|\s)(/\S*)}g) {
17136ecd9674SAndy Whitcroft				my $file = $1;
17146ecd9674SAndy Whitcroft
17156ecd9674SAndy Whitcroft				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
17166ecd9674SAndy Whitcroft				    check_absolute_file($1, $herecurr)) {
17176ecd9674SAndy Whitcroft					#
17186ecd9674SAndy Whitcroft				} else {
17196ecd9674SAndy Whitcroft					check_absolute_file($file, $herecurr);
17206ecd9674SAndy Whitcroft				}
17216ecd9674SAndy Whitcroft			}
17226ecd9674SAndy Whitcroft		}
17236ecd9674SAndy Whitcroft
1724de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1725de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1726171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
1727171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1728171ae1a4SAndy Whitcroft
1729171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
1730171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1731171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
1732171ae1a4SAndy Whitcroft
173334d99219SJoe Perches			CHK("INVALID_UTF8",
1734000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
173500df344fSAndy Whitcroft		}
17360a920b5bSAndy Whitcroft
173715662b3eSJoe Perches# Check if it's the start of a commit log
173815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
173915662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
1740270c49a0SJoe Perches		    $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
174115662b3eSJoe Perches			$in_header_lines = 0;
174215662b3eSJoe Perches			$in_commit_log = 1;
174315662b3eSJoe Perches		}
174415662b3eSJoe Perches
1745fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
1746fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
1747fa64205dSPasi Savanainen		if ($in_header_lines &&
1748fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
1749fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
1750fa64205dSPasi Savanainen			$non_utf8_charset = 1;
1751fa64205dSPasi Savanainen		}
1752fa64205dSPasi Savanainen
1753fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
175415662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
1755fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
175615662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
175715662b3eSJoe Perches		}
175815662b3eSJoe Perches
175930670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
176030670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
176100df344fSAndy Whitcroft
17620a920b5bSAndy Whitcroft#trailing whitespace
17639c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
1764c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1765000d1cc1SJoe Perches			ERROR("DOS_LINE_ENDINGS",
1766000d1cc1SJoe Perches			      "DOS line endings\n" . $herevet);
17679c0ca6f9SAndy Whitcroft
1768c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1769c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1770*3705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
1771*3705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
1772*3705ce5bSJoe Perches			    $fix) {
1773*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*?)\s+$/$1/;
1774*3705ce5bSJoe Perches			}
1775*3705ce5bSJoe Perches
1776d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
17770a920b5bSAndy Whitcroft		}
17785368df20SAndy Whitcroft
17793354957aSAndi Kleen# check for Kconfig help text having a real description
17809fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
17819fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
17823354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
1783a1385803SAndy Whitcroft		    $line =~ /.\s*config\s+/) {
17843354957aSAndi Kleen			my $length = 0;
17859fe287d7SAndy Whitcroft			my $cnt = $realcnt;
17869fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
17879fe287d7SAndy Whitcroft			my $f;
1788a1385803SAndy Whitcroft			my $is_start = 0;
17899fe287d7SAndy Whitcroft			my $is_end = 0;
1790a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
17919fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
17929fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
17939fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
17949fe287d7SAndy Whitcroft
17959fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
1796a1385803SAndy Whitcroft
1797a1385803SAndy Whitcroft				if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) {
1798a1385803SAndy Whitcroft					$is_start = 1;
1799a1385803SAndy Whitcroft				} elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) {
1800a1385803SAndy Whitcroft					$length = -1;
1801a1385803SAndy Whitcroft				}
1802a1385803SAndy Whitcroft
18039fe287d7SAndy Whitcroft				$f =~ s/^.//;
18043354957aSAndi Kleen				$f =~ s/#.*//;
18053354957aSAndi Kleen				$f =~ s/^\s+//;
18063354957aSAndi Kleen				next if ($f =~ /^$/);
18079fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
18089fe287d7SAndy Whitcroft					$is_end = 1;
18099fe287d7SAndy Whitcroft					last;
18109fe287d7SAndy Whitcroft				}
18113354957aSAndi Kleen				$length++;
18123354957aSAndi Kleen			}
1813000d1cc1SJoe Perches			WARN("CONFIG_DESCRIPTION",
1814a1385803SAndy Whitcroft			     "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);
1815a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
18163354957aSAndi Kleen		}
18173354957aSAndi Kleen
18181ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
18191ba8dfd1SKees Cook		if ($realfile =~ /Kconfig/ &&
18201ba8dfd1SKees Cook		    $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
18211ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
18221ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
18231ba8dfd1SKees Cook		}
18241ba8dfd1SKees Cook
1825c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
1826c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
1827c68e5878SArnaud Lacombe			my $flag = $1;
1828c68e5878SArnaud Lacombe			my $replacement = {
1829c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
1830c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
1831c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
1832c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
1833c68e5878SArnaud Lacombe			};
1834c68e5878SArnaud Lacombe
1835c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
1836c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
1837c68e5878SArnaud Lacombe		}
1838c68e5878SArnaud Lacombe
18395368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
18405368df20SAndy Whitcroft		next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
18415368df20SAndy Whitcroft
18426cd7f386SJoe Perches#line length limit
1843c45dcabdSAndy Whitcroft		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1844f4c014c0SAndy Whitcroft		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
18450fccc622SJoe Perches		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
18468bbea968SJoe Perches		    $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
18476cd7f386SJoe Perches		    $length > $max_line_length)
1848c45dcabdSAndy Whitcroft		{
1849000d1cc1SJoe Perches			WARN("LONG_LINE",
18506cd7f386SJoe Perches			     "line over $max_line_length characters\n" . $herecurr);
18510a920b5bSAndy Whitcroft		}
18520a920b5bSAndy Whitcroft
1853ca56dc09SJosh Triplett# Check for user-visible strings broken across lines, which breaks the ability
1854ca56dc09SJosh Triplett# to grep for the string.  Limited to strings used as parameters (those
1855ca56dc09SJosh Triplett# following an open parenthesis), which almost completely eliminates false
1856ca56dc09SJosh Triplett# positives, as well as warning only once per parameter rather than once per
1857ca56dc09SJosh Triplett# line of the string.  Make an exception when the previous string ends in a
1858ca56dc09SJosh Triplett# newline (multiple lines in one string constant) or \n\t (common in inline
1859ca56dc09SJosh Triplett# assembly to indent the instruction on the following line).
1860ca56dc09SJosh Triplett		if ($line =~ /^\+\s*"/ &&
1861ca56dc09SJosh Triplett		    $prevline =~ /"\s*$/ &&
1862ca56dc09SJosh Triplett		    $prevline =~ /\(/ &&
1863ca56dc09SJosh Triplett		    $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
1864ca56dc09SJosh Triplett			WARN("SPLIT_STRING",
1865ca56dc09SJosh Triplett			     "quoted string split across lines\n" . $hereprev);
1866ca56dc09SJosh Triplett		}
1867ca56dc09SJosh Triplett
18685e79d96eSJoe Perches# check for spaces before a quoted newline
18695e79d96eSJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
1870*3705ce5bSJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
1871*3705ce5bSJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
1872*3705ce5bSJoe Perches			    $fix) {
1873*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
1874*3705ce5bSJoe Perches			}
1875*3705ce5bSJoe Perches
18765e79d96eSJoe Perches		}
18775e79d96eSJoe Perches
18788905a67cSAndy Whitcroft# check for adding lines without a newline.
18798905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1880000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
1881000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
18828905a67cSAndy Whitcroft		}
18838905a67cSAndy Whitcroft
188442e41c54SMike Frysinger# Blackfin: use hi/lo macros
188542e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
188642e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
188742e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1888000d1cc1SJoe Perches				ERROR("LO_MACRO",
1889000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
189042e41c54SMike Frysinger			}
189142e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
189242e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1893000d1cc1SJoe Perches				ERROR("HI_MACRO",
1894000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
189542e41c54SMike Frysinger			}
189642e41c54SMike Frysinger		}
189742e41c54SMike Frysinger
1898b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
1899b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c|pl)$/);
19000a920b5bSAndy Whitcroft
19010a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
19020a920b5bSAndy Whitcroft# more than 8 must use tabs.
1903c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
1904c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
1905c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1906d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
1907*3705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
1908*3705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
1909*3705ce5bSJoe Perches			    $fix) {
1910*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
1911*3705ce5bSJoe Perches			}
19120a920b5bSAndy Whitcroft		}
19130a920b5bSAndy Whitcroft
191408e44365SAlberto Panizzo# check for space before tabs.
191508e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
191608e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1917*3705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
1918*3705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
1919*3705ce5bSJoe Perches			    $fix) {
1920*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
1921*3705ce5bSJoe Perches				    s/(^\+.*) +\t/$1\t/;
1922*3705ce5bSJoe Perches			}
192308e44365SAlberto Panizzo		}
192408e44365SAlberto Panizzo
1925d1fe9c09SJoe Perches# check for && or || at the start of a line
1926d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
1927d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
1928d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
1929d1fe9c09SJoe Perches		}
1930d1fe9c09SJoe Perches
1931d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
1932d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
1933d1fe9c09SJoe Perches		    $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
1934d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
1935d1fe9c09SJoe Perches			my $oldindent = $1;
1936d1fe9c09SJoe Perches			my $rest = $2;
1937d1fe9c09SJoe Perches
1938d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
1939d1fe9c09SJoe Perches			if ($pos >= 0) {
1940b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
1941b34a26f3SJoe Perches				my $newindent = $2;
1942d1fe9c09SJoe Perches
1943d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
1944d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
1945d1fe9c09SJoe Perches					" "  x ($pos % 8);
1946d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
1947d1fe9c09SJoe Perches
1948d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
1949d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
1950*3705ce5bSJoe Perches
1951*3705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
1952*3705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
1953*3705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
1954*3705ce5bSJoe Perches						$fixed[$linenr - 1] =~
1955*3705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
1956*3705ce5bSJoe Perches					}
1957d1fe9c09SJoe Perches				}
1958d1fe9c09SJoe Perches			}
1959d1fe9c09SJoe Perches		}
1960d1fe9c09SJoe Perches
196123f780c9SJoe Perches		if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
1962*3705ce5bSJoe Perches			if (CHK("SPACING",
1963*3705ce5bSJoe Perches				"No space is necessary after a cast\n" . $hereprev) &&
1964*3705ce5bSJoe Perches			    $fix) {
1965*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
1966*3705ce5bSJoe Perches				    s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
1967*3705ce5bSJoe Perches			}
1968aad4f614SJoe Perches		}
1969aad4f614SJoe Perches
197005880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
1971fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
1972fdb4bcd6SJoe Perches		    $rawline =~ /^\+[ \t]*\*/) {
197305880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
197405880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
197505880600SJoe Perches		}
197605880600SJoe Perches
197705880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
1978a605e32eSJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*
1979a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
1980a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
1981a605e32eSJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
1982a605e32eSJoe Perches			     "networking block comments start with * on subsequent lines\n" . $hereprev);
1983a605e32eSJoe Perches		}
1984a605e32eSJoe Perches
1985a605e32eSJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
1986c24f9f19SJoe Perches		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
1987c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
1988c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
1989c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
199005880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
199105880600SJoe Perches			     "networking block comments put the trailing */ on a separate line\n" . $herecurr);
199205880600SJoe Perches		}
199305880600SJoe Perches
19945f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
19956b4c5bebSAndy Whitcroft# Exceptions:
19966b4c5bebSAndy Whitcroft#  1) within comments
19976b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
19986b4c5bebSAndy Whitcroft#  3) hanging labels
1999*3705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
20005f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2001*3705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
2002*3705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
2003*3705ce5bSJoe Perches			    $fix) {
2004*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
2005*3705ce5bSJoe Perches			}
20065f7ddae6SRaffaele Recalcati		}
20075f7ddae6SRaffaele Recalcati
2008b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
2009b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
2010b9ea10d6SAndy Whitcroft
20111ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
20121ba8dfd1SKees Cook		if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
20131ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
20141ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
20151ba8dfd1SKees Cook		}
20161ba8dfd1SKees Cook
2017c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
2018cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2019000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
2020000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2021c2fdda0dSAndy Whitcroft		}
202222f2a2efSAndy Whitcroft
202342e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
202442e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
202542e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2026000d1cc1SJoe Perches			ERROR("CSYNC",
2027000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
202842e41c54SMike Frysinger		}
202942e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
203042e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2031000d1cc1SJoe Perches			ERROR("SSYNC",
2032000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
203342e41c54SMike Frysinger		}
203442e41c54SMike Frysinger
203556e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
203656e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
203756e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
203856e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
203956e77d70SJoe Perches		}
204056e77d70SJoe Perches
20419c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
20422b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
20432b474a1aSAndy Whitcroft		    $realline_next);
20443e469cdcSAndy Whitcroft#print "LINE<$line>\n";
20453e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
20463e469cdcSAndy Whitcroft		    $realcnt && $line =~ /.\s*\S/) {
2047170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2048f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
2049171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
2050171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
2051171ae1a4SAndy Whitcroft
20523e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
20533e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
20543e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
20553e469cdcSAndy Whitcroft			# until we hit end of it.
20563e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
20573e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
20583e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
20593e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
20603e469cdcSAndy Whitcroft			}
2061f74bd194SAndy Whitcroft
20622b474a1aSAndy Whitcroft			# Find the real next line.
20632b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
20642b474a1aSAndy Whitcroft			if (defined $realline_next &&
20652b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
20662b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
20672b474a1aSAndy Whitcroft				$realline_next++;
20682b474a1aSAndy Whitcroft			}
20692b474a1aSAndy Whitcroft
2070171ae1a4SAndy Whitcroft			my $s = $stat;
2071171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
2072cf655043SAndy Whitcroft
2073c2fdda0dSAndy Whitcroft			# Ignore goto labels.
2074171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
2075c2fdda0dSAndy Whitcroft
2076c2fdda0dSAndy Whitcroft			# Ignore functions being called
2077171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2078c2fdda0dSAndy Whitcroft
2079463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
2080463f2864SAndy Whitcroft
2081c45dcabdSAndy Whitcroft			# declarations always start with types
2082d2506586SAndy 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) {
2083c45dcabdSAndy Whitcroft				my $type = $1;
2084c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
2085c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
2086c45dcabdSAndy Whitcroft
20876c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
2088a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2089c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
2090c2fdda0dSAndy Whitcroft			}
20918905a67cSAndy Whitcroft
20926c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
209365863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2094c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
20959c0ca6f9SAndy Whitcroft			}
20968905a67cSAndy Whitcroft
20978905a67cSAndy Whitcroft			# Check for any sort of function declaration.
20988905a67cSAndy Whitcroft			# int foo(something bar, other baz);
20998905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
2100171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
21018905a67cSAndy Whitcroft				my ($name_len) = length($1);
21028905a67cSAndy Whitcroft
2103cf655043SAndy Whitcroft				my $ctx = $s;
2104773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
21058905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
2106cf655043SAndy Whitcroft
21078905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
2108c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
21098905a67cSAndy Whitcroft
2110c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
21118905a67cSAndy Whitcroft					}
21128905a67cSAndy Whitcroft				}
21138905a67cSAndy Whitcroft			}
21148905a67cSAndy Whitcroft
21159c0ca6f9SAndy Whitcroft		}
21169c0ca6f9SAndy Whitcroft
211700df344fSAndy Whitcroft#
211800df344fSAndy Whitcroft# Checks which may be anchored in the context.
211900df344fSAndy Whitcroft#
212000df344fSAndy Whitcroft
212100df344fSAndy Whitcroft# Check for switch () and associated case and default
212200df344fSAndy Whitcroft# statements should be at the same indent.
212300df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
212400df344fSAndy Whitcroft			my $err = '';
212500df344fSAndy Whitcroft			my $sep = '';
212600df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
212700df344fSAndy Whitcroft			shift(@ctx);
212800df344fSAndy Whitcroft			for my $ctx (@ctx) {
212900df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
213000df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
213100df344fSAndy Whitcroft							$indent != $cindent) {
213200df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
213300df344fSAndy Whitcroft					$sep = '';
213400df344fSAndy Whitcroft				} else {
213500df344fSAndy Whitcroft					$sep = "[...]\n";
213600df344fSAndy Whitcroft				}
213700df344fSAndy Whitcroft			}
213800df344fSAndy Whitcroft			if ($err ne '') {
2139000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
2140000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
2141de7d4f0eSAndy Whitcroft			}
2142de7d4f0eSAndy Whitcroft		}
2143de7d4f0eSAndy Whitcroft
2144de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
2145de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
2146c45dcabdSAndy Whitcroft		if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2147773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
2148773647a0SAndy Whitcroft
21499c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
21508eef05ddSJoe Perches
21518eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
21528eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
21538eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
21548eef05ddSJoe Perches			}
21558eef05ddSJoe Perches
2156de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
2157de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
2158de7d4f0eSAndy Whitcroft
2159548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
2160548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
2161de7d4f0eSAndy Whitcroft
2162548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2163548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
2164548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
2165548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2166548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2167773647a0SAndy Whitcroft				$ctx_ln++;
2168773647a0SAndy Whitcroft			}
2169548596d5SAndy Whitcroft
217053210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
217153210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2172773647a0SAndy Whitcroft
2173773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2174000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
2175000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
217601464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
217700df344fSAndy Whitcroft			}
2178773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2179773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
2180773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
2181773647a0SAndy Whitcroft			{
21829c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
21839c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
2184000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
2185000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
218601464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
21879c0ca6f9SAndy Whitcroft				}
21889c0ca6f9SAndy Whitcroft			}
218900df344fSAndy Whitcroft		}
219000df344fSAndy Whitcroft
21914d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
21924d001e4dSAndy Whitcroft		if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
21933e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
21943e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
21953e469cdcSAndy Whitcroft					if (!defined $stat);
21964d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
21974d001e4dSAndy Whitcroft
21984d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
21994d001e4dSAndy Whitcroft
22004d001e4dSAndy Whitcroft			# Make sure we remove the line prefixes as we have
22014d001e4dSAndy Whitcroft			# none on the first line, and are going to readd them
22024d001e4dSAndy Whitcroft			# where necessary.
22034d001e4dSAndy Whitcroft			$s =~ s/\n./\n/gs;
22044d001e4dSAndy Whitcroft
22054d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
22066f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
22076f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
22084d001e4dSAndy Whitcroft
22094d001e4dSAndy Whitcroft			# We want to check the first line inside the block
22104d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
22114d001e4dSAndy Whitcroft			#  1) any blank line termination
22124d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
22134d001e4dSAndy Whitcroft			#  3) any do (...) {
22144d001e4dSAndy Whitcroft			my $continuation = 0;
22154d001e4dSAndy Whitcroft			my $check = 0;
22164d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
22174d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
22184d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
22194d001e4dSAndy Whitcroft				$continuation = 1;
22204d001e4dSAndy Whitcroft			}
22219bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
22224d001e4dSAndy Whitcroft				$check = 1;
22234d001e4dSAndy Whitcroft				$cond_lines++;
22244d001e4dSAndy Whitcroft			}
22254d001e4dSAndy Whitcroft
22264d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
22274d001e4dSAndy Whitcroft			# preprocessor statement.
22284d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
22294d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
22304d001e4dSAndy Whitcroft				$check = 0;
22314d001e4dSAndy Whitcroft			}
22324d001e4dSAndy Whitcroft
22339bd49efeSAndy Whitcroft			my $cond_ptr = -1;
2234740504c6SAndy Whitcroft			$continuation = 0;
22359bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
22369bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
22374d001e4dSAndy Whitcroft
2238f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
2239f16fa28fSAndy Whitcroft				# is not linear.
2240f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2241f16fa28fSAndy Whitcroft					$check = 0;
2242f16fa28fSAndy Whitcroft				}
2243f16fa28fSAndy Whitcroft
22449bd49efeSAndy Whitcroft				# Ignore:
22459bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
22469bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
22479bd49efeSAndy Whitcroft				#  3) labels.
2248740504c6SAndy Whitcroft				if ($continuation ||
2249740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
22509bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
22519bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
2252740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
225330dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
22549bd49efeSAndy Whitcroft						$cond_lines++;
22559bd49efeSAndy Whitcroft					}
22564d001e4dSAndy Whitcroft				}
225730dad6ebSAndy Whitcroft			}
22584d001e4dSAndy Whitcroft
22594d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
22604d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
22614d001e4dSAndy Whitcroft
22624d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
22634d001e4dSAndy Whitcroft			# this is not this patch's fault.
22644d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
22654d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
22664d001e4dSAndy Whitcroft				$check = 0;
22674d001e4dSAndy Whitcroft			}
22684d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
22694d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
22704d001e4dSAndy Whitcroft			}
22714d001e4dSAndy Whitcroft
22729bd49efeSAndy 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";
22734d001e4dSAndy Whitcroft
22744d001e4dSAndy Whitcroft			if ($check && (($sindent % 8) != 0 ||
22754d001e4dSAndy Whitcroft			    ($sindent <= $indent && $s ne ''))) {
2276000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
2277000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
22784d001e4dSAndy Whitcroft			}
22794d001e4dSAndy Whitcroft		}
22804d001e4dSAndy Whitcroft
22816c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
22826c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
22831f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
22841f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
22856c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
2286c2fdda0dSAndy Whitcroft		if ($dbg_values) {
2287c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
2288cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
2289cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
22901f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
2291c2fdda0dSAndy Whitcroft		}
22926c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
22936c72ffaaSAndy Whitcroft
229400df344fSAndy Whitcroft#ignore lines not being added
2295*3705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
229600df344fSAndy Whitcroft
2297653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
22987429c690SAndy Whitcroft		if ($dbg_type) {
22997429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
2300000d1cc1SJoe Perches				ERROR("TEST_TYPE",
2301000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
23027429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
2303000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
2304000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
23057429c690SAndy Whitcroft			}
2306653d4876SAndy Whitcroft			next;
2307653d4876SAndy Whitcroft		}
2308a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
2309a1ef277eSAndy Whitcroft		if ($dbg_attr) {
23109360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
2311000d1cc1SJoe Perches				ERROR("TEST_ATTR",
2312000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
23139360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
2314000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
2315000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
2316a1ef277eSAndy Whitcroft			}
2317a1ef277eSAndy Whitcroft			next;
2318a1ef277eSAndy Whitcroft		}
2319653d4876SAndy Whitcroft
2320f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
232199423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
232299423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
2323000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2324000d1cc1SJoe Perches			      "that open brace { should be on the previous line\n" . $hereprev);
2325f0a594c1SAndy Whitcroft		}
2326f0a594c1SAndy Whitcroft
232700df344fSAndy Whitcroft#
232800df344fSAndy Whitcroft# Checks which are anchored on the added line.
232900df344fSAndy Whitcroft#
233000df344fSAndy Whitcroft
2331653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
2332c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
2333653d4876SAndy Whitcroft			my $path = $1;
2334653d4876SAndy Whitcroft			if ($path =~ m{//}) {
2335000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
2336495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
2337495e9d84SJoe Perches			}
2338495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
2339495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
2340495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
2341653d4876SAndy Whitcroft			}
2342653d4876SAndy Whitcroft		}
2343653d4876SAndy Whitcroft
234400df344fSAndy Whitcroft# no C99 // comments
234500df344fSAndy Whitcroft		if ($line =~ m{//}) {
2346*3705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
2347*3705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
2348*3705ce5bSJoe Perches			    $fix) {
2349*3705ce5bSJoe Perches				my $line = $fixed[$linenr - 1];
2350*3705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
2351*3705ce5bSJoe Perches					my $comment = trim($1);
2352*3705ce5bSJoe Perches					$fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
2353*3705ce5bSJoe Perches				}
2354*3705ce5bSJoe Perches			}
235500df344fSAndy Whitcroft		}
235600df344fSAndy Whitcroft		# Remove C99 comments.
23570a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
23586c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
23590a920b5bSAndy Whitcroft
23602b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
23612b474a1aSAndy Whitcroft# the whole statement.
23622b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
23632b474a1aSAndy Whitcroft		if (defined $realline_next &&
23642b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
23652b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
23662b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
23672b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
23683cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
23693cbf62dfSAndy Whitcroft			# a prefix:
23703cbf62dfSAndy Whitcroft			#   XXX(foo);
23713cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
2372653d4876SAndy Whitcroft			my $name = $1;
237387a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
23743cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
23753cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
23763cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
23773cbf62dfSAndy Whitcroft
23783cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
23792b474a1aSAndy Whitcroft				\n.}\s*$|
238048012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
238148012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
238248012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
23832b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
23842b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
238548012058SAndy Whitcroft			    )/x) {
23862b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
23872b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
23882b474a1aSAndy Whitcroft			} else {
23892b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
23900a920b5bSAndy Whitcroft			}
23910a920b5bSAndy Whitcroft		}
23922b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
23932b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
23942b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
23952b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
23962b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
23972b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
23982b474a1aSAndy Whitcroft		}
23992b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
24002b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
2401000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
2402000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
24032b474a1aSAndy Whitcroft		}
24040a920b5bSAndy Whitcroft
24055150bda4SJoe Eloff# check for global initialisers.
2406c45dcabdSAndy Whitcroft		if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
2407000d1cc1SJoe Perches			ERROR("GLOBAL_INITIALISERS",
2408000d1cc1SJoe Perches			      "do not initialise globals to 0 or NULL\n" .
2409f0a594c1SAndy Whitcroft				$herecurr);
2410f0a594c1SAndy Whitcroft		}
24110a920b5bSAndy Whitcroft# check for static initialisers.
24122d1bafd7SAndy Whitcroft		if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
2413000d1cc1SJoe Perches			ERROR("INITIALISED_STATIC",
2414000d1cc1SJoe Perches			      "do not initialise statics to 0 or NULL\n" .
2415de7d4f0eSAndy Whitcroft				$herecurr);
24160a920b5bSAndy Whitcroft		}
24170a920b5bSAndy Whitcroft
2418cb710ecaSJoe Perches# check for static const char * arrays.
2419cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
2420000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2421000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
2422cb710ecaSJoe Perches				$herecurr);
2423cb710ecaSJoe Perches               }
2424cb710ecaSJoe Perches
2425cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
2426cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
2427000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2428000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
2429cb710ecaSJoe Perches				$herecurr);
2430cb710ecaSJoe Perches               }
2431cb710ecaSJoe Perches
243293ed0e2dSJoe Perches# check for declarations of struct pci_device_id
243393ed0e2dSJoe Perches		if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
2434000d1cc1SJoe Perches			WARN("DEFINE_PCI_DEVICE_TABLE",
2435000d1cc1SJoe Perches			     "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
243693ed0e2dSJoe Perches		}
243793ed0e2dSJoe Perches
2438653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
2439653d4876SAndy Whitcroft# make sense.
2440653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
24418054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
2442c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
24438ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
2444653d4876SAndy Whitcroft		    $line !~ /\b__bitwise(?:__|)\b/) {
2445000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
2446000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
24470a920b5bSAndy Whitcroft		}
24480a920b5bSAndy Whitcroft
24490a920b5bSAndy Whitcroft# * goes on variable not on type
245065863862SAndy Whitcroft		# (char*[ const])
2451bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
2452bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
2453*3705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
2454d8aaf121SAndy Whitcroft
245565863862SAndy Whitcroft			# Should start with a space.
245665863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
245765863862SAndy Whitcroft			# Should not end with a space.
245865863862SAndy Whitcroft			$to =~ s/\s+$//;
245965863862SAndy Whitcroft			# '*'s should not have spaces between.
2460f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
246165863862SAndy Whitcroft			}
2462d8aaf121SAndy Whitcroft
2463*3705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
246465863862SAndy Whitcroft			if ($from ne $to) {
2465*3705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
2466*3705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
2467*3705ce5bSJoe Perches				    $fix) {
2468*3705ce5bSJoe Perches					my $sub_from = $ident;
2469*3705ce5bSJoe Perches					my $sub_to = $ident;
2470*3705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
2471*3705ce5bSJoe Perches					$fixed[$linenr - 1] =~
2472*3705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
2473*3705ce5bSJoe Perches				}
247465863862SAndy Whitcroft			}
2475bfcb2cc7SAndy Whitcroft		}
2476bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
2477bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
2478*3705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
2479d8aaf121SAndy Whitcroft
248065863862SAndy Whitcroft			# Should start with a space.
248165863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
248265863862SAndy Whitcroft			# Should not end with a space.
248365863862SAndy Whitcroft			$to =~ s/\s+$//;
248465863862SAndy Whitcroft			# '*'s should not have spaces between.
2485f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
248665863862SAndy Whitcroft			}
248765863862SAndy Whitcroft			# Modifiers should have spaces.
248865863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
248965863862SAndy Whitcroft
2490*3705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
2491667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
2492*3705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
2493*3705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
2494*3705ce5bSJoe Perches				    $fix) {
2495*3705ce5bSJoe Perches
2496*3705ce5bSJoe Perches					my $sub_from = $match;
2497*3705ce5bSJoe Perches					my $sub_to = $match;
2498*3705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
2499*3705ce5bSJoe Perches					$fixed[$linenr - 1] =~
2500*3705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
2501*3705ce5bSJoe Perches				}
250265863862SAndy Whitcroft			}
25030a920b5bSAndy Whitcroft		}
25040a920b5bSAndy Whitcroft
25050a920b5bSAndy Whitcroft# # no BUG() or BUG_ON()
25060a920b5bSAndy Whitcroft# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {
25070a920b5bSAndy Whitcroft# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
25080a920b5bSAndy Whitcroft# 			print "$herecurr";
25090a920b5bSAndy Whitcroft# 			$clean = 0;
25100a920b5bSAndy Whitcroft# 		}
25110a920b5bSAndy Whitcroft
25128905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
2513000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
2514000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
25158905a67cSAndy Whitcroft		}
25168905a67cSAndy Whitcroft
251717441227SJoe Perches# check for uses of printk_ratelimit
251817441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
2519000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
2520000d1cc1SJoe Perches"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
252117441227SJoe Perches		}
252217441227SJoe Perches
252300df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
252400df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
252500df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
252625985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
252700df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
2528f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
252900df344fSAndy Whitcroft			my $ok = 0;
253000df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
253100df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
253225985edcSLucas De Marchi				# we have a preceding printk if it ends
253300df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
253400df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
253500df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
253600df344fSAndy Whitcroft						$ok = 1;
253700df344fSAndy Whitcroft					}
253800df344fSAndy Whitcroft					last;
253900df344fSAndy Whitcroft				}
254000df344fSAndy Whitcroft			}
254100df344fSAndy Whitcroft			if ($ok == 0) {
2542000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
2543000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
25440a920b5bSAndy Whitcroft			}
254500df344fSAndy Whitcroft		}
25460a920b5bSAndy Whitcroft
2547243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
2548243f3803SJoe Perches			my $orig = $1;
2549243f3803SJoe Perches			my $level = lc($orig);
2550243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
25518f26b837SJoe Perches			my $level2 = $level;
25528f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
2553243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
25548f26b837SJoe Perches			     "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
2555243f3803SJoe Perches		}
2556243f3803SJoe Perches
2557243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
2558243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
2559243f3803SJoe Perches			     "Prefer pr_warn(... to pr_warning(...\n" . $herecurr);
2560243f3803SJoe Perches		}
2561243f3803SJoe Perches
2562dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
2563dc139313SJoe Perches			my $orig = $1;
2564dc139313SJoe Perches			my $level = lc($orig);
2565dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
2566dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
2567dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
2568dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
2569dc139313SJoe Perches		}
2570dc139313SJoe Perches
2571653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
2572653d4876SAndy Whitcroft# or if closed on same line
2573c45dcabdSAndy Whitcroft		if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
2574c45dcabdSAndy Whitcroft		    !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
2575000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2576000d1cc1SJoe Perches			      "open brace '{' following function declarations go on the next line\n" . $herecurr);
25770a920b5bSAndy Whitcroft		}
2578653d4876SAndy Whitcroft
25798905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
25808905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
25818905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2582000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2583000d1cc1SJoe Perches			      "open brace '{' following $1 go on the same line\n" . $hereprev);
25848905a67cSAndy Whitcroft		}
25858905a67cSAndy Whitcroft
25860c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
2587*3705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
2588*3705ce5bSJoe Perches			if (WARN("SPACING",
2589*3705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
2590*3705ce5bSJoe Perches			    $fix) {
2591*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2592*3705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
2593*3705ce5bSJoe Perches			}
25940c73b4ebSAndy Whitcroft		}
25950c73b4ebSAndy Whitcroft
25968d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
25978d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
2598fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2599fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
26008d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
26018d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
26028d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
2603fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
2604daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
2605*3705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
2606*3705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
2607*3705ce5bSJoe Perches				    $fix) {
2608*3705ce5bSJoe Perches				    $fixed[$linenr - 1] =~
2609*3705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
2610*3705ce5bSJoe Perches				}
26118d31cfceSAndy Whitcroft			}
26128d31cfceSAndy Whitcroft		}
26138d31cfceSAndy Whitcroft
2614f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
26156c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
2616c2fdda0dSAndy Whitcroft			my $name = $1;
2617773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
2618773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
2619c2fdda0dSAndy Whitcroft
2620c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
2621773647a0SAndy Whitcroft			if ($name =~ /^(?:
2622773647a0SAndy Whitcroft				if|for|while|switch|return|case|
2623773647a0SAndy Whitcroft				volatile|__volatile__|
2624773647a0SAndy Whitcroft				__attribute__|format|__extension__|
2625773647a0SAndy Whitcroft				asm|__asm__)$/x)
2626773647a0SAndy Whitcroft			{
2627c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
2628c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
2629c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
2630c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
2631773647a0SAndy Whitcroft
2632773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
2633c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
2634c2fdda0dSAndy Whitcroft
2635c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
2636c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
2637773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
2638c2fdda0dSAndy Whitcroft
2639c2fdda0dSAndy Whitcroft			} else {
2640*3705ce5bSJoe Perches				if (WARN("SPACING",
2641*3705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
2642*3705ce5bSJoe Perches					     $fix) {
2643*3705ce5bSJoe Perches					$fixed[$linenr - 1] =~
2644*3705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
2645*3705ce5bSJoe Perches				}
2646f0a594c1SAndy Whitcroft			}
26476c72ffaaSAndy Whitcroft		}
26489a4cad4eSEric Nelson
26499a4cad4eSEric Nelson# check for whitespace before a non-naked semicolon
26509a4cad4eSEric Nelson		if ($line =~ /^\+.*\S\s+;/) {
2651*3705ce5bSJoe Perches			if (WARN("SPACING",
2652*3705ce5bSJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
2653*3705ce5bSJoe Perches			    $fix) {
2654*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2655*3705ce5bSJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
2656*3705ce5bSJoe Perches			}
26579a4cad4eSEric Nelson		}
26589a4cad4eSEric Nelson
2659653d4876SAndy Whitcroft# Check operator spacing.
26600a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
2661*3705ce5bSJoe Perches			my $fixed_line = "";
2662*3705ce5bSJoe Perches			my $line_fixed = 0;
2663*3705ce5bSJoe Perches
26649c0ca6f9SAndy Whitcroft			my $ops = qr{
26659c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
26669c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
26679c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
26681f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
26691f65f947SAndy Whitcroft				\?|:
26709c0ca6f9SAndy Whitcroft			}x;
2671cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
2672*3705ce5bSJoe Perches
2673*3705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
2674*3705ce5bSJoe Perches##			foreach my $el (@elements) {
2675*3705ce5bSJoe Perches##				print("el: <$el>\n");
2676*3705ce5bSJoe Perches##			}
2677*3705ce5bSJoe Perches
2678*3705ce5bSJoe Perches			my @fix_elements = ();
267900df344fSAndy Whitcroft			my $off = 0;
26806c72ffaaSAndy Whitcroft
2681*3705ce5bSJoe Perches			foreach my $el (@elements) {
2682*3705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
2683*3705ce5bSJoe Perches				$off += length($el);
2684*3705ce5bSJoe Perches			}
2685*3705ce5bSJoe Perches
2686*3705ce5bSJoe Perches			$off = 0;
2687*3705ce5bSJoe Perches
26886c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
26896c72ffaaSAndy Whitcroft
26900a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
2691*3705ce5bSJoe Perches
2692*3705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
2693*3705ce5bSJoe Perches
2694*3705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
2695*3705ce5bSJoe Perches
26964a0df2efSAndy Whitcroft				$off += length($elements[$n]);
26974a0df2efSAndy Whitcroft
269825985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
2699773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
2700773647a0SAndy Whitcroft				my $cc = '';
2701773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
2702773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
2703773647a0SAndy Whitcroft				}
2704773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
2705773647a0SAndy Whitcroft
27064a0df2efSAndy Whitcroft				my $a = '';
27074a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
27084a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
2709cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
27104a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
27114a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
2712773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
27134a0df2efSAndy Whitcroft
27140a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
27154a0df2efSAndy Whitcroft
27164a0df2efSAndy Whitcroft				my $c = '';
27170a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
27184a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
27194a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
2720cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
27214a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
27224a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
27238b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
27244a0df2efSAndy Whitcroft				} else {
27254a0df2efSAndy Whitcroft					$c = 'E';
27260a920b5bSAndy Whitcroft				}
27270a920b5bSAndy Whitcroft
27284a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
27294a0df2efSAndy Whitcroft
27304a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
27314a0df2efSAndy Whitcroft
27326c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
2733de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
27340a920b5bSAndy Whitcroft
273574048ed8SAndy Whitcroft				# Pull out the value of this operator.
27366c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
27370a920b5bSAndy Whitcroft
27381f65f947SAndy Whitcroft				# Get the full operator variant.
27391f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
27401f65f947SAndy Whitcroft
274113214adfSAndy Whitcroft				# Ignore operators passed as parameters.
274213214adfSAndy Whitcroft				if ($op_type ne 'V' &&
274313214adfSAndy Whitcroft				    $ca =~ /\s$/ && $cc =~ /^\s*,/) {
274413214adfSAndy Whitcroft
2745cf655043SAndy Whitcroft#				# Ignore comments
2746cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
274713214adfSAndy Whitcroft
2748d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
274913214adfSAndy Whitcroft				} elsif ($op eq ';') {
2750cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
2751cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
2752*3705ce5bSJoe Perches						if (ERROR("SPACING",
2753*3705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
2754*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2755*3705ce5bSJoe Perches							$line_fixed = 1;
2756*3705ce5bSJoe Perches						}
2757d8aaf121SAndy Whitcroft					}
2758d8aaf121SAndy Whitcroft
2759d8aaf121SAndy Whitcroft				# // is a comment
2760d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
27610a920b5bSAndy Whitcroft
27621f65f947SAndy Whitcroft				# No spaces for:
27631f65f947SAndy Whitcroft				#   ->
27641f65f947SAndy Whitcroft				#   :   when part of a bitfield
27651f65f947SAndy Whitcroft				} elsif ($op eq '->' || $opv eq ':B') {
27664a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
2767*3705ce5bSJoe Perches						if (ERROR("SPACING",
2768*3705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
2769*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2770*3705ce5bSJoe Perches							$line_fixed = 1;
2771*3705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
2772*3705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
2773*3705ce5bSJoe Perches							}
2774*3705ce5bSJoe Perches						}
27750a920b5bSAndy Whitcroft					}
27760a920b5bSAndy Whitcroft
27770a920b5bSAndy Whitcroft				# , must have a space on the right.
27780a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
2779cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
2780*3705ce5bSJoe Perches						if (ERROR("SPACING",
2781*3705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
2782*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
2783*3705ce5bSJoe Perches							$line_fixed = 1;
2784*3705ce5bSJoe Perches						}
27850a920b5bSAndy Whitcroft					}
27860a920b5bSAndy Whitcroft
27879c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
278874048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
27899c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
27909c0ca6f9SAndy Whitcroft
27919c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
27929c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
27939c0ca6f9SAndy Whitcroft				# unary operator, or a cast
27949c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
279574048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
27960d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
2797cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
2798*3705ce5bSJoe Perches						if (ERROR("SPACING",
2799*3705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
2800*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
2801*3705ce5bSJoe Perches							$line_fixed = 1;
2802*3705ce5bSJoe Perches						}
28030a920b5bSAndy Whitcroft					}
2804a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2805171ae1a4SAndy Whitcroft						# A unary '*' may be const
2806171ae1a4SAndy Whitcroft
2807171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
2808*3705ce5bSJoe Perches						if (ERROR("SPACING",
2809*3705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
2810*3705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
2811*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2812*3705ce5bSJoe Perches							$line_fixed = 1;
2813*3705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
2814*3705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
2815*3705ce5bSJoe Perches							}
2816*3705ce5bSJoe Perches						}
28170a920b5bSAndy Whitcroft					}
28180a920b5bSAndy Whitcroft
28190a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
28200a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
2821773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
2822*3705ce5bSJoe Perches						if (ERROR("SPACING",
2823*3705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
2824*3705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
2825*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
2826*3705ce5bSJoe Perches							$line_fixed = 1;
2827*3705ce5bSJoe Perches						}
28280a920b5bSAndy Whitcroft					}
2829773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
2830773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
2831*3705ce5bSJoe Perches						if (ERROR("SPACING",
2832*3705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
2833*3705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
2834*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2835*3705ce5bSJoe Perches							$line_fixed = 1;
2836*3705ce5bSJoe Perches						}
2837653d4876SAndy Whitcroft					}
2838773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
2839*3705ce5bSJoe Perches						if (ERROR("SPACING",
2840*3705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
2841*3705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
2842*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2843*3705ce5bSJoe Perches							$line_fixed = 1;
2844*3705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
2845*3705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
2846773647a0SAndy Whitcroft							}
2847*3705ce5bSJoe Perches						}
2848*3705ce5bSJoe Perches					}
28490a920b5bSAndy Whitcroft
28500a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
28519c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
28529c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
28539c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
2854c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
2855c2fdda0dSAndy Whitcroft					 $op eq '%')
28560a920b5bSAndy Whitcroft				{
2857773647a0SAndy Whitcroft					if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
2858*3705ce5bSJoe Perches						if (ERROR("SPACING",
2859*3705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
2860*3705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
2861*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2862*3705ce5bSJoe Perches							$line_fixed = 1;
2863*3705ce5bSJoe Perches						}
28640a920b5bSAndy Whitcroft					}
28650a920b5bSAndy Whitcroft
28661f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
28671f65f947SAndy Whitcroft				# terminating a case value or a label.
28681f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
28691f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
2870*3705ce5bSJoe Perches						if (ERROR("SPACING",
2871*3705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
2872*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2873*3705ce5bSJoe Perches							$line_fixed = 1;
2874*3705ce5bSJoe Perches						}
28751f65f947SAndy Whitcroft					}
28761f65f947SAndy Whitcroft
28770a920b5bSAndy Whitcroft				# All the others need spaces both sides.
2878cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
28791f65f947SAndy Whitcroft					my $ok = 0;
28801f65f947SAndy Whitcroft
288122f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
28821f65f947SAndy Whitcroft					if (($op eq '<' &&
28831f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
28841f65f947SAndy Whitcroft					    ($op eq '>' &&
28851f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
28861f65f947SAndy Whitcroft					{
28871f65f947SAndy Whitcroft					    	$ok = 1;
28881f65f947SAndy Whitcroft					}
28891f65f947SAndy Whitcroft
28901f65f947SAndy Whitcroft					# Ignore ?:
28911f65f947SAndy Whitcroft					if (($opv eq ':O' && $ca =~ /\?$/) ||
28921f65f947SAndy Whitcroft					    ($op eq '?' && $cc =~ /^:/)) {
28931f65f947SAndy Whitcroft					    	$ok = 1;
28941f65f947SAndy Whitcroft					}
28951f65f947SAndy Whitcroft
28961f65f947SAndy Whitcroft					if ($ok == 0) {
2897*3705ce5bSJoe Perches						if (ERROR("SPACING",
2898*3705ce5bSJoe Perches							  "spaces required around that '$op' $at\n" . $hereptr)) {
2899*3705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
2900*3705ce5bSJoe Perches							$good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " ";
2901*3705ce5bSJoe Perches							$line_fixed = 1;
2902*3705ce5bSJoe Perches						}
29030a920b5bSAndy Whitcroft					}
290422f2a2efSAndy Whitcroft				}
29054a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
2906*3705ce5bSJoe Perches
2907*3705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
2908*3705ce5bSJoe Perches
2909*3705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
29100a920b5bSAndy Whitcroft			}
2911*3705ce5bSJoe Perches
2912*3705ce5bSJoe Perches			if (($#elements % 2) == 0) {
2913*3705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
2914*3705ce5bSJoe Perches			}
2915*3705ce5bSJoe Perches
2916*3705ce5bSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
2917*3705ce5bSJoe Perches				$fixed[$linenr - 1] = $fixed_line;
2918*3705ce5bSJoe Perches			}
2919*3705ce5bSJoe Perches
2920*3705ce5bSJoe Perches
29210a920b5bSAndy Whitcroft		}
29220a920b5bSAndy Whitcroft
2923f0a594c1SAndy Whitcroft# check for multiple assignments
2924f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
2925000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
2926000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
2927f0a594c1SAndy Whitcroft		}
2928f0a594c1SAndy Whitcroft
292922f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
293022f2a2efSAndy Whitcroft## # continuation.
293122f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
293222f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
293322f2a2efSAndy Whitcroft##
293422f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
293522f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
293622f2a2efSAndy Whitcroft## 			my $ln = $line;
293722f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
293822f2a2efSAndy Whitcroft## 			}
293922f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
2940000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
2941000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
294222f2a2efSAndy Whitcroft## 			}
294322f2a2efSAndy Whitcroft## 		}
2944f0a594c1SAndy Whitcroft
29450a920b5bSAndy Whitcroft#need space before brace following if, while, etc
294622f2a2efSAndy Whitcroft		if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
294722f2a2efSAndy Whitcroft		    $line =~ /do{/) {
2948*3705ce5bSJoe Perches			if (ERROR("SPACING",
2949*3705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
2950*3705ce5bSJoe Perches			    $fix) {
2951*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2952*3705ce5bSJoe Perches				    s/^(\+.*(?:do|\))){/$1 {/;
2953*3705ce5bSJoe Perches			}
2954de7d4f0eSAndy Whitcroft		}
2955de7d4f0eSAndy Whitcroft
2956c4a62ef9SJoe Perches## # check for blank lines before declarations
2957c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
2958c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
2959c4a62ef9SJoe Perches##			WARN("SPACING",
2960c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
2961c4a62ef9SJoe Perches##		}
2962c4a62ef9SJoe Perches##
2963c4a62ef9SJoe Perches
2964de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
2965de7d4f0eSAndy Whitcroft# on the line
2966de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
2967000d1cc1SJoe Perches			ERROR("SPACING",
2968000d1cc1SJoe Perches			      "space required after that close brace '}'\n" . $herecurr);
29690a920b5bSAndy Whitcroft		}
29700a920b5bSAndy Whitcroft
297122f2a2efSAndy Whitcroft# check spacing on square brackets
297222f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
2973*3705ce5bSJoe Perches			if (ERROR("SPACING",
2974*3705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
2975*3705ce5bSJoe Perches			    $fix) {
2976*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2977*3705ce5bSJoe Perches				    s/\[\s+/\[/;
2978*3705ce5bSJoe Perches			}
297922f2a2efSAndy Whitcroft		}
298022f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
2981*3705ce5bSJoe Perches			if (ERROR("SPACING",
2982*3705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
2983*3705ce5bSJoe Perches			    $fix) {
2984*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2985*3705ce5bSJoe Perches				    s/\s+\]/\]/;
2986*3705ce5bSJoe Perches			}
298722f2a2efSAndy Whitcroft		}
298822f2a2efSAndy Whitcroft
2989c45dcabdSAndy Whitcroft# check spacing on parentheses
29909c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
29919c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
2992*3705ce5bSJoe Perches			if (ERROR("SPACING",
2993*3705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
2994*3705ce5bSJoe Perches			    $fix) {
2995*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
2996*3705ce5bSJoe Perches				    s/\(\s+/\(/;
2997*3705ce5bSJoe Perches			}
299822f2a2efSAndy Whitcroft		}
299913214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
3000c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
3001c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
3002*3705ce5bSJoe Perches			if (ERROR("SPACING",
3003*3705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
3004*3705ce5bSJoe Perches			    $fix) {
3005*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
3006*3705ce5bSJoe Perches				    s/\s+\)/\)/;
3007*3705ce5bSJoe Perches			}
300822f2a2efSAndy Whitcroft		}
300922f2a2efSAndy Whitcroft
30100a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
30114a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
30120a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
3013*3705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
3014*3705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
3015*3705ce5bSJoe Perches			    $fix) {
3016*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
3017*3705ce5bSJoe Perches				    s/^(.)\s+/$1/;
3018*3705ce5bSJoe Perches			}
30190a920b5bSAndy Whitcroft		}
30200a920b5bSAndy Whitcroft
3021c45dcabdSAndy Whitcroft# Return is not a function.
3022c45dcabdSAndy Whitcroft		if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
3023c45dcabdSAndy Whitcroft			my $spacing = $1;
3024c45dcabdSAndy Whitcroft			my $value = $2;
3025c45dcabdSAndy Whitcroft
302686f9d059SAndy Whitcroft			# Flatten any parentheses
3027fb2d2c1bSAndy Whitcroft			$value =~ s/\(/ \(/g;
3028fb2d2c1bSAndy Whitcroft			$value =~ s/\)/\) /g;
3029e01886adSAndy Whitcroft			while ($value =~ s/\[[^\[\]]*\]/1/ ||
303063f17f89SAndy Whitcroft			       $value !~ /(?:$Ident|-?$Constant)\s*
303163f17f89SAndy Whitcroft					     $Compare\s*
303263f17f89SAndy Whitcroft					     (?:$Ident|-?$Constant)/x &&
303363f17f89SAndy Whitcroft			       $value =~ s/\([^\(\)]*\)/1/) {
3034c45dcabdSAndy Whitcroft			}
3035fb2d2c1bSAndy Whitcroft#print "value<$value>\n";
3036fb2d2c1bSAndy Whitcroft			if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
3037000d1cc1SJoe Perches				ERROR("RETURN_PARENTHESES",
3038000d1cc1SJoe Perches				      "return is not a function, parentheses are not required\n" . $herecurr);
3039c45dcabdSAndy Whitcroft
3040c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
3041000d1cc1SJoe Perches				ERROR("SPACING",
3042000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
3043c45dcabdSAndy Whitcroft			}
3044c45dcabdSAndy Whitcroft		}
304553a3c448SAndy Whitcroft# Return of what appears to be an errno should normally be -'ve
304653a3c448SAndy Whitcroft		if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
304753a3c448SAndy Whitcroft			my $name = $1;
304853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
3049000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
3050000d1cc1SJoe Perches				     "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
305153a3c448SAndy Whitcroft			}
305253a3c448SAndy Whitcroft		}
3053c45dcabdSAndy Whitcroft
30540a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
30554a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
3056*3705ce5bSJoe Perches			if (ERROR("SPACING",
3057*3705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
3058*3705ce5bSJoe Perches			    $fix) {
3059*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
3060*3705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
3061*3705ce5bSJoe Perches			}
30620a920b5bSAndy Whitcroft		}
30630a920b5bSAndy Whitcroft
3064f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
3065f5fe35ddSAndy Whitcroft# statements after the conditional.
3066170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
30673e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
30683e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
30693e469cdcSAndy Whitcroft					if (!defined $stat);
3070170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
3071170d3a22SAndy Whitcroft						$remain_next, $off_next);
3072170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
3073170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
3074170d3a22SAndy Whitcroft
3075170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
3076170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
3077170d3a22SAndy Whitcroft				# then count those as offsets.
3078170d3a22SAndy Whitcroft				my ($whitespace) =
3079170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
3080170d3a22SAndy Whitcroft				my $offset =
3081170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
3082170d3a22SAndy Whitcroft
3083170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
3084170d3a22SAndy Whitcroft								$offset} = 1;
3085170d3a22SAndy Whitcroft			}
3086170d3a22SAndy Whitcroft		}
3087170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
3088170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
3089171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
30908905a67cSAndy Whitcroft
3091b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
3092000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
3093000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
30948905a67cSAndy Whitcroft			}
30958905a67cSAndy Whitcroft
30968905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
30978905a67cSAndy Whitcroft			# conditional.
3098773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
30998905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
310013214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
310153210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
310253210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
3103773647a0SAndy Whitcroft			{
3104bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
3105bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
3106bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
310742bdf74cSHidetoshi Seto				my $stat_real = '';
3108bb44ad39SAndy Whitcroft
310942bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
311042bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
3111bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
3112bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
3113bb44ad39SAndy Whitcroft				}
3114bb44ad39SAndy Whitcroft
3115000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3116000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
31178905a67cSAndy Whitcroft			}
31188905a67cSAndy Whitcroft		}
31198905a67cSAndy Whitcroft
312013214adfSAndy Whitcroft# Check for bitwise tests written as boolean
312113214adfSAndy Whitcroft		if ($line =~ /
312213214adfSAndy Whitcroft			(?:
312313214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
312413214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
312513214adfSAndy Whitcroft				(?:\&\&|\|\|)
312613214adfSAndy Whitcroft			|
312713214adfSAndy Whitcroft				(?:\&\&|\|\|)
312813214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
312913214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
313013214adfSAndy Whitcroft			)/x)
313113214adfSAndy Whitcroft		{
3132000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
3133000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
313413214adfSAndy Whitcroft		}
313513214adfSAndy Whitcroft
31368905a67cSAndy Whitcroft# if and else should not have general statements after it
313713214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
313813214adfSAndy Whitcroft			my $s = $1;
313913214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
314013214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3141000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3142000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
31430a920b5bSAndy Whitcroft			}
314413214adfSAndy Whitcroft		}
314539667782SAndy Whitcroft# if should not continue a brace
314639667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
3147000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3148000d1cc1SJoe Perches			      "trailing statements should be on next line\n" .
314939667782SAndy Whitcroft				$herecurr);
315039667782SAndy Whitcroft		}
3151a1080bf8SAndy Whitcroft# case and default should not have general statements after them
3152a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3153a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
31543fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3155a1080bf8SAndy Whitcroft			\s*return\s+
3156a1080bf8SAndy Whitcroft		    )/xg)
3157a1080bf8SAndy Whitcroft		{
3158000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3159000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
3160a1080bf8SAndy Whitcroft		}
31610a920b5bSAndy Whitcroft
31620a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
31630a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
31640a920b5bSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
31650a920b5bSAndy Whitcroft						$previndent == $indent) {
3166000d1cc1SJoe Perches			ERROR("ELSE_AFTER_BRACE",
3167000d1cc1SJoe Perches			      "else should follow close brace '}'\n" . $hereprev);
31680a920b5bSAndy Whitcroft		}
31690a920b5bSAndy Whitcroft
3170c2fdda0dSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3171c2fdda0dSAndy Whitcroft						$previndent == $indent) {
3172c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3173c2fdda0dSAndy Whitcroft
3174c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
3175c2fdda0dSAndy Whitcroft			# conditional.
3176773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
3177c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
3178c2fdda0dSAndy Whitcroft
3179c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
3180000d1cc1SJoe Perches				ERROR("WHILE_AFTER_BRACE",
3181000d1cc1SJoe Perches				      "while should follow close brace '}'\n" . $hereprev);
3182c2fdda0dSAndy Whitcroft			}
3183c2fdda0dSAndy Whitcroft		}
3184c2fdda0dSAndy Whitcroft
318595e2c602SJoe Perches#Specific variable tests
3186323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
3187323c1260SJoe Perches			my $var = $1;
318895e2c602SJoe Perches
318995e2c602SJoe Perches#gcc binary extension
319095e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
319195e2c602SJoe Perches				WARN("GCC_BINARY_CONSTANT",
319295e2c602SJoe Perches				     "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr);
319395e2c602SJoe Perches			}
319495e2c602SJoe Perches
319595e2c602SJoe Perches#CamelCase
3196807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
3197be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
3198807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
3199323c1260SJoe Perches			    !defined $camelcase{$var}) {
3200323c1260SJoe Perches				$camelcase{$var} = 1;
3201be79794bSJoe Perches				CHK("CAMELCASE",
3202323c1260SJoe Perches				    "Avoid CamelCase: <$var>\n" . $herecurr);
3203323c1260SJoe Perches			}
3204323c1260SJoe Perches		}
32050a920b5bSAndy Whitcroft
32060a920b5bSAndy Whitcroft#no spaces allowed after \ in define
3207c45dcabdSAndy Whitcroft		if ($line=~/\#\s*define.*\\\s$/) {
3208000d1cc1SJoe Perches			WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3209000d1cc1SJoe Perches			     "Whitepspace after \\ makes next lines useless\n" . $herecurr);
32100a920b5bSAndy Whitcroft		}
32110a920b5bSAndy Whitcroft
3212653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
3213c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
3214e09dec48SAndy Whitcroft			my $file = "$1.h";
3215e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
3216e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
3217e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
32187840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
3219c45dcabdSAndy Whitcroft			{
3220e09dec48SAndy Whitcroft				if ($realfile =~ m{^arch/}) {
3221000d1cc1SJoe Perches					CHK("ARCH_INCLUDE_LINUX",
3222000d1cc1SJoe Perches					    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3223e09dec48SAndy Whitcroft				} else {
3224000d1cc1SJoe Perches					WARN("INCLUDE_LINUX",
3225000d1cc1SJoe Perches					     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3226e09dec48SAndy Whitcroft				}
32270a920b5bSAndy Whitcroft			}
32280a920b5bSAndy Whitcroft		}
32290a920b5bSAndy Whitcroft
3230653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
3231653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
3232cf655043SAndy Whitcroft# in a known good container
3233b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
3234b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3235d8aaf121SAndy Whitcroft			my $ln = $linenr;
3236d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
3237c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
3238c45dcabdSAndy Whitcroft			my $ctx = '';
3239c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
3240f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3241f74bd194SAndy Whitcroft			$ctx = $dstat;
3242c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3243a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3244c45dcabdSAndy Whitcroft
3245f74bd194SAndy Whitcroft			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3246292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
3247c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
3248c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
3249c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
3250c45dcabdSAndy Whitcroft
3251c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
3252bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3253bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
3254c81769fdSAndy Whitcroft			       $dstat =~ s/\[[^\[\]]*\]/1/)
3255bf30d6edSAndy Whitcroft			{
3256c45dcabdSAndy Whitcroft			}
3257c45dcabdSAndy Whitcroft
3258e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
3259e45bab8eSAndy Whitcroft			while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3260e45bab8eSAndy Whitcroft			       $dstat =~ s/$Ident\s*("X*")/$1/)
3261e45bab8eSAndy Whitcroft			{
3262e45bab8eSAndy Whitcroft			}
3263e45bab8eSAndy Whitcroft
3264c45dcabdSAndy Whitcroft			my $exceptions = qr{
3265c45dcabdSAndy Whitcroft				$Declare|
3266c45dcabdSAndy Whitcroft				module_param_named|
3267a0a0a7a9SKees Cook				MODULE_PARM_DESC|
3268c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
3269c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
3270383099fdSAndy Whitcroft				__typeof__\(|
327122fd2d3eSStefani Seibold				union|
327222fd2d3eSStefani Seibold				struct|
3273ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
3274ea71a0a0SAndy Whitcroft				^\"|\"$
3275c45dcabdSAndy Whitcroft			}x;
32765eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3277f74bd194SAndy Whitcroft			if ($dstat ne '' &&
3278f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
3279f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
32803cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3281b9df76acSAndy Whitcroft			    $dstat !~ /^'X'$/ &&					# character constants
3282f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
3283f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
3284e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
328572f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
3286f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
3287f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
3288f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
3289f74bd194SAndy Whitcroft			    $dstat !~ /^\({/)						# ({...
3290c45dcabdSAndy Whitcroft			{
3291f74bd194SAndy Whitcroft				$ctx =~ s/\n*$//;
3292f74bd194SAndy Whitcroft				my $herectx = $here . "\n";
3293f74bd194SAndy Whitcroft				my $cnt = statement_rawlines($ctx);
3294f74bd194SAndy Whitcroft
3295f74bd194SAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
3296f74bd194SAndy Whitcroft					$herectx .= raw_line($linenr, $n) . "\n";
3297c45dcabdSAndy Whitcroft				}
3298c45dcabdSAndy Whitcroft
3299f74bd194SAndy Whitcroft				if ($dstat =~ /;/) {
3300f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3301f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3302f74bd194SAndy Whitcroft				} else {
3303000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
3304f74bd194SAndy Whitcroft					      "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3305d8aaf121SAndy Whitcroft				}
33060a920b5bSAndy Whitcroft			}
33075023d347SJoe Perches
3308481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
33095023d347SJoe Perches
33105023d347SJoe Perches		} else {
33115023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
3312481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
3313481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
33145023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
33155023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
33165023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
33175023d347SJoe Perches			}
3318653d4876SAndy Whitcroft		}
33190a920b5bSAndy Whitcroft
3320b13edf7fSJoe Perches# do {} while (0) macro tests:
3321b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
3322b13edf7fSJoe Perches# macro should not end with a semicolon
3323b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3324b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
3325b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3326b13edf7fSJoe Perches			my $ln = $linenr;
3327b13edf7fSJoe Perches			my $cnt = $realcnt;
3328b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
3329b13edf7fSJoe Perches			my $ctx = '';
3330b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
3331b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
3332b13edf7fSJoe Perches			$ctx = $dstat;
3333b13edf7fSJoe Perches
3334b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
3335b13edf7fSJoe Perches
3336b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3337b13edf7fSJoe Perches				my $stmts = $2;
3338b13edf7fSJoe Perches				my $semis = $3;
3339b13edf7fSJoe Perches
3340b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
3341b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
3342b13edf7fSJoe Perches				my $herectx = $here . "\n";
3343b13edf7fSJoe Perches
3344b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
3345b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
3346b13edf7fSJoe Perches				}
3347b13edf7fSJoe Perches
3348ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
3349ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
3350b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3351b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3352b13edf7fSJoe Perches				}
3353b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
3354b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3355b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3356b13edf7fSJoe Perches				}
3357b13edf7fSJoe Perches			}
3358b13edf7fSJoe Perches		}
3359b13edf7fSJoe Perches
3360080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
3361080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
3362080ba929SMike Frysinger#	.
3363080ba929SMike Frysinger#	ALIGN(...)
3364080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
3365080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
3366000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
3367000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
3368080ba929SMike Frysinger		}
3369080ba929SMike Frysinger
3370f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
337113214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
337213214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
3373cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
337413214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3375cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3376cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
3377aad4f614SJoe Perches				my @allowed = ();
3378aad4f614SJoe Perches				my $allow = 0;
337913214adfSAndy Whitcroft				my $seen = 0;
3380773647a0SAndy Whitcroft				my $herectx = $here . "\n";
3381cf655043SAndy Whitcroft				my $ln = $linenr - 1;
338213214adfSAndy Whitcroft				for my $chunk (@chunks) {
338313214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
338413214adfSAndy Whitcroft
3385773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
3386773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3387773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
3388773647a0SAndy Whitcroft
3389aad4f614SJoe Perches					$allowed[$allow] = 0;
3390773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3391773647a0SAndy Whitcroft
3392773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
3393773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
3394773647a0SAndy Whitcroft
3395773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3396cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
3397cf655043SAndy Whitcroft
3398773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
339913214adfSAndy Whitcroft
340013214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
340113214adfSAndy Whitcroft
3402aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3403cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
3404cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
3405aad4f614SJoe Perches						$allowed[$allow] = 1;
340613214adfSAndy Whitcroft					}
340713214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
3408cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
3409aad4f614SJoe Perches						$allowed[$allow] = 1;
341013214adfSAndy Whitcroft					}
3411cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
3412cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
3413aad4f614SJoe Perches						$allowed[$allow] = 1;
341413214adfSAndy Whitcroft					}
3415aad4f614SJoe Perches					$allow++;
341613214adfSAndy Whitcroft				}
3417aad4f614SJoe Perches				if ($seen) {
3418aad4f614SJoe Perches					my $sum_allowed = 0;
3419aad4f614SJoe Perches					foreach (@allowed) {
3420aad4f614SJoe Perches						$sum_allowed += $_;
3421aad4f614SJoe Perches					}
3422aad4f614SJoe Perches					if ($sum_allowed == 0) {
3423000d1cc1SJoe Perches						WARN("BRACES",
3424000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
3425aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
3426aad4f614SJoe Perches						 $seen != $allow) {
3427aad4f614SJoe Perches						CHK("BRACES",
3428aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
3429aad4f614SJoe Perches					}
343013214adfSAndy Whitcroft				}
343113214adfSAndy Whitcroft			}
343213214adfSAndy Whitcroft		}
3433773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
343413214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
3435cf655043SAndy Whitcroft			my $allowed = 0;
3436f0a594c1SAndy Whitcroft
3437cf655043SAndy Whitcroft			# Check the pre-context.
3438cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3439cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
3440cf655043SAndy Whitcroft				$allowed = 1;
3441f0a594c1SAndy Whitcroft			}
3442773647a0SAndy Whitcroft
3443773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
3444773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
3445773647a0SAndy Whitcroft
3446cf655043SAndy Whitcroft			# Check the condition.
3447cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
3448773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3449cf655043SAndy Whitcroft			if (defined $cond) {
3450773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
3451cf655043SAndy Whitcroft			}
3452cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
3453cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
3454cf655043SAndy Whitcroft				$allowed = 1;
3455cf655043SAndy Whitcroft			}
3456cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
3457cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
3458cf655043SAndy Whitcroft				$allowed = 1;
3459cf655043SAndy Whitcroft			}
3460cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
3461cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
3462cf655043SAndy Whitcroft				$allowed = 1;
3463cf655043SAndy Whitcroft			}
3464cf655043SAndy Whitcroft			# Check the post-context.
3465cf655043SAndy Whitcroft			if (defined $chunks[1]) {
3466cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
3467cf655043SAndy Whitcroft				if (defined $cond) {
3468773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
3469cf655043SAndy Whitcroft				}
3470cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
3471cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
3472cf655043SAndy Whitcroft					$allowed = 1;
3473cf655043SAndy Whitcroft				}
3474cf655043SAndy Whitcroft			}
3475cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
347669932487SJustin P. Mattock				my $herectx = $here . "\n";
3477f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
3478cf655043SAndy Whitcroft
3479f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
348069932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
3481cf655043SAndy Whitcroft				}
3482cf655043SAndy Whitcroft
3483000d1cc1SJoe Perches				WARN("BRACES",
3484000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
3485f0a594c1SAndy Whitcroft			}
3486f0a594c1SAndy Whitcroft		}
3487f0a594c1SAndy Whitcroft
34880979ae66SJoe Perches# check for unnecessary blank lines around braces
348977b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
34900979ae66SJoe Perches			CHK("BRACES",
34910979ae66SJoe Perches			    "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
34920979ae66SJoe Perches		}
349377b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
34940979ae66SJoe Perches			CHK("BRACES",
34950979ae66SJoe Perches			    "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
34960979ae66SJoe Perches		}
34970979ae66SJoe Perches
34984a0df2efSAndy Whitcroft# no volatiles please
34996c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
35006c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
3501000d1cc1SJoe Perches			WARN("VOLATILE",
3502000d1cc1SJoe Perches			     "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
35034a0df2efSAndy Whitcroft		}
35044a0df2efSAndy Whitcroft
350500df344fSAndy Whitcroft# warn about #if 0
3506c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3507000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
3508000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
3509de7d4f0eSAndy Whitcroft				$herecurr);
35104a0df2efSAndy Whitcroft		}
35114a0df2efSAndy Whitcroft
351203df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
351303df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
351403df4b51SAndy Whitcroft			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
351503df4b51SAndy Whitcroft			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
351603df4b51SAndy Whitcroft				WARN('NEEDLESS_IF',
351703df4b51SAndy Whitcroft				     "$1(NULL) is safe this check is probably not required\n" . $hereprev);
35184c432a8fSGreg Kroah-Hartman			}
35194c432a8fSGreg Kroah-Hartman		}
3520f0a594c1SAndy Whitcroft
35211a15a250SPatrick Pannuto# prefer usleep_range over udelay
352237581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
35231a15a250SPatrick Pannuto			# ignore udelay's < 10, however
352437581c28SBruce Allan			if (! ($1 < 10) ) {
3525000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
3526000d1cc1SJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
35271a15a250SPatrick Pannuto			}
35281a15a250SPatrick Pannuto		}
35291a15a250SPatrick Pannuto
353009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
353109ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
353209ef8725SPatrick Pannuto			if ($1 < 20) {
3533000d1cc1SJoe Perches				WARN("MSLEEP",
3534000d1cc1SJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
353509ef8725SPatrick Pannuto			}
353609ef8725SPatrick Pannuto		}
353709ef8725SPatrick Pannuto
353836ec1939SJoe Perches# check for comparisons of jiffies
353936ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
354036ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
354136ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
354236ec1939SJoe Perches		}
354336ec1939SJoe Perches
35449d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
35459d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
35469d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
35479d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
35489d7a34a5SJoe Perches		}
35499d7a34a5SJoe Perches
355000df344fSAndy Whitcroft# warn about #ifdefs in C files
3551c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
355200df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
355300df344fSAndy Whitcroft#			print "$herecurr";
355400df344fSAndy Whitcroft#			$clean = 0;
355500df344fSAndy Whitcroft#		}
355600df344fSAndy Whitcroft
355722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
3558c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
3559*3705ce5bSJoe Perches			if (ERROR("SPACING",
3560*3705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
3561*3705ce5bSJoe Perches			    $fix) {
3562*3705ce5bSJoe Perches				$fixed[$linenr - 1] =~
3563*3705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
3564*3705ce5bSJoe Perches			}
3565*3705ce5bSJoe Perches
356622f2a2efSAndy Whitcroft		}
356722f2a2efSAndy Whitcroft
35684a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
3569171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
3570171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
35714a0df2efSAndy Whitcroft			my $which = $1;
35724a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3573000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
3574000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
35754a0df2efSAndy Whitcroft			}
35764a0df2efSAndy Whitcroft		}
35774a0df2efSAndy Whitcroft# check for memory barriers without a comment.
35784a0df2efSAndy Whitcroft		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
35794a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3580000d1cc1SJoe Perches				CHK("MEMORY_BARRIER",
3581000d1cc1SJoe Perches				    "memory barrier without comment\n" . $herecurr);
35824a0df2efSAndy Whitcroft			}
35834a0df2efSAndy Whitcroft		}
35844a0df2efSAndy Whitcroft# check of hardware specific defines
3585c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
3586000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
3587000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
35880a920b5bSAndy Whitcroft		}
3589653d4876SAndy Whitcroft
3590d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
3591d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3592000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
3593000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
3594d4977c78STobias Klauser		}
3595d4977c78STobias Klauser
3596de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
3597de7d4f0eSAndy Whitcroft# storage class and type.
35989c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
35999c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
3600000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
3601000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
3602de7d4f0eSAndy Whitcroft		}
3603de7d4f0eSAndy Whitcroft
36048905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
36058905a67cSAndy Whitcroft		if ($line =~ /\b(__inline__|__inline)\b/) {
3606000d1cc1SJoe Perches			WARN("INLINE",
3607000d1cc1SJoe Perches			     "plain inline is preferred over $1\n" . $herecurr);
36088905a67cSAndy Whitcroft		}
36098905a67cSAndy Whitcroft
36103d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
36113d130fd0SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3612000d1cc1SJoe Perches			WARN("PREFER_PACKED",
3613000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
36143d130fd0SJoe Perches		}
36153d130fd0SJoe Perches
361639b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
361739b7e287SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3618000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
3619000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
362039b7e287SJoe Perches		}
362139b7e287SJoe Perches
36225f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
36235f14d3bdSJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
36245f14d3bdSJoe Perches			WARN("PREFER_PRINTF",
36255f14d3bdSJoe Perches			     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
36265f14d3bdSJoe Perches		}
36275f14d3bdSJoe Perches
36286061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
36296061d949SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
36306061d949SJoe Perches			WARN("PREFER_SCANF",
36316061d949SJoe Perches			     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
36326061d949SJoe Perches		}
36336061d949SJoe Perches
36348f53a9b8SJoe Perches# check for sizeof(&)
36358f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
3636000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
3637000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
36388f53a9b8SJoe Perches		}
36398f53a9b8SJoe Perches
364066c80b60SJoe Perches# check for sizeof without parenthesis
364166c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
364266c80b60SJoe Perches			WARN("SIZEOF_PARENTHESIS",
364366c80b60SJoe Perches			     "sizeof $1 should be sizeof($1)\n" . $herecurr);
364466c80b60SJoe Perches		}
364566c80b60SJoe Perches
3646428e2fdcSJoe Perches# check for line continuations in quoted strings with odd counts of "
3647428e2fdcSJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3648000d1cc1SJoe Perches			WARN("LINE_CONTINUATIONS",
3649000d1cc1SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
3650428e2fdcSJoe Perches		}
3651428e2fdcSJoe Perches
365288982feaSJoe Perches# check for struct spinlock declarations
365388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
365488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
365588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
365688982feaSJoe Perches		}
365788982feaSJoe Perches
3658a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
3659a6962d72SJoe Perches		if ($line =~ /\bseq_printf\s*\(/) {
3660a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
3661a6962d72SJoe Perches			if ($fmt !~ /[^\\]\%/) {
3662a6962d72SJoe Perches				WARN("PREFER_SEQ_PUTS",
3663a6962d72SJoe Perches				     "Prefer seq_puts to seq_printf\n" . $herecurr);
3664a6962d72SJoe Perches			}
3665a6962d72SJoe Perches		}
3666a6962d72SJoe Perches
3667554e165cSAndy Whitcroft# Check for misused memsets
3668d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3669d1fe9c09SJoe Perches		    defined $stat &&
3670d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3671554e165cSAndy Whitcroft
3672d7c76ba7SJoe Perches			my $ms_addr = $2;
3673d1fe9c09SJoe Perches			my $ms_val = $7;
3674d1fe9c09SJoe Perches			my $ms_size = $12;
3675d7c76ba7SJoe Perches
3676554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
3677554e165cSAndy Whitcroft				ERROR("MEMSET",
3678d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3679554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
3680554e165cSAndy Whitcroft				WARN("MEMSET",
3681d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3682d7c76ba7SJoe Perches			}
3683d7c76ba7SJoe Perches		}
3684d7c76ba7SJoe Perches
3685d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
3686d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3687d1fe9c09SJoe Perches		    defined $stat &&
3688d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3689d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
3690d7c76ba7SJoe Perches				my $call = $1;
3691d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
3692d7c76ba7SJoe Perches				my $arg1 = $3;
3693d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
3694d1fe9c09SJoe Perches				my $arg2 = $8;
3695d7c76ba7SJoe Perches				my $cast;
3696d7c76ba7SJoe Perches
3697d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3698d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
3699d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
3700d7c76ba7SJoe Perches					$cast = $cast1;
3701d7c76ba7SJoe Perches				} else {
3702d7c76ba7SJoe Perches					$cast = $cast2;
3703d7c76ba7SJoe Perches				}
3704d7c76ba7SJoe Perches				WARN("MINMAX",
3705d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3706554e165cSAndy Whitcroft			}
3707554e165cSAndy Whitcroft		}
3708554e165cSAndy Whitcroft
37094a273195SJoe Perches# check usleep_range arguments
37104a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
37114a273195SJoe Perches		    defined $stat &&
37124a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
37134a273195SJoe Perches			my $min = $1;
37144a273195SJoe Perches			my $max = $7;
37154a273195SJoe Perches			if ($min eq $max) {
37164a273195SJoe Perches				WARN("USLEEP_RANGE",
37174a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
37184a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
37194a273195SJoe Perches				 $min > $max) {
37204a273195SJoe Perches				WARN("USLEEP_RANGE",
37214a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
37224a273195SJoe Perches			}
37234a273195SJoe Perches		}
37244a273195SJoe Perches
3725de7d4f0eSAndy Whitcroft# check for new externs in .c files.
3726171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
3727c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
3728171ae1a4SAndy Whitcroft		{
3729c45dcabdSAndy Whitcroft			my $function_name = $1;
3730c45dcabdSAndy Whitcroft			my $paren_space = $2;
3731171ae1a4SAndy Whitcroft
3732171ae1a4SAndy Whitcroft			my $s = $stat;
3733171ae1a4SAndy Whitcroft			if (defined $cond) {
3734171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
3735171ae1a4SAndy Whitcroft			}
3736c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
3737c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
3738c45dcabdSAndy Whitcroft			{
3739000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
3740000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
3741de7d4f0eSAndy Whitcroft			}
3742de7d4f0eSAndy Whitcroft
3743171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
3744000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
3745000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
3746171ae1a4SAndy Whitcroft			}
37479c9ba34eSAndy Whitcroft
37489c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
37499c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
37509c9ba34eSAndy Whitcroft		{
3751000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
3752000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
3753171ae1a4SAndy Whitcroft		}
3754171ae1a4SAndy Whitcroft
3755de7d4f0eSAndy Whitcroft# checks for new __setup's
3756de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
3757de7d4f0eSAndy Whitcroft			my $name = $1;
3758de7d4f0eSAndy Whitcroft
3759de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
3760000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
3761000d1cc1SJoe Perches				    "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
3762de7d4f0eSAndy Whitcroft			}
3763653d4876SAndy Whitcroft		}
37649c0ca6f9SAndy Whitcroft
37659c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
3766caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
3767000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
3768000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
37699c0ca6f9SAndy Whitcroft		}
377013214adfSAndy Whitcroft
3771a640d25cSJoe Perches# alloc style
3772a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
3773a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3774a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
3775a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
3776a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
3777a640d25cSJoe Perches		}
3778a640d25cSJoe Perches
3779972fdea2SJoe Perches# check for krealloc arg reuse
3780972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3781972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
3782972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
3783972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
3784972fdea2SJoe Perches		}
3785972fdea2SJoe Perches
37865ce59ae0SJoe Perches# check for alloc argument mismatch
37875ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
37885ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
37895ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
37905ce59ae0SJoe Perches		}
37915ce59ae0SJoe Perches
3792caf2a54fSJoe Perches# check for multiple semicolons
3793caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
3794000d1cc1SJoe Perches			WARN("ONE_SEMICOLON",
3795000d1cc1SJoe Perches			     "Statements terminations use 1 semicolon\n" . $herecurr);
3796d1e2ad07SJoe Perches		}
3797d1e2ad07SJoe Perches
3798d1e2ad07SJoe Perches# check for switch/default statements without a break;
3799d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3800d1e2ad07SJoe Perches		    defined $stat &&
3801d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
3802d1e2ad07SJoe Perches			my $ctx = '';
3803d1e2ad07SJoe Perches			my $herectx = $here . "\n";
3804d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
3805d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
3806d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
3807d1e2ad07SJoe Perches			}
3808d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
3809d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
3810caf2a54fSJoe Perches		}
3811caf2a54fSJoe Perches
381213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
381313214adfSAndy Whitcroft		if ($line =~ /__FUNCTION__/) {
3814000d1cc1SJoe Perches			WARN("USE_FUNC",
3815000d1cc1SJoe Perches			     "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
381613214adfSAndy Whitcroft		}
3817773647a0SAndy Whitcroft
38182c92488aSJoe Perches# check for use of yield()
38192c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
38202c92488aSJoe Perches			WARN("YIELD",
38212c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
38222c92488aSJoe Perches		}
38232c92488aSJoe Perches
3824179f8f40SJoe Perches# check for comparisons against true and false
3825179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
3826179f8f40SJoe Perches			my $lead = $1;
3827179f8f40SJoe Perches			my $arg = $2;
3828179f8f40SJoe Perches			my $test = $3;
3829179f8f40SJoe Perches			my $otype = $4;
3830179f8f40SJoe Perches			my $trail = $5;
3831179f8f40SJoe Perches			my $op = "!";
3832179f8f40SJoe Perches
3833179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
3834179f8f40SJoe Perches
3835179f8f40SJoe Perches			my $type = lc($otype);
3836179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
3837179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
3838179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
3839179f8f40SJoe Perches					$op = "";
3840179f8f40SJoe Perches				}
3841179f8f40SJoe Perches
3842179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
3843179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
3844179f8f40SJoe Perches
3845179f8f40SJoe Perches## maybe suggesting a correct construct would better
3846179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
3847179f8f40SJoe Perches
3848179f8f40SJoe Perches			}
3849179f8f40SJoe Perches		}
3850179f8f40SJoe Perches
38514882720bSThomas Gleixner# check for semaphores initialized locked
38524882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
3853000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
3854000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
3855773647a0SAndy Whitcroft		}
38566712d858SJoe Perches
385767d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
385867d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
3859000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
386067d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
3861773647a0SAndy Whitcroft		}
38626712d858SJoe Perches
3863f3db6639SMichael Ellerman# check for __initcall(), use device_initcall() explicitly please
3864f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
3865000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
3866000d1cc1SJoe Perches			     "please use device_initcall() instead of __initcall()\n" . $herecurr);
3867f3db6639SMichael Ellerman		}
38686712d858SJoe Perches
386979404849SEmese Revfy# check for various ops structs, ensure they are const.
387079404849SEmese Revfy		my $struct_ops = qr{acpi_dock_ops|
387179404849SEmese Revfy				address_space_operations|
387279404849SEmese Revfy				backlight_ops|
387379404849SEmese Revfy				block_device_operations|
387479404849SEmese Revfy				dentry_operations|
387579404849SEmese Revfy				dev_pm_ops|
387679404849SEmese Revfy				dma_map_ops|
387779404849SEmese Revfy				extent_io_ops|
387879404849SEmese Revfy				file_lock_operations|
387979404849SEmese Revfy				file_operations|
388079404849SEmese Revfy				hv_ops|
388179404849SEmese Revfy				ide_dma_ops|
388279404849SEmese Revfy				intel_dvo_dev_ops|
388379404849SEmese Revfy				item_operations|
388479404849SEmese Revfy				iwl_ops|
388579404849SEmese Revfy				kgdb_arch|
388679404849SEmese Revfy				kgdb_io|
388779404849SEmese Revfy				kset_uevent_ops|
388879404849SEmese Revfy				lock_manager_operations|
388979404849SEmese Revfy				microcode_ops|
389079404849SEmese Revfy				mtrr_ops|
389179404849SEmese Revfy				neigh_ops|
389279404849SEmese Revfy				nlmsvc_binding|
389379404849SEmese Revfy				pci_raw_ops|
389479404849SEmese Revfy				pipe_buf_operations|
389579404849SEmese Revfy				platform_hibernation_ops|
389679404849SEmese Revfy				platform_suspend_ops|
389779404849SEmese Revfy				proto_ops|
389879404849SEmese Revfy				rpc_pipe_ops|
389979404849SEmese Revfy				seq_operations|
390079404849SEmese Revfy				snd_ac97_build_ops|
390179404849SEmese Revfy				soc_pcmcia_socket_ops|
390279404849SEmese Revfy				stacktrace_ops|
390379404849SEmese Revfy				sysfs_ops|
390479404849SEmese Revfy				tty_operations|
390579404849SEmese Revfy				usb_mon_operations|
390679404849SEmese Revfy				wd_ops}x;
39076903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
390879404849SEmese Revfy		    $line =~ /\bstruct\s+($struct_ops)\b/) {
3909000d1cc1SJoe Perches			WARN("CONST_STRUCT",
3910000d1cc1SJoe Perches			     "struct $1 should normally be const\n" .
39116903ffb2SAndy Whitcroft				$herecurr);
39122b6db5cbSAndy Whitcroft		}
3913773647a0SAndy Whitcroft
3914773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
3915773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
3916773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
3917c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
3918c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
3919171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
3920171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
3921171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
3922773647a0SAndy Whitcroft		{
3923000d1cc1SJoe Perches			WARN("NR_CPUS",
3924000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
3925773647a0SAndy Whitcroft		}
39269c9ba34eSAndy Whitcroft
39279c9ba34eSAndy Whitcroft# check for %L{u,d,i} in strings
39289c9ba34eSAndy Whitcroft		my $string;
39299c9ba34eSAndy Whitcroft		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
39309c9ba34eSAndy Whitcroft			$string = substr($rawline, $-[1], $+[1] - $-[1]);
39312a1bc5d5SAndy Whitcroft			$string =~ s/%%/__/g;
39329c9ba34eSAndy Whitcroft			if ($string =~ /(?<!%)%L[udi]/) {
3933000d1cc1SJoe Perches				WARN("PRINTF_L",
3934000d1cc1SJoe Perches				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
39359c9ba34eSAndy Whitcroft				last;
39369c9ba34eSAndy Whitcroft			}
39379c9ba34eSAndy Whitcroft		}
3938691d77b6SAndy Whitcroft
3939691d77b6SAndy Whitcroft# whine mightly about in_atomic
3940691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
3941691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
3942000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
3943000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
3944f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
3945000d1cc1SJoe Perches				WARN("IN_ATOMIC",
3946000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
3947691d77b6SAndy Whitcroft			}
3948691d77b6SAndy Whitcroft		}
39491704f47bSPeter Zijlstra
39501704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
39511704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
39521704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
39531704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
39541704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
39551704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
3956000d1cc1SJoe Perches				ERROR("LOCKDEP",
3957000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
39581704f47bSPeter Zijlstra			}
39591704f47bSPeter Zijlstra		}
396088f8831cSDave Jones
396188f8831cSDave Jones		if ($line =~ /debugfs_create_file.*S_IWUGO/ ||
396288f8831cSDave Jones		    $line =~ /DEVICE_ATTR.*S_IWUGO/ ) {
3963000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
3964000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
396588f8831cSDave Jones		}
396613214adfSAndy Whitcroft	}
396713214adfSAndy Whitcroft
396813214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
396913214adfSAndy Whitcroft	# so just keep quiet.
397013214adfSAndy Whitcroft	if ($#rawlines == -1) {
397113214adfSAndy Whitcroft		exit(0);
39720a920b5bSAndy Whitcroft	}
39730a920b5bSAndy Whitcroft
39748905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
39758905a67cSAndy Whitcroft	# things that appear to be patches.
39768905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
39778905a67cSAndy Whitcroft		exit(0);
39788905a67cSAndy Whitcroft	}
39798905a67cSAndy Whitcroft
39808905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
39818905a67cSAndy Whitcroft	# just keep quiet.
39828905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
39838905a67cSAndy Whitcroft		exit(0);
39848905a67cSAndy Whitcroft	}
39858905a67cSAndy Whitcroft
39868905a67cSAndy Whitcroft	if (!$is_patch) {
3987000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
3988000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
39890a920b5bSAndy Whitcroft	}
39900a920b5bSAndy Whitcroft	if ($is_patch && $chk_signoff && $signoff == 0) {
3991000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
3992000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
39930a920b5bSAndy Whitcroft	}
39940a920b5bSAndy Whitcroft
3995f0a594c1SAndy Whitcroft	print report_dump();
399613214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
399713214adfSAndy Whitcroft		print "$filename " if ($summary_file);
39986c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
39996c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
40006c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
40018905a67cSAndy Whitcroft		print "\n" if ($quiet == 0);
40026c72ffaaSAndy Whitcroft	}
40038905a67cSAndy Whitcroft
4004d2c0a235SAndy Whitcroft	if ($quiet == 0) {
4005d1fe9c09SJoe Perches
4006d1fe9c09SJoe Perches		if ($^V lt 5.10.0) {
4007d1fe9c09SJoe Perches			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
4008d1fe9c09SJoe Perches			print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
4009d1fe9c09SJoe Perches		}
4010d1fe9c09SJoe Perches
4011d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
4012d2c0a235SAndy Whitcroft		# then suggest that.
4013d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
4014d2c0a235SAndy Whitcroft			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
4015d2c0a235SAndy Whitcroft			print "      scripts/cleanfile\n\n";
4016b0781216SMike Frysinger			$rpt_cleaners = 0;
4017d2c0a235SAndy Whitcroft		}
4018d2c0a235SAndy Whitcroft	}
4019d2c0a235SAndy Whitcroft
402011232688SArtem Bityutskiy	if ($quiet == 0 && keys %ignore_type) {
4021000d1cc1SJoe Perches	    print "NOTE: Ignored message types:";
4022000d1cc1SJoe Perches	    foreach my $ignore (sort keys %ignore_type) {
4023000d1cc1SJoe Perches		print " $ignore";
4024000d1cc1SJoe Perches	    }
402511232688SArtem Bityutskiy	    print "\n\n";
4026000d1cc1SJoe Perches	}
4027000d1cc1SJoe Perches
4028*3705ce5bSJoe Perches	if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
4029*3705ce5bSJoe Perches		my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes";
4030*3705ce5bSJoe Perches		my $linecount = 0;
4031*3705ce5bSJoe Perches		my $f;
4032*3705ce5bSJoe Perches
4033*3705ce5bSJoe Perches		open($f, '>', $newfile)
4034*3705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
4035*3705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
4036*3705ce5bSJoe Perches			$linecount++;
4037*3705ce5bSJoe Perches			if ($file) {
4038*3705ce5bSJoe Perches				if ($linecount > 3) {
4039*3705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
4040*3705ce5bSJoe Perches					print $f $fixed_line. "\n";
4041*3705ce5bSJoe Perches				}
4042*3705ce5bSJoe Perches			} else {
4043*3705ce5bSJoe Perches				print $f $fixed_line . "\n";
4044*3705ce5bSJoe Perches			}
4045*3705ce5bSJoe Perches		}
4046*3705ce5bSJoe Perches		close($f);
4047*3705ce5bSJoe Perches
4048*3705ce5bSJoe Perches		if (!$quiet) {
4049*3705ce5bSJoe Perches			print << "EOM";
4050*3705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
4051*3705ce5bSJoe Perches
4052*3705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
4053*3705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
4054*3705ce5bSJoe Perches
4055*3705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
4056*3705ce5bSJoe PerchesNo warranties, expressed or implied...
4057*3705ce5bSJoe Perches
4058*3705ce5bSJoe PerchesEOM
4059*3705ce5bSJoe Perches		}
4060*3705ce5bSJoe Perches	}
4061*3705ce5bSJoe Perches
40620a920b5bSAndy Whitcroft	if ($clean == 1 && $quiet == 0) {
4063c2fdda0dSAndy Whitcroft		print "$vname has no obvious style problems and is ready for submission.\n"
40640a920b5bSAndy Whitcroft	}
40650a920b5bSAndy Whitcroft	if ($clean == 0 && $quiet == 0) {
4066000d1cc1SJoe Perches		print << "EOM";
4067000d1cc1SJoe Perches$vname has style problems, please review.
4068000d1cc1SJoe Perches
4069000d1cc1SJoe PerchesIf any of these errors are false positives, please report
4070000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS.
4071000d1cc1SJoe PerchesEOM
40720a920b5bSAndy Whitcroft	}
407313214adfSAndy Whitcroft
40740a920b5bSAndy Whitcroft	return $clean;
40750a920b5bSAndy Whitcroft}
4076