xref: /linux-6.15/scripts/checkpatch.pl (revision 485ff23e)
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;
9c707a81dSJoe Perchesuse POSIX;
1036061e38SJoe Perchesuse File::Basename;
1136061e38SJoe Perchesuse Cwd 'abs_path';
120a920b5bSAndy Whitcroft
130a920b5bSAndy Whitcroftmy $P = $0;
1436061e38SJoe Perchesmy $D = dirname(abs_path($P));
150a920b5bSAndy Whitcroft
16000d1cc1SJoe Perchesmy $V = '0.32';
170a920b5bSAndy Whitcroft
180a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
190a920b5bSAndy Whitcroft
200a920b5bSAndy Whitcroftmy $quiet = 0;
210a920b5bSAndy Whitcroftmy $tree = 1;
220a920b5bSAndy Whitcroftmy $chk_signoff = 1;
230a920b5bSAndy Whitcroftmy $chk_patch = 1;
24773647a0SAndy Whitcroftmy $tst_only;
256c72ffaaSAndy Whitcroftmy $emacs = 0;
268905a67cSAndy Whitcroftmy $terse = 0;
276c72ffaaSAndy Whitcroftmy $file = 0;
286c72ffaaSAndy Whitcroftmy $check = 0;
292ac73b4fSJoe Perchesmy $check_orig = 0;
308905a67cSAndy Whitcroftmy $summary = 1;
318905a67cSAndy Whitcroftmy $mailback = 0;
3213214adfSAndy Whitcroftmy $summary_file = 0;
33000d1cc1SJoe Perchesmy $show_types = 0;
343705ce5bSJoe Perchesmy $fix = 0;
359624b8d6SJoe Perchesmy $fix_inplace = 0;
366c72ffaaSAndy Whitcroftmy $root;
37c2fdda0dSAndy Whitcroftmy %debug;
383445686aSJoe Perchesmy %camelcase = ();
3991bfe484SJoe Perchesmy %use_type = ();
4091bfe484SJoe Perchesmy @use = ();
4191bfe484SJoe Perchesmy %ignore_type = ();
42000d1cc1SJoe Perchesmy @ignore = ();
4377f5b10aSHannes Edermy $help = 0;
44000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
456cd7f386SJoe Perchesmy $max_line_length = 80;
46d62a201fSDave Hansenmy $ignore_perl_version = 0;
47d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
4856193274SVadim Bendeburymy $min_conf_desc_length = 4;
4966b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
50ebfd7d62SJoe Perchesmy $codespell = 0;
51ebfd7d62SJoe Perchesmy $codespellfile = "/usr/local/share/codespell/dictionary.txt";
5277f5b10aSHannes Eder
5377f5b10aSHannes Edersub help {
5477f5b10aSHannes Eder	my ($exitcode) = @_;
5577f5b10aSHannes Eder
5677f5b10aSHannes Eder	print << "EOM";
5777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
5877f5b10aSHannes EderVersion: $V
5977f5b10aSHannes Eder
6077f5b10aSHannes EderOptions:
6177f5b10aSHannes Eder  -q, --quiet                quiet
6277f5b10aSHannes Eder  --no-tree                  run without a kernel tree
6377f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
6477f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
6577f5b10aSHannes Eder  --emacs                    emacs compile window format
6677f5b10aSHannes Eder  --terse                    one line per report
6777f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
6877f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
6991bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
70000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
716cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
7256193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
73000d1cc1SJoe Perches  --show-types               show the message "types" in the output
7477f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
7577f5b10aSHannes Eder  --no-summary               suppress the per-file summary
7677f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
7777f5b10aSHannes Eder  --summary-file             include the filename in summary
7877f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
7977f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
8077f5b10aSHannes Eder                             is all off)
8177f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
8277f5b10aSHannes Eder                             literally
833705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
843705ce5bSJoe Perches                             If correctable single-line errors exist, create
853705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
863705ce5bSJoe Perches                             with potential errors corrected to the preferred
873705ce5bSJoe Perches                             checkpatch style
889624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
899624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
909624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
91d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
92d62a201fSDave Hansen                             runtime errors.
93ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
94ebfd7d62SJoe Perches                             (default:/usr/local/share/codespell/dictionary.txt)
95ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
9677f5b10aSHannes Eder  -h, --help, --version      display this help and exit
9777f5b10aSHannes Eder
9877f5b10aSHannes EderWhen FILE is - read standard input.
9977f5b10aSHannes EderEOM
10077f5b10aSHannes Eder
10177f5b10aSHannes Eder	exit($exitcode);
10277f5b10aSHannes Eder}
10377f5b10aSHannes Eder
104000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
105000d1cc1SJoe Perchesif (-f $conf) {
106000d1cc1SJoe Perches	my @conf_args;
107000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
108000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
109000d1cc1SJoe Perches
110000d1cc1SJoe Perches	while (<$conffile>) {
111000d1cc1SJoe Perches		my $line = $_;
112000d1cc1SJoe Perches
113000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
114000d1cc1SJoe Perches		$line =~ s/^\s*//g;
115000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
116000d1cc1SJoe Perches
117000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
118000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
119000d1cc1SJoe Perches
120000d1cc1SJoe Perches		my @words = split(" ", $line);
121000d1cc1SJoe Perches		foreach my $word (@words) {
122000d1cc1SJoe Perches			last if ($word =~ m/^#/);
123000d1cc1SJoe Perches			push (@conf_args, $word);
124000d1cc1SJoe Perches		}
125000d1cc1SJoe Perches	}
126000d1cc1SJoe Perches	close($conffile);
127000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
128000d1cc1SJoe Perches}
129000d1cc1SJoe Perches
1300a920b5bSAndy WhitcroftGetOptions(
1316c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1320a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1330a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1340a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1356c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1368905a67cSAndy Whitcroft	'terse!'	=> \$terse,
13777f5b10aSHannes Eder	'f|file!'	=> \$file,
1386c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1396c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
140000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
14191bfe484SJoe Perches	'types=s'	=> \@use,
142000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
1436cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
14456193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
1456c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
1468905a67cSAndy Whitcroft	'summary!'	=> \$summary,
1478905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
14813214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
1493705ce5bSJoe Perches	'fix!'		=> \$fix,
1509624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
151d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
152c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
153773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
154ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
155ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
15677f5b10aSHannes Eder	'h|help'	=> \$help,
15777f5b10aSHannes Eder	'version'	=> \$help
15877f5b10aSHannes Eder) or help(1);
15977f5b10aSHannes Eder
16077f5b10aSHannes Ederhelp(0) if ($help);
1610a920b5bSAndy Whitcroft
1629624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
1632ac73b4fSJoe Perches$check_orig = $check;
1649624b8d6SJoe Perches
1650a920b5bSAndy Whitcroftmy $exit = 0;
1660a920b5bSAndy Whitcroft
167d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
168d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
169d62a201fSDave Hansen	if (!$ignore_perl_version) {
170d62a201fSDave Hansen		exit(1);
171d62a201fSDave Hansen	}
172d62a201fSDave Hansen}
173d62a201fSDave Hansen
1740a920b5bSAndy Whitcroftif ($#ARGV < 0) {
17577f5b10aSHannes Eder	print "$P: no input files\n";
1760a920b5bSAndy Whitcroft	exit(1);
1770a920b5bSAndy Whitcroft}
1780a920b5bSAndy Whitcroft
17991bfe484SJoe Perchessub hash_save_array_words {
18091bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
18191bfe484SJoe Perches
18291bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
18391bfe484SJoe Perches	foreach my $word (@array) {
184000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
185000d1cc1SJoe Perches		$word =~ s/^\s*//g;
186000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
187000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
188000d1cc1SJoe Perches
189000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
190000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
191000d1cc1SJoe Perches
19291bfe484SJoe Perches		$hashRef->{$word}++;
193000d1cc1SJoe Perches	}
19491bfe484SJoe Perches}
19591bfe484SJoe Perches
19691bfe484SJoe Perchessub hash_show_words {
19791bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
19891bfe484SJoe Perches
19958cb3cf6SJoe Perches	if ($quiet == 0 && keys %$hashRef) {
20091bfe484SJoe Perches		print "NOTE: $prefix message types:";
20158cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
20291bfe484SJoe Perches			print " $word";
20391bfe484SJoe Perches		}
20491bfe484SJoe Perches		print "\n\n";
20591bfe484SJoe Perches	}
20691bfe484SJoe Perches}
20791bfe484SJoe Perches
20891bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
20991bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
210000d1cc1SJoe Perches
211c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
212c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
2137429c690SAndy Whitcroftmy $dbg_type = 0;
214a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
215c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
21621caa13cSAndy Whitcroft	## no critic
21721caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
21821caa13cSAndy Whitcroft	die "$@" if ($@);
219c2fdda0dSAndy Whitcroft}
220c2fdda0dSAndy Whitcroft
221d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
222d2c0a235SAndy Whitcroft
2238905a67cSAndy Whitcroftif ($terse) {
2248905a67cSAndy Whitcroft	$emacs = 1;
2258905a67cSAndy Whitcroft	$quiet++;
2268905a67cSAndy Whitcroft}
2278905a67cSAndy Whitcroft
2286c72ffaaSAndy Whitcroftif ($tree) {
2296c72ffaaSAndy Whitcroft	if (defined $root) {
2306c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
2316c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
2326c72ffaaSAndy Whitcroft		}
2336c72ffaaSAndy Whitcroft	} else {
2346c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
2356c72ffaaSAndy Whitcroft			$root = '.';
2366c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
2376c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
2386c72ffaaSAndy Whitcroft			$root = $1;
2396c72ffaaSAndy Whitcroft		}
2406c72ffaaSAndy Whitcroft	}
2416c72ffaaSAndy Whitcroft
2426c72ffaaSAndy Whitcroft	if (!defined $root) {
2430a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
2440a920b5bSAndy Whitcroft		exit(2);
2450a920b5bSAndy Whitcroft	}
2466c72ffaaSAndy Whitcroft}
2476c72ffaaSAndy Whitcroft
2486c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
2496c72ffaaSAndy Whitcroft
2502ceb532bSAndy Whitcroftour $Ident	= qr{
2512ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
2522ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
2532ceb532bSAndy Whitcroft		}x;
2546c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
2556c72ffaaSAndy Whitcroftour $Sparse	= qr{
2566c72ffaaSAndy Whitcroft			__user|
2576c72ffaaSAndy Whitcroft			__kernel|
2586c72ffaaSAndy Whitcroft			__force|
2596c72ffaaSAndy Whitcroft			__iomem|
2606c72ffaaSAndy Whitcroft			__must_check|
2616c72ffaaSAndy Whitcroft			__init_refok|
262417495edSAndy Whitcroft			__kprobes|
263165e72a6SSven Eckelmann			__ref|
264165e72a6SSven Eckelmann			__rcu
2656c72ffaaSAndy Whitcroft		}x;
266e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
267e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
268e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
269e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
270e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
2718716de38SJoe Perches
27252131292SWolfram Sang# Notes to $Attribute:
27352131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
2746c72ffaaSAndy Whitcroftour $Attribute	= qr{
2756c72ffaaSAndy Whitcroft			const|
27603f1df7dSJoe Perches			__percpu|
27703f1df7dSJoe Perches			__nocast|
27803f1df7dSJoe Perches			__safe|
27903f1df7dSJoe Perches			__bitwise__|
28003f1df7dSJoe Perches			__packed__|
28103f1df7dSJoe Perches			__packed2__|
28203f1df7dSJoe Perches			__naked|
28303f1df7dSJoe Perches			__maybe_unused|
28403f1df7dSJoe Perches			__always_unused|
28503f1df7dSJoe Perches			__noreturn|
28603f1df7dSJoe Perches			__used|
28703f1df7dSJoe Perches			__cold|
288e23ef1f3SJoe Perches			__pure|
28903f1df7dSJoe Perches			__noclone|
29003f1df7dSJoe Perches			__deprecated|
2916c72ffaaSAndy Whitcroft			__read_mostly|
2926c72ffaaSAndy Whitcroft			__kprobes|
2938716de38SJoe Perches			$InitAttribute|
29424e1d81aSAndy Whitcroft			____cacheline_aligned|
29524e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
2965fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
2975fe3af11SAndy Whitcroft			__weak
2986c72ffaaSAndy Whitcroft		  }x;
299c45dcabdSAndy Whitcroftour $Modifier;
30091cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
3016c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
3026c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
3036c72ffaaSAndy Whitcroft
30495e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
30595e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
30695e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
30795e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
3082435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
309c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
310326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
311326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
312326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
31374349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
3142435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
315326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
316447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
31723f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
3186c72ffaaSAndy Whitcroftour $Operators	= qr{
3196c72ffaaSAndy Whitcroft			<=|>=|==|!=|
3206c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
32123f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
3226c72ffaaSAndy Whitcroft		  }x;
3236c72ffaaSAndy Whitcroft
32491cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
32591cb5195SJoe Perches
326ab7e23f3SJoe Perchesour $BasicType;
3278905a67cSAndy Whitcroftour $NonptrType;
3281813087dSJoe Perchesour $NonptrTypeMisordered;
3298716de38SJoe Perchesour $NonptrTypeWithAttr;
3308905a67cSAndy Whitcroftour $Type;
3311813087dSJoe Perchesour $TypeMisordered;
3328905a67cSAndy Whitcroftour $Declare;
3331813087dSJoe Perchesour $DeclareMisordered;
3348905a67cSAndy Whitcroft
33515662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
33615662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
337171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
338171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
339171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
340171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
341171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
342171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
343171ae1a4SAndy Whitcroft}x;
344171ae1a4SAndy Whitcroft
34515662b3eSJoe Perchesour $UTF8	= qr{
34615662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
34715662b3eSJoe Perches	| $NON_ASCII_UTF8
34815662b3eSJoe Perches}x;
34915662b3eSJoe Perches
350e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
351021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
352021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
353021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
354021158b4SJoe Perches)};
355e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
356fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
3578ed22cadSAndy Whitcroft	atomic_t
3588ed22cadSAndy Whitcroft)};
359e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
360e6176fa4SJoe Perches	$typeC99Typedefs\b|
361e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
362e6176fa4SJoe Perches	$typeKernelTypedefs\b
363e6176fa4SJoe Perches)};
3648ed22cadSAndy Whitcroft
365691e669bSJoe Perchesour $logFunctions = qr{(?x:
3666e60c02eSJoe Perches	printk(?:_ratelimited|_once|)|
3677d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
3686e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
369b0531722SJoe Perches	panic|
37006668727SJoe Perches	MODULE_[A-Z_]+|
37106668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
372691e669bSJoe Perches)};
373691e669bSJoe Perches
37420112475SJoe Perchesour $signature_tags = qr{(?xi:
37520112475SJoe Perches	Signed-off-by:|
37620112475SJoe Perches	Acked-by:|
37720112475SJoe Perches	Tested-by:|
37820112475SJoe Perches	Reviewed-by:|
37920112475SJoe Perches	Reported-by:|
3808543ae12SMugunthan V N	Suggested-by:|
38120112475SJoe Perches	To:|
38220112475SJoe Perches	Cc:
38320112475SJoe Perches)};
38420112475SJoe Perches
3851813087dSJoe Perchesour @typeListMisordered = (
3861813087dSJoe Perches	qr{char\s+(?:un)?signed},
3871813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
3881813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
3891813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
3901813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
3911813087dSJoe Perches	qr{short\s+(?:un)?signed},
3921813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
3931813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
3941813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
3951813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
3961813087dSJoe Perches	qr{int\s+(?:un)?signed},
3971813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
3981813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
3991813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
4001813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
4011813087dSJoe Perches	qr{long\s+(?:un)?signed},
4021813087dSJoe Perches);
4031813087dSJoe Perches
4048905a67cSAndy Whitcroftour @typeList = (
4058905a67cSAndy Whitcroft	qr{void},
4060c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
4070c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
4080c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
4090c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
4100c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
4110c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
4120c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
4130c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
4140c773d9dSJoe Perches	qr{(?:un)?signed},
4158905a67cSAndy Whitcroft	qr{float},
4168905a67cSAndy Whitcroft	qr{double},
4178905a67cSAndy Whitcroft	qr{bool},
4188905a67cSAndy Whitcroft	qr{struct\s+$Ident},
4198905a67cSAndy Whitcroft	qr{union\s+$Ident},
4208905a67cSAndy Whitcroft	qr{enum\s+$Ident},
4218905a67cSAndy Whitcroft	qr{${Ident}_t},
4228905a67cSAndy Whitcroft	qr{${Ident}_handler},
4238905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
4241813087dSJoe Perches	@typeListMisordered,
4258905a67cSAndy Whitcroft);
426*485ff23eSAlex Dowadour @typeListFile = ();
4278716de38SJoe Perchesour @typeListWithAttr = (
4288716de38SJoe Perches	@typeList,
4298716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
4308716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
4318716de38SJoe Perches);
4328716de38SJoe Perches
433c45dcabdSAndy Whitcroftour @modifierList = (
434c45dcabdSAndy Whitcroft	qr{fastcall},
435c45dcabdSAndy Whitcroft);
436*485ff23eSAlex Dowadour @modifierListFile = ();
4378905a67cSAndy Whitcroft
4382435880fSJoe Perchesour @mode_permission_funcs = (
4392435880fSJoe Perches	["module_param", 3],
4402435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
4412435880fSJoe Perches	["module_param_array_named", 5],
4422435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
4432435880fSJoe Perches	["proc_create(?:_data|)", 2],
4442435880fSJoe Perches	["(?:CLASS|DEVICE|SENSOR)_ATTR", 2],
4452435880fSJoe Perches);
4462435880fSJoe Perches
447515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
448515a235eSJoe Perchesour $mode_perms_search = "";
449515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
450515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
451515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
452515a235eSJoe Perches}
453515a235eSJoe Perches
454b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
455b392c64fSJoe Perches	S_IWUGO		|
456b392c64fSJoe Perches	S_IWOTH		|
457b392c64fSJoe Perches	S_IRWXUGO	|
458b392c64fSJoe Perches	S_IALLUGO	|
459b392c64fSJoe Perches	0[0-7][0-7][2367]
460b392c64fSJoe Perches}x;
461b392c64fSJoe Perches
4627840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
4637840a94cSWolfram Sang	irq|
464cdcee686SSergey Ryazanov	memory|
465cdcee686SSergey Ryazanov	time|
466cdcee686SSergey Ryazanov	reboot
4677840a94cSWolfram Sang)};
4687840a94cSWolfram Sang# memory.h: ARM has a custom one
4697840a94cSWolfram Sang
47066b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
47166b47b4aSKees Cookmy $misspellings;
47266b47b4aSKees Cookmy %spelling_fix;
47336061e38SJoe Perches
47436061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
47566b47b4aSKees Cook	while (<$spelling>) {
47666b47b4aSKees Cook		my $line = $_;
47766b47b4aSKees Cook
47866b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
47966b47b4aSKees Cook		$line =~ s/^\s*//g;
48066b47b4aSKees Cook
48166b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
48266b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
48366b47b4aSKees Cook
48466b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
48566b47b4aSKees Cook
48666b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
48766b47b4aSKees Cook	}
48866b47b4aSKees Cook	close($spelling);
48936061e38SJoe Perches} else {
49036061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
49136061e38SJoe Perches}
49266b47b4aSKees Cook
493ebfd7d62SJoe Perchesif ($codespell) {
494ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
495ebfd7d62SJoe Perches		while (<$spelling>) {
496ebfd7d62SJoe Perches			my $line = $_;
497ebfd7d62SJoe Perches
498ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
499ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
500ebfd7d62SJoe Perches
501ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
502ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
503ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
504ebfd7d62SJoe Perches
505ebfd7d62SJoe Perches			$line =~ s/,.*$//;
506ebfd7d62SJoe Perches
507ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
508ebfd7d62SJoe Perches
509ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
510ebfd7d62SJoe Perches		}
511ebfd7d62SJoe Perches		close($spelling);
512ebfd7d62SJoe Perches	} else {
513ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
514ebfd7d62SJoe Perches	}
515ebfd7d62SJoe Perches}
516ebfd7d62SJoe Perches
517ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
518ebfd7d62SJoe Perches
5198905a67cSAndy Whitcroftsub build_types {
520*485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
521*485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
5221813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
5238716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
524c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
525ab7e23f3SJoe Perches	$BasicType	= qr{
526ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
527ab7e23f3SJoe Perches				(?:${all}\b)
528ab7e23f3SJoe Perches		}x;
5298905a67cSAndy Whitcroft	$NonptrType	= qr{
530d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
531cf655043SAndy Whitcroft			(?:
5326b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
5338ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
534c45dcabdSAndy Whitcroft				(?:${all}\b)
535cf655043SAndy Whitcroft			)
536c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
5378905a67cSAndy Whitcroft		  }x;
5381813087dSJoe Perches	$NonptrTypeMisordered	= qr{
5391813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
5401813087dSJoe Perches			(?:
5411813087dSJoe Perches				(?:${Misordered}\b)
5421813087dSJoe Perches			)
5431813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
5441813087dSJoe Perches		  }x;
5458716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
5468716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
5478716de38SJoe Perches			(?:
5488716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
5498716de38SJoe Perches				(?:$typeTypedefs\b)|
5508716de38SJoe Perches				(?:${allWithAttr}\b)
5518716de38SJoe Perches			)
5528716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
5538716de38SJoe Perches		  }x;
5548905a67cSAndy Whitcroft	$Type	= qr{
555c45dcabdSAndy Whitcroft			$NonptrType
5561574a29fSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
557c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
5588905a67cSAndy Whitcroft		  }x;
5591813087dSJoe Perches	$TypeMisordered	= qr{
5601813087dSJoe Perches			$NonptrTypeMisordered
5611813087dSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
5621813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
5631813087dSJoe Perches		  }x;
56491cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
5651813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
5668905a67cSAndy Whitcroft}
5678905a67cSAndy Whitcroftbuild_types();
5686c72ffaaSAndy Whitcroft
5697d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
570d1fe9c09SJoe Perches
571d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
572d1fe9c09SJoe Perches# requires at least perl version v5.10.0
573d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
574d1fe9c09SJoe Perches
575d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
5762435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
577c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
5787d2367afSJoe Perches
579f8422308SJoe Perchesour $declaration_macros = qr{(?x:
580f8422308SJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,2}\s*\(|
581f8422308SJoe Perches	(?:$Storage\s+)?LIST_HEAD\s*\(|
582f8422308SJoe Perches	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
583f8422308SJoe Perches)};
584f8422308SJoe Perches
5857d2367afSJoe Perchessub deparenthesize {
5867d2367afSJoe Perches	my ($string) = @_;
5877d2367afSJoe Perches	return "" if (!defined($string));
5885b9553abSJoe Perches
5895b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
5905b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
5915b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
5925b9553abSJoe Perches	}
5935b9553abSJoe Perches
5947d2367afSJoe Perches	$string =~ s@\s+@ @g;
5955b9553abSJoe Perches
5967d2367afSJoe Perches	return $string;
5977d2367afSJoe Perches}
5987d2367afSJoe Perches
5993445686aSJoe Perchessub seed_camelcase_file {
6003445686aSJoe Perches	my ($file) = @_;
6013445686aSJoe Perches
6023445686aSJoe Perches	return if (!(-f $file));
6033445686aSJoe Perches
6043445686aSJoe Perches	local $/;
6053445686aSJoe Perches
6063445686aSJoe Perches	open(my $include_file, '<', "$file")
6073445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
6083445686aSJoe Perches	my $text = <$include_file>;
6093445686aSJoe Perches	close($include_file);
6103445686aSJoe Perches
6113445686aSJoe Perches	my @lines = split('\n', $text);
6123445686aSJoe Perches
6133445686aSJoe Perches	foreach my $line (@lines) {
6143445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
6153445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
6163445686aSJoe Perches			$camelcase{$1} = 1;
61711ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
61811ea516aSJoe Perches			$camelcase{$1} = 1;
61911ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
6203445686aSJoe Perches			$camelcase{$1} = 1;
6213445686aSJoe Perches		}
6223445686aSJoe Perches	}
6233445686aSJoe Perches}
6243445686aSJoe Perches
6253445686aSJoe Perchesmy $camelcase_seeded = 0;
6263445686aSJoe Perchessub seed_camelcase_includes {
6273445686aSJoe Perches	return if ($camelcase_seeded);
6283445686aSJoe Perches
6293445686aSJoe Perches	my $files;
630c707a81dSJoe Perches	my $camelcase_cache = "";
631c707a81dSJoe Perches	my @include_files = ();
632c707a81dSJoe Perches
633c707a81dSJoe Perches	$camelcase_seeded = 1;
634351b2a1fSJoe Perches
6353645e328SRichard Genoud	if (-e ".git") {
636351b2a1fSJoe Perches		my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
637351b2a1fSJoe Perches		chomp $git_last_include_commit;
638c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
639c707a81dSJoe Perches	} else {
640c707a81dSJoe Perches		my $last_mod_date = 0;
641c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
642c707a81dSJoe Perches		@include_files = split('\n', $files);
643c707a81dSJoe Perches		foreach my $file (@include_files) {
644c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
645c707a81dSJoe Perches						   localtime((stat $file)[9]));
646c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
647c707a81dSJoe Perches		}
648c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
649c707a81dSJoe Perches	}
650c707a81dSJoe Perches
651c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
652c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
653c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
654351b2a1fSJoe Perches		while (<$camelcase_file>) {
655351b2a1fSJoe Perches			chomp;
656351b2a1fSJoe Perches			$camelcase{$_} = 1;
657351b2a1fSJoe Perches		}
658351b2a1fSJoe Perches		close($camelcase_file);
659351b2a1fSJoe Perches
660351b2a1fSJoe Perches		return;
661351b2a1fSJoe Perches	}
662c707a81dSJoe Perches
6633645e328SRichard Genoud	if (-e ".git") {
664c707a81dSJoe Perches		$files = `git ls-files "include/*.h"`;
665c707a81dSJoe Perches		@include_files = split('\n', $files);
6663445686aSJoe Perches	}
667c707a81dSJoe Perches
6683445686aSJoe Perches	foreach my $file (@include_files) {
6693445686aSJoe Perches		seed_camelcase_file($file);
6703445686aSJoe Perches	}
671351b2a1fSJoe Perches
672c707a81dSJoe Perches	if ($camelcase_cache ne "") {
673351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
674c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
675c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
676351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
677351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
678351b2a1fSJoe Perches		}
679351b2a1fSJoe Perches		close($camelcase_file);
680351b2a1fSJoe Perches	}
6813445686aSJoe Perches}
6823445686aSJoe Perches
683d311cd44SJoe Perchessub git_commit_info {
684d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
685d311cd44SJoe Perches
686d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
687d311cd44SJoe Perches
688d311cd44SJoe Perches	my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
689d311cd44SJoe Perches	$output =~ s/^\s*//gm;
690d311cd44SJoe Perches	my @lines = split("\n", $output);
691d311cd44SJoe Perches
6920d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
6930d7835fcSJoe Perches
694d311cd44SJoe Perches	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
695d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
696d311cd44SJoe Perches# all matching commit ids, but it's very slow...
697d311cd44SJoe Perches#
698d311cd44SJoe Perches#		echo "checking commits $1..."
699d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
700d311cd44SJoe Perches#		while read line ; do
701d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
702d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
703d311cd44SJoe Perches#		done
704d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
705d311cd44SJoe Perches	} else {
706d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
707d311cd44SJoe Perches		$desc = substr($lines[0], 41);
708d311cd44SJoe Perches	}
709d311cd44SJoe Perches
710d311cd44SJoe Perches	return ($id, $desc);
711d311cd44SJoe Perches}
712d311cd44SJoe Perches
7136c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
7140a920b5bSAndy Whitcroft
71500df344fSAndy Whitcroftmy @rawlines = ();
716c2fdda0dSAndy Whitcroftmy @lines = ();
7173705ce5bSJoe Perchesmy @fixed = ();
718d752fcc8SJoe Perchesmy @fixed_inserted = ();
719d752fcc8SJoe Perchesmy @fixed_deleted = ();
720194f66fcSJoe Perchesmy $fixlinenr = -1;
721194f66fcSJoe Perches
722c2fdda0dSAndy Whitcroftmy $vname;
7236c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
72421caa13cSAndy Whitcroft	my $FILE;
7256c72ffaaSAndy Whitcroft	if ($file) {
72621caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
7276c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
72821caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
72921caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
7306c72ffaaSAndy Whitcroft	} else {
73121caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
7326c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
7336c72ffaaSAndy Whitcroft	}
734c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
735c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
736c2fdda0dSAndy Whitcroft	} else {
737c2fdda0dSAndy Whitcroft		$vname = $filename;
738c2fdda0dSAndy Whitcroft	}
73921caa13cSAndy Whitcroft	while (<$FILE>) {
7400a920b5bSAndy Whitcroft		chomp;
74100df344fSAndy Whitcroft		push(@rawlines, $_);
7426c72ffaaSAndy Whitcroft	}
74321caa13cSAndy Whitcroft	close($FILE);
744c2fdda0dSAndy Whitcroft	if (!process($filename)) {
7450a920b5bSAndy Whitcroft		$exit = 1;
7460a920b5bSAndy Whitcroft	}
74700df344fSAndy Whitcroft	@rawlines = ();
74813214adfSAndy Whitcroft	@lines = ();
7493705ce5bSJoe Perches	@fixed = ();
750d752fcc8SJoe Perches	@fixed_inserted = ();
751d752fcc8SJoe Perches	@fixed_deleted = ();
752194f66fcSJoe Perches	$fixlinenr = -1;
753*485ff23eSAlex Dowad	@modifierListFile = ();
754*485ff23eSAlex Dowad	@typeListFile = ();
755*485ff23eSAlex Dowad	build_types();
7560a920b5bSAndy Whitcroft}
7570a920b5bSAndy Whitcroft
7580a920b5bSAndy Whitcroftexit($exit);
7590a920b5bSAndy Whitcroft
7600a920b5bSAndy Whitcroftsub top_of_kernel_tree {
7616c72ffaaSAndy Whitcroft	my ($root) = @_;
7626c72ffaaSAndy Whitcroft
7636c72ffaaSAndy Whitcroft	my @tree_check = (
7646c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
7656c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
7666c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
7676c72ffaaSAndy Whitcroft	);
7686c72ffaaSAndy Whitcroft
7696c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
7706c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
7710a920b5bSAndy Whitcroft			return 0;
7720a920b5bSAndy Whitcroft		}
7736c72ffaaSAndy Whitcroft	}
7746c72ffaaSAndy Whitcroft	return 1;
7756c72ffaaSAndy Whitcroft}
7760a920b5bSAndy Whitcroft
77720112475SJoe Perchessub parse_email {
77820112475SJoe Perches	my ($formatted_email) = @_;
77920112475SJoe Perches
78020112475SJoe Perches	my $name = "";
78120112475SJoe Perches	my $address = "";
78220112475SJoe Perches	my $comment = "";
78320112475SJoe Perches
78420112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
78520112475SJoe Perches		$name = $1;
78620112475SJoe Perches		$address = $2;
78720112475SJoe Perches		$comment = $3 if defined $3;
78820112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
78920112475SJoe Perches		$address = $1;
79020112475SJoe Perches		$comment = $2 if defined $2;
79120112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
79220112475SJoe Perches		$address = $1;
79320112475SJoe Perches		$comment = $2 if defined $2;
79420112475SJoe Perches		$formatted_email =~ s/$address.*$//;
79520112475SJoe Perches		$name = $formatted_email;
7963705ce5bSJoe Perches		$name = trim($name);
79720112475SJoe Perches		$name =~ s/^\"|\"$//g;
79820112475SJoe Perches		# If there's a name left after stripping spaces and
79920112475SJoe Perches		# leading quotes, and the address doesn't have both
80020112475SJoe Perches		# leading and trailing angle brackets, the address
80120112475SJoe Perches		# is invalid. ie:
80220112475SJoe Perches		#   "joe smith [email protected]" bad
80320112475SJoe Perches		#   "joe smith <[email protected]" bad
80420112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
80520112475SJoe Perches			$name = "";
80620112475SJoe Perches			$address = "";
80720112475SJoe Perches			$comment = "";
80820112475SJoe Perches		}
80920112475SJoe Perches	}
81020112475SJoe Perches
8113705ce5bSJoe Perches	$name = trim($name);
81220112475SJoe Perches	$name =~ s/^\"|\"$//g;
8133705ce5bSJoe Perches	$address = trim($address);
81420112475SJoe Perches	$address =~ s/^\<|\>$//g;
81520112475SJoe Perches
81620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
81720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
81820112475SJoe Perches		$name = "\"$name\"";
81920112475SJoe Perches	}
82020112475SJoe Perches
82120112475SJoe Perches	return ($name, $address, $comment);
82220112475SJoe Perches}
82320112475SJoe Perches
82420112475SJoe Perchessub format_email {
82520112475SJoe Perches	my ($name, $address) = @_;
82620112475SJoe Perches
82720112475SJoe Perches	my $formatted_email;
82820112475SJoe Perches
8293705ce5bSJoe Perches	$name = trim($name);
83020112475SJoe Perches	$name =~ s/^\"|\"$//g;
8313705ce5bSJoe Perches	$address = trim($address);
83220112475SJoe Perches
83320112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
83420112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
83520112475SJoe Perches		$name = "\"$name\"";
83620112475SJoe Perches	}
83720112475SJoe Perches
83820112475SJoe Perches	if ("$name" eq "") {
83920112475SJoe Perches		$formatted_email = "$address";
84020112475SJoe Perches	} else {
84120112475SJoe Perches		$formatted_email = "$name <$address>";
84220112475SJoe Perches	}
84320112475SJoe Perches
84420112475SJoe Perches	return $formatted_email;
84520112475SJoe Perches}
84620112475SJoe Perches
847d311cd44SJoe Perchessub which {
848d311cd44SJoe Perches	my ($bin) = @_;
849d311cd44SJoe Perches
850d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
851d311cd44SJoe Perches		if (-e "$path/$bin") {
852d311cd44SJoe Perches			return "$path/$bin";
853d311cd44SJoe Perches		}
854d311cd44SJoe Perches	}
855d311cd44SJoe Perches
856d311cd44SJoe Perches	return "";
857d311cd44SJoe Perches}
858d311cd44SJoe Perches
859000d1cc1SJoe Perchessub which_conf {
860000d1cc1SJoe Perches	my ($conf) = @_;
861000d1cc1SJoe Perches
862000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
863000d1cc1SJoe Perches		if (-e "$path/$conf") {
864000d1cc1SJoe Perches			return "$path/$conf";
865000d1cc1SJoe Perches		}
866000d1cc1SJoe Perches	}
867000d1cc1SJoe Perches
868000d1cc1SJoe Perches	return "";
869000d1cc1SJoe Perches}
870000d1cc1SJoe Perches
8710a920b5bSAndy Whitcroftsub expand_tabs {
8720a920b5bSAndy Whitcroft	my ($str) = @_;
8730a920b5bSAndy Whitcroft
8740a920b5bSAndy Whitcroft	my $res = '';
8750a920b5bSAndy Whitcroft	my $n = 0;
8760a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
8770a920b5bSAndy Whitcroft		if ($c eq "\t") {
8780a920b5bSAndy Whitcroft			$res .= ' ';
8790a920b5bSAndy Whitcroft			$n++;
8800a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
8810a920b5bSAndy Whitcroft				$res .= ' ';
8820a920b5bSAndy Whitcroft			}
8830a920b5bSAndy Whitcroft			next;
8840a920b5bSAndy Whitcroft		}
8850a920b5bSAndy Whitcroft		$res .= $c;
8860a920b5bSAndy Whitcroft		$n++;
8870a920b5bSAndy Whitcroft	}
8880a920b5bSAndy Whitcroft
8890a920b5bSAndy Whitcroft	return $res;
8900a920b5bSAndy Whitcroft}
8916c72ffaaSAndy Whitcroftsub copy_spacing {
892773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
8936c72ffaaSAndy Whitcroft	return $res;
8946c72ffaaSAndy Whitcroft}
8950a920b5bSAndy Whitcroft
8964a0df2efSAndy Whitcroftsub line_stats {
8974a0df2efSAndy Whitcroft	my ($line) = @_;
8984a0df2efSAndy Whitcroft
8994a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
9004a0df2efSAndy Whitcroft	$line =~ s/^.//;
9014a0df2efSAndy Whitcroft	$line = expand_tabs($line);
9024a0df2efSAndy Whitcroft
9034a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
9044a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
9054a0df2efSAndy Whitcroft
9064a0df2efSAndy Whitcroft	return (length($line), length($white));
9074a0df2efSAndy Whitcroft}
9084a0df2efSAndy Whitcroft
909773647a0SAndy Whitcroftmy $sanitise_quote = '';
910773647a0SAndy Whitcroft
911773647a0SAndy Whitcroftsub sanitise_line_reset {
912773647a0SAndy Whitcroft	my ($in_comment) = @_;
913773647a0SAndy Whitcroft
914773647a0SAndy Whitcroft	if ($in_comment) {
915773647a0SAndy Whitcroft		$sanitise_quote = '*/';
916773647a0SAndy Whitcroft	} else {
917773647a0SAndy Whitcroft		$sanitise_quote = '';
918773647a0SAndy Whitcroft	}
919773647a0SAndy Whitcroft}
92000df344fSAndy Whitcroftsub sanitise_line {
92100df344fSAndy Whitcroft	my ($line) = @_;
92200df344fSAndy Whitcroft
92300df344fSAndy Whitcroft	my $res = '';
92400df344fSAndy Whitcroft	my $l = '';
92500df344fSAndy Whitcroft
926c2fdda0dSAndy Whitcroft	my $qlen = 0;
927773647a0SAndy Whitcroft	my $off = 0;
928773647a0SAndy Whitcroft	my $c;
92900df344fSAndy Whitcroft
930773647a0SAndy Whitcroft	# Always copy over the diff marker.
931773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
932773647a0SAndy Whitcroft
933773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
934773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
935773647a0SAndy Whitcroft
936773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
937773647a0SAndy Whitcroft		# and end, all to $;.
938773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
939773647a0SAndy Whitcroft			$sanitise_quote = '*/';
940773647a0SAndy Whitcroft
941773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
942773647a0SAndy Whitcroft			$off++;
94300df344fSAndy Whitcroft			next;
944773647a0SAndy Whitcroft		}
94581bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
946773647a0SAndy Whitcroft			$sanitise_quote = '';
947773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
948773647a0SAndy Whitcroft			$off++;
949773647a0SAndy Whitcroft			next;
950773647a0SAndy Whitcroft		}
951113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
952113f04a8SDaniel Walker			$sanitise_quote = '//';
953113f04a8SDaniel Walker
954113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
955113f04a8SDaniel Walker			$off++;
956113f04a8SDaniel Walker			next;
957113f04a8SDaniel Walker		}
958773647a0SAndy Whitcroft
959773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
960773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
961773647a0SAndy Whitcroft		    $c eq "\\") {
962773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
963773647a0SAndy Whitcroft			$off++;
964773647a0SAndy Whitcroft			next;
965773647a0SAndy Whitcroft		}
966773647a0SAndy Whitcroft		# Regular quotes.
967773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
968773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
969773647a0SAndy Whitcroft				$sanitise_quote = $c;
970773647a0SAndy Whitcroft
971773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
972773647a0SAndy Whitcroft				next;
973773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
974773647a0SAndy Whitcroft				$sanitise_quote = '';
97500df344fSAndy Whitcroft			}
97600df344fSAndy Whitcroft		}
977773647a0SAndy Whitcroft
978fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
979773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
980773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
981113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
982113f04a8SDaniel Walker			substr($res, $off, 1, $;);
983773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
984773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
98500df344fSAndy Whitcroft		} else {
986773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
98700df344fSAndy Whitcroft		}
988c2fdda0dSAndy Whitcroft	}
989c2fdda0dSAndy Whitcroft
990113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
991113f04a8SDaniel Walker		$sanitise_quote = '';
992113f04a8SDaniel Walker	}
993113f04a8SDaniel Walker
994c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
995c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
996c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
997c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
998c2fdda0dSAndy Whitcroft
999c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1000c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1001c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1002c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1003c2fdda0dSAndy Whitcroft	}
1004c2fdda0dSAndy Whitcroft
100500df344fSAndy Whitcroft	return $res;
100600df344fSAndy Whitcroft}
100700df344fSAndy Whitcroft
1008a6962d72SJoe Perchessub get_quoted_string {
1009a6962d72SJoe Perches	my ($line, $rawline) = @_;
1010a6962d72SJoe Perches
10115e4f6ba5SJoe Perches	return "" if ($line !~ m/(\"[X\t]+\")/g);
1012a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1013a6962d72SJoe Perches}
1014a6962d72SJoe Perches
10158905a67cSAndy Whitcroftsub ctx_statement_block {
10168905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
10178905a67cSAndy Whitcroft	my $line = $linenr - 1;
10188905a67cSAndy Whitcroft	my $blk = '';
10198905a67cSAndy Whitcroft	my $soff = $off;
10208905a67cSAndy Whitcroft	my $coff = $off - 1;
1021773647a0SAndy Whitcroft	my $coff_set = 0;
10228905a67cSAndy Whitcroft
102313214adfSAndy Whitcroft	my $loff = 0;
102413214adfSAndy Whitcroft
10258905a67cSAndy Whitcroft	my $type = '';
10268905a67cSAndy Whitcroft	my $level = 0;
1027a2750645SAndy Whitcroft	my @stack = ();
1028cf655043SAndy Whitcroft	my $p;
10298905a67cSAndy Whitcroft	my $c;
10308905a67cSAndy Whitcroft	my $len = 0;
103113214adfSAndy Whitcroft
103213214adfSAndy Whitcroft	my $remainder;
10338905a67cSAndy Whitcroft	while (1) {
1034a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1035a2750645SAndy Whitcroft
1036773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
10378905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
10388905a67cSAndy Whitcroft		# context.
10398905a67cSAndy Whitcroft		if ($off >= $len) {
10408905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1041dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1042c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
10438905a67cSAndy Whitcroft				$remain--;
104413214adfSAndy Whitcroft				$loff = $len;
1045c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
10468905a67cSAndy Whitcroft				$len = length($blk);
10478905a67cSAndy Whitcroft				$line++;
10488905a67cSAndy Whitcroft				last;
10498905a67cSAndy Whitcroft			}
10508905a67cSAndy Whitcroft			# Bail if there is no further context.
10518905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
105213214adfSAndy Whitcroft			if ($off >= $len) {
10538905a67cSAndy Whitcroft				last;
10548905a67cSAndy Whitcroft			}
1055f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1056f74bd194SAndy Whitcroft				$level++;
1057f74bd194SAndy Whitcroft				$type = '#';
1058f74bd194SAndy Whitcroft			}
10598905a67cSAndy Whitcroft		}
1060cf655043SAndy Whitcroft		$p = $c;
10618905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
106213214adfSAndy Whitcroft		$remainder = substr($blk, $off);
10638905a67cSAndy Whitcroft
1064773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
10654635f4fbSAndy Whitcroft
10664635f4fbSAndy Whitcroft		# Handle nested #if/#else.
10674635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
10684635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
10694635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
10704635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
10714635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
10724635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
10734635f4fbSAndy Whitcroft		}
10744635f4fbSAndy Whitcroft
10758905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
10768905a67cSAndy Whitcroft		# outermost level.
10778905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
10788905a67cSAndy Whitcroft			last;
10798905a67cSAndy Whitcroft		}
10808905a67cSAndy Whitcroft
108113214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1082773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1083773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1084773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1085773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1086773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1087773647a0SAndy Whitcroft			$coff_set = 1;
1088773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1089773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
109013214adfSAndy Whitcroft		}
109113214adfSAndy Whitcroft
10928905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
10938905a67cSAndy Whitcroft			$level++;
10948905a67cSAndy Whitcroft			$type = '(';
10958905a67cSAndy Whitcroft		}
10968905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
10978905a67cSAndy Whitcroft			$level--;
10988905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
10998905a67cSAndy Whitcroft
11008905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
11018905a67cSAndy Whitcroft				$coff = $off;
1102773647a0SAndy Whitcroft				$coff_set = 1;
1103773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
11048905a67cSAndy Whitcroft			}
11058905a67cSAndy Whitcroft		}
11068905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
11078905a67cSAndy Whitcroft			$level++;
11088905a67cSAndy Whitcroft			$type = '{';
11098905a67cSAndy Whitcroft		}
11108905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
11118905a67cSAndy Whitcroft			$level--;
11128905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
11138905a67cSAndy Whitcroft
11148905a67cSAndy Whitcroft			if ($level == 0) {
1115b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1116b998e001SPatrick Pannuto					$off++;
1117b998e001SPatrick Pannuto				}
11188905a67cSAndy Whitcroft				last;
11198905a67cSAndy Whitcroft			}
11208905a67cSAndy Whitcroft		}
1121f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1122f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1123f74bd194SAndy Whitcroft			$level--;
1124f74bd194SAndy Whitcroft			$type = '';
1125f74bd194SAndy Whitcroft			$off++;
1126f74bd194SAndy Whitcroft			last;
1127f74bd194SAndy Whitcroft		}
11288905a67cSAndy Whitcroft		$off++;
11298905a67cSAndy Whitcroft	}
1130a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
113113214adfSAndy Whitcroft	if ($off == $len) {
1132a3bb97a7SAndy Whitcroft		$loff = $len + 1;
113313214adfSAndy Whitcroft		$line++;
113413214adfSAndy Whitcroft		$remain--;
113513214adfSAndy Whitcroft	}
11368905a67cSAndy Whitcroft
11378905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
11388905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
11398905a67cSAndy Whitcroft
11408905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
11418905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
11428905a67cSAndy Whitcroft
1143773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
114413214adfSAndy Whitcroft
114513214adfSAndy Whitcroft	return ($statement, $condition,
114613214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
114713214adfSAndy Whitcroft}
114813214adfSAndy Whitcroft
1149cf655043SAndy Whitcroftsub statement_lines {
1150cf655043SAndy Whitcroft	my ($stmt) = @_;
1151cf655043SAndy Whitcroft
1152cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1153cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1154cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1155cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1156cf655043SAndy Whitcroft
1157cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1158cf655043SAndy Whitcroft
1159cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1160cf655043SAndy Whitcroft}
1161cf655043SAndy Whitcroft
1162cf655043SAndy Whitcroftsub statement_rawlines {
1163cf655043SAndy Whitcroft	my ($stmt) = @_;
1164cf655043SAndy Whitcroft
1165cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1166cf655043SAndy Whitcroft
1167cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1168cf655043SAndy Whitcroft}
1169cf655043SAndy Whitcroft
1170cf655043SAndy Whitcroftsub statement_block_size {
1171cf655043SAndy Whitcroft	my ($stmt) = @_;
1172cf655043SAndy Whitcroft
1173cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1174cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1175cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1176cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1177cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1178cf655043SAndy Whitcroft
1179cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1180cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1181cf655043SAndy Whitcroft
1182cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1183cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1184cf655043SAndy Whitcroft
1185cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1186cf655043SAndy Whitcroft		return $stmt_lines;
1187cf655043SAndy Whitcroft	} else {
1188cf655043SAndy Whitcroft		return $stmt_statements;
1189cf655043SAndy Whitcroft	}
1190cf655043SAndy Whitcroft}
1191cf655043SAndy Whitcroft
119213214adfSAndy Whitcroftsub ctx_statement_full {
119313214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
119413214adfSAndy Whitcroft	my ($statement, $condition, $level);
119513214adfSAndy Whitcroft
119613214adfSAndy Whitcroft	my (@chunks);
119713214adfSAndy Whitcroft
1198cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
119913214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
120013214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1201773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
120213214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1203cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1204cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1205cf655043SAndy Whitcroft	}
1206cf655043SAndy Whitcroft
1207cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1208cf655043SAndy Whitcroft	# could continue the statement.
1209cf655043SAndy Whitcroft	for (;;) {
121013214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
121113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1212cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1213773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1214cf655043SAndy Whitcroft		#print "C: push\n";
1215cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
121613214adfSAndy Whitcroft	}
121713214adfSAndy Whitcroft
121813214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
12198905a67cSAndy Whitcroft}
12208905a67cSAndy Whitcroft
12214a0df2efSAndy Whitcroftsub ctx_block_get {
1222f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
12234a0df2efSAndy Whitcroft	my $line;
12244a0df2efSAndy Whitcroft	my $start = $linenr - 1;
12254a0df2efSAndy Whitcroft	my $blk = '';
12264a0df2efSAndy Whitcroft	my @o;
12274a0df2efSAndy Whitcroft	my @c;
12284a0df2efSAndy Whitcroft	my @res = ();
12294a0df2efSAndy Whitcroft
1230f0a594c1SAndy Whitcroft	my $level = 0;
12314635f4fbSAndy Whitcroft	my @stack = ($level);
123200df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
123300df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
123400df344fSAndy Whitcroft		$remain--;
123500df344fSAndy Whitcroft
123600df344fSAndy Whitcroft		$blk .= $rawlines[$line];
12374635f4fbSAndy Whitcroft
12384635f4fbSAndy Whitcroft		# Handle nested #if/#else.
123901464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
12404635f4fbSAndy Whitcroft			push(@stack, $level);
124101464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
12424635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
124301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
12444635f4fbSAndy Whitcroft			$level = pop(@stack);
12454635f4fbSAndy Whitcroft		}
12464635f4fbSAndy Whitcroft
124701464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1248f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1249f0a594c1SAndy Whitcroft			if ($off > 0) {
1250f0a594c1SAndy Whitcroft				$off--;
1251f0a594c1SAndy Whitcroft				next;
1252f0a594c1SAndy Whitcroft			}
12534a0df2efSAndy Whitcroft
1254f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1255f0a594c1SAndy Whitcroft				$level--;
1256f0a594c1SAndy Whitcroft				last if ($level == 0);
1257f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1258f0a594c1SAndy Whitcroft				$level++;
1259f0a594c1SAndy Whitcroft			}
1260f0a594c1SAndy Whitcroft		}
12614a0df2efSAndy Whitcroft
1262f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
126300df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
12644a0df2efSAndy Whitcroft		}
12654a0df2efSAndy Whitcroft
1266f0a594c1SAndy Whitcroft		last if ($level == 0);
12674a0df2efSAndy Whitcroft	}
12684a0df2efSAndy Whitcroft
1269f0a594c1SAndy Whitcroft	return ($level, @res);
12704a0df2efSAndy Whitcroft}
12714a0df2efSAndy Whitcroftsub ctx_block_outer {
12724a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
12734a0df2efSAndy Whitcroft
1274f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1275f0a594c1SAndy Whitcroft	return @r;
12764a0df2efSAndy Whitcroft}
12774a0df2efSAndy Whitcroftsub ctx_block {
12784a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
12794a0df2efSAndy Whitcroft
1280f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1281f0a594c1SAndy Whitcroft	return @r;
1282653d4876SAndy Whitcroft}
1283653d4876SAndy Whitcroftsub ctx_statement {
1284f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1285f0a594c1SAndy Whitcroft
1286f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1287f0a594c1SAndy Whitcroft	return @r;
1288f0a594c1SAndy Whitcroft}
1289f0a594c1SAndy Whitcroftsub ctx_block_level {
1290653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1291653d4876SAndy Whitcroft
1292f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
12934a0df2efSAndy Whitcroft}
12949c0ca6f9SAndy Whitcroftsub ctx_statement_level {
12959c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
12969c0ca6f9SAndy Whitcroft
12979c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
12989c0ca6f9SAndy Whitcroft}
12994a0df2efSAndy Whitcroft
13004a0df2efSAndy Whitcroftsub ctx_locate_comment {
13014a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
13024a0df2efSAndy Whitcroft
13034a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1304beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
13054a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
13064a0df2efSAndy Whitcroft
13074a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
13084a0df2efSAndy Whitcroft	# comment.
13094a0df2efSAndy Whitcroft	my $in_comment = 0;
13104a0df2efSAndy Whitcroft	$current_comment = '';
13114a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
131200df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
131300df344fSAndy Whitcroft		#warn "           $line\n";
13144a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
13154a0df2efSAndy Whitcroft			$in_comment = 1;
13164a0df2efSAndy Whitcroft		}
13174a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
13184a0df2efSAndy Whitcroft			$in_comment = 1;
13194a0df2efSAndy Whitcroft		}
13204a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
13214a0df2efSAndy Whitcroft			$current_comment = '';
13224a0df2efSAndy Whitcroft		}
13234a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
13244a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
13254a0df2efSAndy Whitcroft			$in_comment = 0;
13264a0df2efSAndy Whitcroft		}
13274a0df2efSAndy Whitcroft	}
13284a0df2efSAndy Whitcroft
13294a0df2efSAndy Whitcroft	chomp($current_comment);
13304a0df2efSAndy Whitcroft	return($current_comment);
13314a0df2efSAndy Whitcroft}
13324a0df2efSAndy Whitcroftsub ctx_has_comment {
13334a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
13344a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
13354a0df2efSAndy Whitcroft
133600df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
13374a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
13384a0df2efSAndy Whitcroft
13394a0df2efSAndy Whitcroft	return ($cmt ne '');
13404a0df2efSAndy Whitcroft}
13414a0df2efSAndy Whitcroft
13424d001e4dSAndy Whitcroftsub raw_line {
13434d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
13444d001e4dSAndy Whitcroft
13454d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
13464d001e4dSAndy Whitcroft	$cnt++;
13474d001e4dSAndy Whitcroft
13484d001e4dSAndy Whitcroft	my $line;
13494d001e4dSAndy Whitcroft	while ($cnt) {
13504d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
13514d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
13524d001e4dSAndy Whitcroft		$cnt--;
13534d001e4dSAndy Whitcroft	}
13544d001e4dSAndy Whitcroft
13554d001e4dSAndy Whitcroft	return $line;
13564d001e4dSAndy Whitcroft}
13574d001e4dSAndy Whitcroft
13580a920b5bSAndy Whitcroftsub cat_vet {
13590a920b5bSAndy Whitcroft	my ($vet) = @_;
13609c0ca6f9SAndy Whitcroft	my ($res, $coded);
13610a920b5bSAndy Whitcroft
13629c0ca6f9SAndy Whitcroft	$res = '';
13636c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
13646c72ffaaSAndy Whitcroft		$res .= $1;
13656c72ffaaSAndy Whitcroft		if ($2 ne '') {
13669c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
13676c72ffaaSAndy Whitcroft			$res .= $coded;
13686c72ffaaSAndy Whitcroft		}
13699c0ca6f9SAndy Whitcroft	}
13709c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
13710a920b5bSAndy Whitcroft
13729c0ca6f9SAndy Whitcroft	return $res;
13730a920b5bSAndy Whitcroft}
13740a920b5bSAndy Whitcroft
1375c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1376cf655043SAndy Whitcroftmy $av_pending;
1377c2fdda0dSAndy Whitcroftmy @av_paren_type;
13781f65f947SAndy Whitcroftmy $av_pend_colon;
1379c2fdda0dSAndy Whitcroft
1380c2fdda0dSAndy Whitcroftsub annotate_reset {
1381c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1382cf655043SAndy Whitcroft	$av_pending = '_';
1383cf655043SAndy Whitcroft	@av_paren_type = ('E');
13841f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1385c2fdda0dSAndy Whitcroft}
1386c2fdda0dSAndy Whitcroft
13876c72ffaaSAndy Whitcroftsub annotate_values {
13886c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
13896c72ffaaSAndy Whitcroft
13906c72ffaaSAndy Whitcroft	my $res;
13911f65f947SAndy Whitcroft	my $var = '_' x length($stream);
13926c72ffaaSAndy Whitcroft	my $cur = $stream;
13936c72ffaaSAndy Whitcroft
1394c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
13956c72ffaaSAndy Whitcroft
13966c72ffaaSAndy Whitcroft	while (length($cur)) {
1397773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1398cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1399171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
14006c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1401c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1402c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1403cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1404c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
14056c72ffaaSAndy Whitcroft			}
14066c72ffaaSAndy Whitcroft
1407c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
14089446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
14099446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1410addcdceaSAndy Whitcroft			$type = 'c';
14119446ef56SAndy Whitcroft
1412e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1413c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
14146c72ffaaSAndy Whitcroft			$type = 'T';
14156c72ffaaSAndy Whitcroft
1416389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1417389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1418389a2fe5SAndy Whitcroft			$type = 'T';
1419389a2fe5SAndy Whitcroft
1420c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1421171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1422c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1423171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1424171ae1a4SAndy Whitcroft			if ($2 ne '') {
1425cf655043SAndy Whitcroft				$av_pending = 'N';
1426171ae1a4SAndy Whitcroft			}
1427171ae1a4SAndy Whitcroft			$type = 'E';
1428171ae1a4SAndy Whitcroft
1429c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1430171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1431171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1432171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
14336c72ffaaSAndy Whitcroft
1434c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1435cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1436c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1437cf655043SAndy Whitcroft
1438cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1439cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1440171ae1a4SAndy Whitcroft			$type = 'E';
1441cf655043SAndy Whitcroft
1442c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1443cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1444cf655043SAndy Whitcroft			$av_preprocessor = 1;
1445cf655043SAndy Whitcroft
1446cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1447cf655043SAndy Whitcroft
1448171ae1a4SAndy Whitcroft			$type = 'E';
1449cf655043SAndy Whitcroft
1450c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1451cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1452cf655043SAndy Whitcroft
1453cf655043SAndy Whitcroft			$av_preprocessor = 1;
1454cf655043SAndy Whitcroft
1455cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1456cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1457cf655043SAndy Whitcroft			pop(@av_paren_type);
1458cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1459171ae1a4SAndy Whitcroft			$type = 'E';
14606c72ffaaSAndy Whitcroft
14616c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1462c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
14636c72ffaaSAndy Whitcroft
1464171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1465171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1466171ae1a4SAndy Whitcroft			$av_pending = $type;
1467171ae1a4SAndy Whitcroft			$type = 'N';
1468171ae1a4SAndy Whitcroft
14696c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1470c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
14716c72ffaaSAndy Whitcroft			if (defined $2) {
1472cf655043SAndy Whitcroft				$av_pending = 'V';
14736c72ffaaSAndy Whitcroft			}
14746c72ffaaSAndy Whitcroft			$type = 'N';
14756c72ffaaSAndy Whitcroft
147614b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1477c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
147814b111c1SAndy Whitcroft			$av_pending = 'E';
14796c72ffaaSAndy Whitcroft			$type = 'N';
14806c72ffaaSAndy Whitcroft
14811f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
14821f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
14831f65f947SAndy Whitcroft			$av_pend_colon = 'C';
14841f65f947SAndy Whitcroft			$type = 'N';
14851f65f947SAndy Whitcroft
148614b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1487c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
14886c72ffaaSAndy Whitcroft			$type = 'N';
14896c72ffaaSAndy Whitcroft
14906c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1491c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1492cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1493cf655043SAndy Whitcroft			$av_pending = '_';
14946c72ffaaSAndy Whitcroft			$type = 'N';
14956c72ffaaSAndy Whitcroft
14966c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1497cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1498cf655043SAndy Whitcroft			if ($new_type ne '_') {
1499cf655043SAndy Whitcroft				$type = $new_type;
1500c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1501c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
15026c72ffaaSAndy Whitcroft			} else {
1503c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
15046c72ffaaSAndy Whitcroft			}
15056c72ffaaSAndy Whitcroft
1506c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1507c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1508c8cb2ca3SAndy Whitcroft			$type = 'V';
1509cf655043SAndy Whitcroft			$av_pending = 'V';
15106c72ffaaSAndy Whitcroft
15118e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
15128e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
15131f65f947SAndy Whitcroft				$av_pend_colon = 'B';
15148e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
15158e761b04SAndy Whitcroft				$av_pend_colon = 'L';
15161f65f947SAndy Whitcroft			}
15171f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
15181f65f947SAndy Whitcroft			$type = 'V';
15191f65f947SAndy Whitcroft
15206c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1521c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
15226c72ffaaSAndy Whitcroft			$type = 'V';
15236c72ffaaSAndy Whitcroft
15246c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1525c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
15266c72ffaaSAndy Whitcroft			$type = 'N';
15276c72ffaaSAndy Whitcroft
1528cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1529c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
153013214adfSAndy Whitcroft			$type = 'E';
15311f65f947SAndy Whitcroft			$av_pend_colon = 'O';
153213214adfSAndy Whitcroft
15338e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
15348e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
15358e761b04SAndy Whitcroft			$type = 'C';
15368e761b04SAndy Whitcroft
15371f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
15381f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
15391f65f947SAndy Whitcroft			$type = 'N';
15401f65f947SAndy Whitcroft
15411f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
15421f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
15431f65f947SAndy Whitcroft
15441f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
15451f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
15461f65f947SAndy Whitcroft				$type = 'E';
15471f65f947SAndy Whitcroft			} else {
15481f65f947SAndy Whitcroft				$type = 'N';
15491f65f947SAndy Whitcroft			}
15501f65f947SAndy Whitcroft			$av_pend_colon = 'O';
15511f65f947SAndy Whitcroft
15528e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
155313214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
15546c72ffaaSAndy Whitcroft			$type = 'N';
15556c72ffaaSAndy Whitcroft
15560d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
155774048ed8SAndy Whitcroft			my $variant;
155874048ed8SAndy Whitcroft
155974048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
156074048ed8SAndy Whitcroft			if ($type eq 'V') {
156174048ed8SAndy Whitcroft				$variant = 'B';
156274048ed8SAndy Whitcroft			} else {
156374048ed8SAndy Whitcroft				$variant = 'U';
156474048ed8SAndy Whitcroft			}
156574048ed8SAndy Whitcroft
156674048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
156774048ed8SAndy Whitcroft			$type = 'N';
156874048ed8SAndy Whitcroft
15696c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1570c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
15716c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
15726c72ffaaSAndy Whitcroft				$type = 'N';
15736c72ffaaSAndy Whitcroft			}
15746c72ffaaSAndy Whitcroft
15756c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1576c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
15776c72ffaaSAndy Whitcroft		}
15786c72ffaaSAndy Whitcroft		if (defined $1) {
15796c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
15806c72ffaaSAndy Whitcroft			$res .= $type x length($1);
15816c72ffaaSAndy Whitcroft		}
15826c72ffaaSAndy Whitcroft	}
15836c72ffaaSAndy Whitcroft
15841f65f947SAndy Whitcroft	return ($res, $var);
15856c72ffaaSAndy Whitcroft}
15866c72ffaaSAndy Whitcroft
15878905a67cSAndy Whitcroftsub possible {
158813214adfSAndy Whitcroft	my ($possible, $line) = @_;
15899a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
15900776e594SAndy Whitcroft		^(?:
15910776e594SAndy Whitcroft			$Modifier|
15920776e594SAndy Whitcroft			$Storage|
15930776e594SAndy Whitcroft			$Type|
15949a974fdbSAndy Whitcroft			DEFINE_\S+
15959a974fdbSAndy Whitcroft		)$|
15969a974fdbSAndy Whitcroft		^(?:
15970776e594SAndy Whitcroft			goto|
15980776e594SAndy Whitcroft			return|
15990776e594SAndy Whitcroft			case|
16000776e594SAndy Whitcroft			else|
16010776e594SAndy Whitcroft			asm|__asm__|
160289a88353SAndy Whitcroft			do|
160389a88353SAndy Whitcroft			\#|
160489a88353SAndy Whitcroft			\#\#|
16059a974fdbSAndy Whitcroft		)(?:\s|$)|
16060776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
16079a974fdbSAndy Whitcroft	    )}x;
16089a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
16099a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1610c45dcabdSAndy Whitcroft		# Check for modifiers.
1611c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1612c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1613c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1614c45dcabdSAndy Whitcroft
1615c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1616c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1617d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
16189a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1619d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1620*485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
1621d2506586SAndy Whitcroft				}
16229a974fdbSAndy Whitcroft			}
1623c45dcabdSAndy Whitcroft
1624c45dcabdSAndy Whitcroft		} else {
162513214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1626*485ff23eSAlex Dowad			push(@typeListFile, $possible);
1627c45dcabdSAndy Whitcroft		}
16288905a67cSAndy Whitcroft		build_types();
16290776e594SAndy Whitcroft	} else {
16300776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
16318905a67cSAndy Whitcroft	}
16328905a67cSAndy Whitcroft}
16338905a67cSAndy Whitcroft
16346c72ffaaSAndy Whitcroftmy $prefix = '';
16356c72ffaaSAndy Whitcroft
1636000d1cc1SJoe Perchessub show_type {
1637cbec18afSJoe Perches	my ($type) = @_;
163891bfe484SJoe Perches
1639cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
1640cbec18afSJoe Perches
1641cbec18afSJoe Perches	return !defined $ignore_type{$type};
1642000d1cc1SJoe Perches}
1643000d1cc1SJoe Perches
1644f0a594c1SAndy Whitcroftsub report {
1645cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
1646cbec18afSJoe Perches
1647cbec18afSJoe Perches	if (!show_type($type) ||
1648cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1649773647a0SAndy Whitcroft		return 0;
1650773647a0SAndy Whitcroft	}
1651000d1cc1SJoe Perches	my $line;
1652000d1cc1SJoe Perches	if ($show_types) {
1653cbec18afSJoe Perches		$line = "$prefix$level:$type: $msg\n";
1654000d1cc1SJoe Perches	} else {
1655cbec18afSJoe Perches		$line = "$prefix$level: $msg\n";
1656000d1cc1SJoe Perches	}
16578905a67cSAndy Whitcroft	$line = (split('\n', $line))[0] . "\n" if ($terse);
16588905a67cSAndy Whitcroft
165913214adfSAndy Whitcroft	push(our @report, $line);
1660773647a0SAndy Whitcroft
1661773647a0SAndy Whitcroft	return 1;
1662f0a594c1SAndy Whitcroft}
1663cbec18afSJoe Perches
1664f0a594c1SAndy Whitcroftsub report_dump {
166513214adfSAndy Whitcroft	our @report;
1666f0a594c1SAndy Whitcroft}
1667000d1cc1SJoe Perches
1668d752fcc8SJoe Perchessub fixup_current_range {
1669d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
1670d752fcc8SJoe Perches
1671d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1672d752fcc8SJoe Perches		my $o = $1;
1673d752fcc8SJoe Perches		my $l = $2;
1674d752fcc8SJoe Perches		my $no = $o + $offset;
1675d752fcc8SJoe Perches		my $nl = $l + $length;
1676d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1677d752fcc8SJoe Perches	}
1678d752fcc8SJoe Perches}
1679d752fcc8SJoe Perches
1680d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
1681d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
1682d752fcc8SJoe Perches
1683d752fcc8SJoe Perches	my $range_last_linenr = 0;
1684d752fcc8SJoe Perches	my $delta_offset = 0;
1685d752fcc8SJoe Perches
1686d752fcc8SJoe Perches	my $old_linenr = 0;
1687d752fcc8SJoe Perches	my $new_linenr = 0;
1688d752fcc8SJoe Perches
1689d752fcc8SJoe Perches	my $next_insert = 0;
1690d752fcc8SJoe Perches	my $next_delete = 0;
1691d752fcc8SJoe Perches
1692d752fcc8SJoe Perches	my @lines = ();
1693d752fcc8SJoe Perches
1694d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
1695d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
1696d752fcc8SJoe Perches
1697d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
1698d752fcc8SJoe Perches		my $save_line = 1;
1699d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
1700323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
1701d752fcc8SJoe Perches			$delta_offset = 0;
1702d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
1703d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
1704d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
1705d752fcc8SJoe Perches		}
1706d752fcc8SJoe Perches
1707d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1708d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
1709d752fcc8SJoe Perches			$save_line = 0;
1710d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1711d752fcc8SJoe Perches		}
1712d752fcc8SJoe Perches
1713d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1714d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
1715d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
1716d752fcc8SJoe Perches			$new_linenr++;
1717d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1718d752fcc8SJoe Perches		}
1719d752fcc8SJoe Perches
1720d752fcc8SJoe Perches		if ($save_line) {
1721d752fcc8SJoe Perches			push(@lines, $line);
1722d752fcc8SJoe Perches			$new_linenr++;
1723d752fcc8SJoe Perches		}
1724d752fcc8SJoe Perches
1725d752fcc8SJoe Perches		$old_linenr++;
1726d752fcc8SJoe Perches	}
1727d752fcc8SJoe Perches
1728d752fcc8SJoe Perches	return @lines;
1729d752fcc8SJoe Perches}
1730d752fcc8SJoe Perches
1731f2d7e4d4SJoe Perchessub fix_insert_line {
1732f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1733f2d7e4d4SJoe Perches
1734f2d7e4d4SJoe Perches	my $inserted = {
1735f2d7e4d4SJoe Perches		LINENR => $linenr,
1736f2d7e4d4SJoe Perches		LINE => $line,
1737f2d7e4d4SJoe Perches	};
1738f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
1739f2d7e4d4SJoe Perches}
1740f2d7e4d4SJoe Perches
1741f2d7e4d4SJoe Perchessub fix_delete_line {
1742f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1743f2d7e4d4SJoe Perches
1744f2d7e4d4SJoe Perches	my $deleted = {
1745f2d7e4d4SJoe Perches		LINENR => $linenr,
1746f2d7e4d4SJoe Perches		LINE => $line,
1747f2d7e4d4SJoe Perches	};
1748f2d7e4d4SJoe Perches
1749f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
1750f2d7e4d4SJoe Perches}
1751f2d7e4d4SJoe Perches
1752de7d4f0eSAndy Whitcroftsub ERROR {
1753cbec18afSJoe Perches	my ($type, $msg) = @_;
1754cbec18afSJoe Perches
1755cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
1756de7d4f0eSAndy Whitcroft		our $clean = 0;
17576c72ffaaSAndy Whitcroft		our $cnt_error++;
17583705ce5bSJoe Perches		return 1;
1759de7d4f0eSAndy Whitcroft	}
17603705ce5bSJoe Perches	return 0;
1761773647a0SAndy Whitcroft}
1762de7d4f0eSAndy Whitcroftsub WARN {
1763cbec18afSJoe Perches	my ($type, $msg) = @_;
1764cbec18afSJoe Perches
1765cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
1766de7d4f0eSAndy Whitcroft		our $clean = 0;
17676c72ffaaSAndy Whitcroft		our $cnt_warn++;
17683705ce5bSJoe Perches		return 1;
1769de7d4f0eSAndy Whitcroft	}
17703705ce5bSJoe Perches	return 0;
1771773647a0SAndy Whitcroft}
1772de7d4f0eSAndy Whitcroftsub CHK {
1773cbec18afSJoe Perches	my ($type, $msg) = @_;
1774cbec18afSJoe Perches
1775cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
1776de7d4f0eSAndy Whitcroft		our $clean = 0;
17776c72ffaaSAndy Whitcroft		our $cnt_chk++;
17783705ce5bSJoe Perches		return 1;
17796c72ffaaSAndy Whitcroft	}
17803705ce5bSJoe Perches	return 0;
1781de7d4f0eSAndy Whitcroft}
1782de7d4f0eSAndy Whitcroft
17836ecd9674SAndy Whitcroftsub check_absolute_file {
17846ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
17856ecd9674SAndy Whitcroft	my $file = $absolute;
17866ecd9674SAndy Whitcroft
17876ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
17886ecd9674SAndy Whitcroft
17896ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
17906ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
17916ecd9674SAndy Whitcroft		if (-f "$root/$file") {
17926ecd9674SAndy Whitcroft			##print "file<$file>\n";
17936ecd9674SAndy Whitcroft			last;
17946ecd9674SAndy Whitcroft		}
17956ecd9674SAndy Whitcroft	}
17966ecd9674SAndy Whitcroft	if (! -f _)  {
17976ecd9674SAndy Whitcroft		return 0;
17986ecd9674SAndy Whitcroft	}
17996ecd9674SAndy Whitcroft
18006ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
18016ecd9674SAndy Whitcroft	my $prefix = $absolute;
18026ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
18036ecd9674SAndy Whitcroft
18046ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
18056ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
1806000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
1807000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
18086ecd9674SAndy Whitcroft	}
18096ecd9674SAndy Whitcroft}
18106ecd9674SAndy Whitcroft
18113705ce5bSJoe Perchessub trim {
18123705ce5bSJoe Perches	my ($string) = @_;
18133705ce5bSJoe Perches
1814b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
1815b34c648bSJoe Perches
1816b34c648bSJoe Perches	return $string;
1817b34c648bSJoe Perches}
1818b34c648bSJoe Perches
1819b34c648bSJoe Perchessub ltrim {
1820b34c648bSJoe Perches	my ($string) = @_;
1821b34c648bSJoe Perches
1822b34c648bSJoe Perches	$string =~ s/^\s+//;
1823b34c648bSJoe Perches
1824b34c648bSJoe Perches	return $string;
1825b34c648bSJoe Perches}
1826b34c648bSJoe Perches
1827b34c648bSJoe Perchessub rtrim {
1828b34c648bSJoe Perches	my ($string) = @_;
1829b34c648bSJoe Perches
1830b34c648bSJoe Perches	$string =~ s/\s+$//;
18313705ce5bSJoe Perches
18323705ce5bSJoe Perches	return $string;
18333705ce5bSJoe Perches}
18343705ce5bSJoe Perches
183552ea8506SJoe Perchessub string_find_replace {
183652ea8506SJoe Perches	my ($string, $find, $replace) = @_;
183752ea8506SJoe Perches
183852ea8506SJoe Perches	$string =~ s/$find/$replace/g;
183952ea8506SJoe Perches
184052ea8506SJoe Perches	return $string;
184152ea8506SJoe Perches}
184252ea8506SJoe Perches
18433705ce5bSJoe Perchessub tabify {
18443705ce5bSJoe Perches	my ($leading) = @_;
18453705ce5bSJoe Perches
18463705ce5bSJoe Perches	my $source_indent = 8;
18473705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
18483705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
18493705ce5bSJoe Perches
18503705ce5bSJoe Perches	#convert leading spaces to tabs
18513705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
18523705ce5bSJoe Perches	#Remove spaces before a tab
18533705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
18543705ce5bSJoe Perches
18553705ce5bSJoe Perches	return "$leading";
18563705ce5bSJoe Perches}
18573705ce5bSJoe Perches
1858d1fe9c09SJoe Perchessub pos_last_openparen {
1859d1fe9c09SJoe Perches	my ($line) = @_;
1860d1fe9c09SJoe Perches
1861d1fe9c09SJoe Perches	my $pos = 0;
1862d1fe9c09SJoe Perches
1863d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
1864d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
1865d1fe9c09SJoe Perches
1866d1fe9c09SJoe Perches	my $last_openparen = 0;
1867d1fe9c09SJoe Perches
1868d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
1869d1fe9c09SJoe Perches		return -1;
1870d1fe9c09SJoe Perches	}
1871d1fe9c09SJoe Perches
1872d1fe9c09SJoe Perches	my $len = length($line);
1873d1fe9c09SJoe Perches
1874d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
1875d1fe9c09SJoe Perches		my $string = substr($line, $pos);
1876d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
1877d1fe9c09SJoe Perches			$pos += length($1) - 1;
1878d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
1879d1fe9c09SJoe Perches			$last_openparen = $pos;
1880d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
1881d1fe9c09SJoe Perches			last;
1882d1fe9c09SJoe Perches		}
1883d1fe9c09SJoe Perches	}
1884d1fe9c09SJoe Perches
188591cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
1886d1fe9c09SJoe Perches}
1887d1fe9c09SJoe Perches
18880a920b5bSAndy Whitcroftsub process {
18890a920b5bSAndy Whitcroft	my $filename = shift;
18900a920b5bSAndy Whitcroft
18910a920b5bSAndy Whitcroft	my $linenr=0;
18920a920b5bSAndy Whitcroft	my $prevline="";
1893c2fdda0dSAndy Whitcroft	my $prevrawline="";
18940a920b5bSAndy Whitcroft	my $stashline="";
1895c2fdda0dSAndy Whitcroft	my $stashrawline="";
18960a920b5bSAndy Whitcroft
18974a0df2efSAndy Whitcroft	my $length;
18980a920b5bSAndy Whitcroft	my $indent;
18990a920b5bSAndy Whitcroft	my $previndent=0;
19000a920b5bSAndy Whitcroft	my $stashindent=0;
19010a920b5bSAndy Whitcroft
1902de7d4f0eSAndy Whitcroft	our $clean = 1;
19030a920b5bSAndy Whitcroft	my $signoff = 0;
19040a920b5bSAndy Whitcroft	my $is_patch = 0;
19050a920b5bSAndy Whitcroft
190629ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
190715662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
19082a076f40SJoe Perches	my $commit_log_long_line = 0;
190913f1937eSJoe Perches	my $reported_maintainer_file = 0;
1910fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
1911fa64205dSPasi Savanainen
1912365dd4eaSJoe Perches	my $last_blank_line = 0;
19135e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
1914365dd4eaSJoe Perches
191513214adfSAndy Whitcroft	our @report = ();
19166c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
19176c72ffaaSAndy Whitcroft	our $cnt_error = 0;
19186c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
19196c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
19206c72ffaaSAndy Whitcroft
19210a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
19220a920b5bSAndy Whitcroft	my $realfile = '';
19230a920b5bSAndy Whitcroft	my $realline = 0;
19240a920b5bSAndy Whitcroft	my $realcnt = 0;
19250a920b5bSAndy Whitcroft	my $here = '';
19260a920b5bSAndy Whitcroft	my $in_comment = 0;
1927c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
19280a920b5bSAndy Whitcroft	my $first_line = 0;
19291e855726SWolfram Sang	my $p1_prefix = '';
19300a920b5bSAndy Whitcroft
193113214adfSAndy Whitcroft	my $prev_values = 'E';
193213214adfSAndy Whitcroft
193313214adfSAndy Whitcroft	# suppression flags
1934773647a0SAndy Whitcroft	my %suppress_ifbraces;
1935170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
19362b474a1aSAndy Whitcroft	my %suppress_export;
19373e469cdcSAndy Whitcroft	my $suppress_statement = 0;
1938653d4876SAndy Whitcroft
19397e51f197SJoe Perches	my %signatures = ();
1940323c1260SJoe Perches
1941c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
1942de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
1943c2fdda0dSAndy Whitcroft	#
1944de7d4f0eSAndy Whitcroft	my @setup_docs = ();
1945de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
1946773647a0SAndy Whitcroft
1947d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
1948d8b07710SJoe Perches
1949773647a0SAndy Whitcroft	sanitise_line_reset();
1950c2fdda0dSAndy Whitcroft	my $line;
1951c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
1952773647a0SAndy Whitcroft		$linenr++;
1953773647a0SAndy Whitcroft		$line = $rawline;
1954c2fdda0dSAndy Whitcroft
19553705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
19563705ce5bSJoe Perches
1957773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1958de7d4f0eSAndy Whitcroft			$setup_docs = 0;
1959de7d4f0eSAndy Whitcroft			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1960de7d4f0eSAndy Whitcroft				$setup_docs = 1;
1961de7d4f0eSAndy Whitcroft			}
1962773647a0SAndy Whitcroft			#next;
1963de7d4f0eSAndy Whitcroft		}
1964773647a0SAndy Whitcroft		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1965773647a0SAndy Whitcroft			$realline=$1-1;
1966773647a0SAndy Whitcroft			if (defined $2) {
1967773647a0SAndy Whitcroft				$realcnt=$3+1;
1968773647a0SAndy Whitcroft			} else {
1969773647a0SAndy Whitcroft				$realcnt=1+1;
1970773647a0SAndy Whitcroft			}
1971c45dcabdSAndy Whitcroft			$in_comment = 0;
1972773647a0SAndy Whitcroft
1973773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
1974773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
1975773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
1976773647a0SAndy Whitcroft			# at context start.
1977773647a0SAndy Whitcroft			my $edge;
197801fa9147SAndy Whitcroft			my $cnt = $realcnt;
197901fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
198001fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
198101fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
198201fa9147SAndy Whitcroft				$cnt--;
198301fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
1984721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
1985fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1986fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1987fae17daeSAndy Whitcroft					($edge) = $1;
1988fae17daeSAndy Whitcroft					last;
1989fae17daeSAndy Whitcroft				}
1990773647a0SAndy Whitcroft			}
1991773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
1992773647a0SAndy Whitcroft				$in_comment = 1;
1993773647a0SAndy Whitcroft			}
1994773647a0SAndy Whitcroft
1995773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
1996773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
1997773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
1998773647a0SAndy Whitcroft			if (!defined $edge &&
199983242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2000773647a0SAndy Whitcroft			{
2001773647a0SAndy Whitcroft				$in_comment = 1;
2002773647a0SAndy Whitcroft			}
2003773647a0SAndy Whitcroft
2004773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2005773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2006773647a0SAndy Whitcroft
2007171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2008773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2009171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2010773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2011773647a0SAndy Whitcroft		}
2012773647a0SAndy Whitcroft		push(@lines, $line);
2013773647a0SAndy Whitcroft
2014773647a0SAndy Whitcroft		if ($realcnt > 1) {
2015773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2016773647a0SAndy Whitcroft		} else {
2017773647a0SAndy Whitcroft			$realcnt = 0;
2018773647a0SAndy Whitcroft		}
2019773647a0SAndy Whitcroft
2020773647a0SAndy Whitcroft		#print "==>$rawline\n";
2021773647a0SAndy Whitcroft		#print "-->$line\n";
2022de7d4f0eSAndy Whitcroft
2023de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2024de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2025de7d4f0eSAndy Whitcroft		}
2026de7d4f0eSAndy Whitcroft	}
2027de7d4f0eSAndy Whitcroft
20286c72ffaaSAndy Whitcroft	$prefix = '';
20296c72ffaaSAndy Whitcroft
2030773647a0SAndy Whitcroft	$realcnt = 0;
2031773647a0SAndy Whitcroft	$linenr = 0;
2032194f66fcSJoe Perches	$fixlinenr = -1;
20330a920b5bSAndy Whitcroft	foreach my $line (@lines) {
20340a920b5bSAndy Whitcroft		$linenr++;
2035194f66fcSJoe Perches		$fixlinenr++;
20361b5539b1SJoe Perches		my $sline = $line;	#copy of $line
20371b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
20380a920b5bSAndy Whitcroft
2039c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
20406c72ffaaSAndy Whitcroft
20410a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
20426c72ffaaSAndy Whitcroft		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
20430a920b5bSAndy Whitcroft			$is_patch = 1;
20444a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
20450a920b5bSAndy Whitcroft			$realline=$1-1;
20460a920b5bSAndy Whitcroft			if (defined $2) {
20470a920b5bSAndy Whitcroft				$realcnt=$3+1;
20480a920b5bSAndy Whitcroft			} else {
20490a920b5bSAndy Whitcroft				$realcnt=1+1;
20500a920b5bSAndy Whitcroft			}
2051c2fdda0dSAndy Whitcroft			annotate_reset();
205213214adfSAndy Whitcroft			$prev_values = 'E';
205313214adfSAndy Whitcroft
2054773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2055170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
20562b474a1aSAndy Whitcroft			%suppress_export = ();
20573e469cdcSAndy Whitcroft			$suppress_statement = 0;
20580a920b5bSAndy Whitcroft			next;
20590a920b5bSAndy Whitcroft
20604a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
20614a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
20624a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2063773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
20640a920b5bSAndy Whitcroft			$realline++;
2065d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
20660a920b5bSAndy Whitcroft
20674a0df2efSAndy Whitcroft			# Measure the line length and indent.
2068c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
20690a920b5bSAndy Whitcroft
20700a920b5bSAndy Whitcroft			# Track the previous line.
20710a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
20720a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2073c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2074c2fdda0dSAndy Whitcroft
2075773647a0SAndy Whitcroft			#warn "line<$line>\n";
20766c72ffaaSAndy Whitcroft
2077d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2078d8aaf121SAndy Whitcroft			$realcnt--;
20790a920b5bSAndy Whitcroft		}
20800a920b5bSAndy Whitcroft
2081cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2082cc77cdcaSAndy Whitcroft
20830a920b5bSAndy Whitcroft#make up the handle for any error we report on this line
2084773647a0SAndy Whitcroft		$prefix = "$filename:$realline: " if ($emacs && $file);
2085773647a0SAndy Whitcroft		$prefix = "$filename:$linenr: " if ($emacs && !$file);
2086773647a0SAndy Whitcroft
20876c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
20886c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2089773647a0SAndy Whitcroft
20902ac73b4fSJoe Perches		my $found_file = 0;
2091773647a0SAndy Whitcroft		# extract the filename as it passes
20923bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
20933bf9a009SRabin Vincent			$realfile = $1;
20942b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2095270c49a0SJoe Perches			$in_commit_log = 0;
20962ac73b4fSJoe Perches			$found_file = 1;
20973bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2098773647a0SAndy Whitcroft			$realfile = $1;
20992b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2100270c49a0SJoe Perches			$in_commit_log = 0;
21011e855726SWolfram Sang
21021e855726SWolfram Sang			$p1_prefix = $1;
2103e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2104e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2105000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2106000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
21071e855726SWolfram Sang			}
2108773647a0SAndy Whitcroft
2109c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2110000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2111000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2112773647a0SAndy Whitcroft			}
21132ac73b4fSJoe Perches			$found_file = 1;
21142ac73b4fSJoe Perches		}
21152ac73b4fSJoe Perches
21162ac73b4fSJoe Perches		if ($found_file) {
21172ac73b4fSJoe Perches			if ($realfile =~ m@^(drivers/net/|net/)@) {
21182ac73b4fSJoe Perches				$check = 1;
21192ac73b4fSJoe Perches			} else {
21202ac73b4fSJoe Perches				$check = $check_orig;
21212ac73b4fSJoe Perches			}
2122773647a0SAndy Whitcroft			next;
2123773647a0SAndy Whitcroft		}
2124773647a0SAndy Whitcroft
2125389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
21260a920b5bSAndy Whitcroft
2127c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2128c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2129c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
21300a920b5bSAndy Whitcroft
21316c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
21326c72ffaaSAndy Whitcroft
21333bf9a009SRabin Vincent# Check for incorrect file permissions
21343bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
21353bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
213604db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
213704db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2138000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2139000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
21403bf9a009SRabin Vincent			}
21413bf9a009SRabin Vincent		}
21423bf9a009SRabin Vincent
214320112475SJoe Perches# Check the patch for a signoff:
2144d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
21454a0df2efSAndy Whitcroft			$signoff++;
214615662b3eSJoe Perches			$in_commit_log = 0;
21470a920b5bSAndy Whitcroft		}
214820112475SJoe Perches
2149e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2150e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2151e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2152e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2153e0d975b1SJoe Perches		}
2154e0d975b1SJoe Perches
215520112475SJoe Perches# Check signature styles
2156270c49a0SJoe Perches		if (!$in_header_lines &&
2157ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
215820112475SJoe Perches			my $space_before = $1;
215920112475SJoe Perches			my $sign_off = $2;
216020112475SJoe Perches			my $space_after = $3;
216120112475SJoe Perches			my $email = $4;
216220112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
216320112475SJoe Perches
2164ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2165ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2166ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2167ce0338dfSJoe Perches			}
216820112475SJoe Perches			if (defined $space_before && $space_before ne "") {
21693705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
21703705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
21713705ce5bSJoe Perches				    $fix) {
2172194f66fcSJoe Perches					$fixed[$fixlinenr] =
21733705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
21743705ce5bSJoe Perches				}
217520112475SJoe Perches			}
217620112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
21773705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
21783705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
21793705ce5bSJoe Perches				    $fix) {
2180194f66fcSJoe Perches					$fixed[$fixlinenr] =
21813705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
21823705ce5bSJoe Perches				}
21833705ce5bSJoe Perches
218420112475SJoe Perches			}
218520112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
21863705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
21873705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
21883705ce5bSJoe Perches				    $fix) {
2189194f66fcSJoe Perches					$fixed[$fixlinenr] =
21903705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
21913705ce5bSJoe Perches				}
219220112475SJoe Perches			}
219320112475SJoe Perches
219420112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
219520112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
219620112475SJoe Perches			if ($suggested_email eq "") {
2197000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2198000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
219920112475SJoe Perches			} else {
220020112475SJoe Perches				my $dequoted = $suggested_email;
220120112475SJoe Perches				$dequoted =~ s/^"//;
220220112475SJoe Perches				$dequoted =~ s/" </ </;
220320112475SJoe Perches				# Don't force email to have quotes
220420112475SJoe Perches				# Allow just an angle bracketed address
220520112475SJoe Perches				if ("$dequoted$comment" ne $email &&
220620112475SJoe Perches				    "<$email_address>$comment" ne $email &&
220720112475SJoe Perches				    "$suggested_email$comment" ne $email) {
2208000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2209000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
221020112475SJoe Perches				}
22110a920b5bSAndy Whitcroft			}
22127e51f197SJoe Perches
22137e51f197SJoe Perches# Check for duplicate signatures
22147e51f197SJoe Perches			my $sig_nospace = $line;
22157e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
22167e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
22177e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
22187e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
22197e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
22207e51f197SJoe Perches			} else {
22217e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
22227e51f197SJoe Perches			}
22230a920b5bSAndy Whitcroft		}
22240a920b5bSAndy Whitcroft
2225a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2226a2fe16b9SJoe Perches		if ($in_header_lines &&
2227a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2228a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2229a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2230a2fe16b9SJoe Perches		}
2231a2fe16b9SJoe Perches
22329b3189ebSJoe Perches# Check for old stable address
22339b3189ebSJoe Perches		if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
22349b3189ebSJoe Perches			ERROR("STABLE_ADDRESS",
22359b3189ebSJoe Perches			      "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
22369b3189ebSJoe Perches		}
22379b3189ebSJoe Perches
22387ebd05efSChristopher Covington# Check for unwanted Gerrit info
22397ebd05efSChristopher Covington		if ($in_commit_log && $line =~ /^\s*change-id:/i) {
22407ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
22417ebd05efSChristopher Covington			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
22427ebd05efSChristopher Covington		}
22437ebd05efSChristopher Covington
22442a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
22452a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
22462a076f40SJoe Perches		    length($line) > 75) {
22472a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
22482a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
22492a076f40SJoe Perches			$commit_log_long_line = 1;
22502a076f40SJoe Perches		}
22512a076f40SJoe Perches
22520d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
22530d7835fcSJoe Perches		if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) {
2254d311cd44SJoe Perches			my $init_char = $1;
2255d311cd44SJoe Perches			my $orig_commit = lc($2);
22560d7835fcSJoe Perches			my $short = 1;
22570d7835fcSJoe Perches			my $long = 0;
22580d7835fcSJoe Perches			my $case = 1;
22590d7835fcSJoe Perches			my $space = 1;
22600d7835fcSJoe Perches			my $hasdesc = 0;
226119c146a6SJoe Perches			my $hasparens = 0;
22620d7835fcSJoe Perches			my $id = '0123456789ab';
22630d7835fcSJoe Perches			my $orig_desc = "commit description";
22640d7835fcSJoe Perches			my $description = "";
22650d7835fcSJoe Perches
22660d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
22670d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
22680d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
22690d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
22700d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
22710d7835fcSJoe Perches				$orig_desc = $1;
227219c146a6SJoe Perches				$hasparens = 1;
22730d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
22740d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
22750d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
22760d7835fcSJoe Perches				$orig_desc = $1;
227719c146a6SJoe Perches				$hasparens = 1;
2278b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2279b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2280b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2281b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2282b671fde0SJoe Perches				$orig_desc = $1;
2283b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2284b671fde0SJoe Perches				$orig_desc .= " " . $1;
228519c146a6SJoe Perches				$hasparens = 1;
22860d7835fcSJoe Perches			}
22870d7835fcSJoe Perches
22880d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
22890d7835fcSJoe Perches							      $id, $orig_desc);
22900d7835fcSJoe Perches
229119c146a6SJoe Perches			if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) {
2292d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
22930d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
22940d7835fcSJoe Perches			}
2295d311cd44SJoe Perches		}
2296d311cd44SJoe Perches
229713f1937eSJoe Perches# Check for added, moved or deleted files
229813f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
229913f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
230013f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
230113f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
230213f1937eSJoe Perches		      (defined($1) || defined($2))))) {
230313f1937eSJoe Perches			$reported_maintainer_file = 1;
230413f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
230513f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
230613f1937eSJoe Perches		}
230713f1937eSJoe Perches
230800df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
23098905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2310000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2311000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
23126c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2313de7d4f0eSAndy Whitcroft		}
2314de7d4f0eSAndy Whitcroft
23156ecd9674SAndy Whitcroft# Check for absolute kernel paths.
23166ecd9674SAndy Whitcroft		if ($tree) {
23176ecd9674SAndy Whitcroft			while ($line =~ m{(?:^|\s)(/\S*)}g) {
23186ecd9674SAndy Whitcroft				my $file = $1;
23196ecd9674SAndy Whitcroft
23206ecd9674SAndy Whitcroft				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
23216ecd9674SAndy Whitcroft				    check_absolute_file($1, $herecurr)) {
23226ecd9674SAndy Whitcroft					#
23236ecd9674SAndy Whitcroft				} else {
23246ecd9674SAndy Whitcroft					check_absolute_file($file, $herecurr);
23256ecd9674SAndy Whitcroft				}
23266ecd9674SAndy Whitcroft			}
23276ecd9674SAndy Whitcroft		}
23286ecd9674SAndy Whitcroft
2329de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2330de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2331171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2332171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2333171ae1a4SAndy Whitcroft
2334171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2335171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2336171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2337171ae1a4SAndy Whitcroft
233834d99219SJoe Perches			CHK("INVALID_UTF8",
2339000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
234000df344fSAndy Whitcroft		}
23410a920b5bSAndy Whitcroft
234215662b3eSJoe Perches# Check if it's the start of a commit log
234315662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
234415662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
234529ee1b0cSJoe Perches		    !($rawline =~ /^\s+\S/ ||
234629ee1b0cSJoe Perches		      $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {
234715662b3eSJoe Perches			$in_header_lines = 0;
234815662b3eSJoe Perches			$in_commit_log = 1;
234915662b3eSJoe Perches		}
235015662b3eSJoe Perches
2351fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2352fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2353fa64205dSPasi Savanainen		if ($in_header_lines &&
2354fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2355fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2356fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2357fa64205dSPasi Savanainen		}
2358fa64205dSPasi Savanainen
2359fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
236015662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2361fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
236215662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
236315662b3eSJoe Perches		}
236415662b3eSJoe Perches
236566b47b4aSKees Cook# Check for various typo / spelling mistakes
236666d7a382SJoe Perches		if (defined($misspellings) &&
236766d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2368ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
236966b47b4aSKees Cook				my $typo = $1;
237066b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
237166b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
237266b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
237366b47b4aSKees Cook				my $msg_type = \&WARN;
237466b47b4aSKees Cook				$msg_type = \&CHK if ($file);
237566b47b4aSKees Cook				if (&{$msg_type}("TYPO_SPELLING",
237666b47b4aSKees Cook						 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
237766b47b4aSKees Cook				    $fix) {
237866b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
237966b47b4aSKees Cook				}
238066b47b4aSKees Cook			}
238166b47b4aSKees Cook		}
238266b47b4aSKees Cook
238330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
238430670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
238500df344fSAndy Whitcroft
23860a920b5bSAndy Whitcroft#trailing whitespace
23879c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2388c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2389d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2390d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2391d5e616fcSJoe Perches			    $fix) {
2392194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2393d5e616fcSJoe Perches			}
2394c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2395c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
23963705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
23973705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
23983705ce5bSJoe Perches			    $fix) {
2399194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
24003705ce5bSJoe Perches			}
24013705ce5bSJoe Perches
2402d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
24030a920b5bSAndy Whitcroft		}
24045368df20SAndy Whitcroft
24054783f894SJosh Triplett# Check for FSF mailing addresses.
2406109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
24073e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
24083e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
24094783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
24104783f894SJosh Triplett			my $msg_type = \&ERROR;
24114783f894SJosh Triplett			$msg_type = \&CHK if ($file);
24124783f894SJosh Triplett			&{$msg_type}("FSF_MAILING_ADDRESS",
24134783f894SJosh Triplett				     "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
24144783f894SJosh Triplett		}
24154783f894SJosh Triplett
24163354957aSAndi Kleen# check for Kconfig help text having a real description
24179fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
24189fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
24193354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
24208d73e0e7SJoe Perches		    $line =~ /^\+\s*config\s+/) {
24213354957aSAndi Kleen			my $length = 0;
24229fe287d7SAndy Whitcroft			my $cnt = $realcnt;
24239fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
24249fe287d7SAndy Whitcroft			my $f;
2425a1385803SAndy Whitcroft			my $is_start = 0;
24269fe287d7SAndy Whitcroft			my $is_end = 0;
2427a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
24289fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
24299fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
24309fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
24319fe287d7SAndy Whitcroft
24329fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
24338d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
2434a1385803SAndy Whitcroft
24358d73e0e7SJoe Perches				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2436a1385803SAndy Whitcroft					$is_start = 1;
24378d73e0e7SJoe Perches				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2438a1385803SAndy Whitcroft					$length = -1;
2439a1385803SAndy Whitcroft				}
2440a1385803SAndy Whitcroft
24419fe287d7SAndy Whitcroft				$f =~ s/^.//;
24423354957aSAndi Kleen				$f =~ s/#.*//;
24433354957aSAndi Kleen				$f =~ s/^\s+//;
24443354957aSAndi Kleen				next if ($f =~ /^$/);
24459fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
24469fe287d7SAndy Whitcroft					$is_end = 1;
24479fe287d7SAndy Whitcroft					last;
24489fe287d7SAndy Whitcroft				}
24493354957aSAndi Kleen				$length++;
24503354957aSAndi Kleen			}
245156193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
2452000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
245356193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
245456193274SVadim Bendebury			}
2455a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
24563354957aSAndi Kleen		}
24573354957aSAndi Kleen
24581ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
24591ba8dfd1SKees Cook		if ($realfile =~ /Kconfig/ &&
24601ba8dfd1SKees Cook		    $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
24611ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
24621ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
24631ba8dfd1SKees Cook		}
24641ba8dfd1SKees Cook
2465327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
2466327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
2467327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
2468327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
2469327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2470327953e9SChristoph Jaeger		}
2471327953e9SChristoph Jaeger
2472c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2473c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2474c68e5878SArnaud Lacombe			my $flag = $1;
2475c68e5878SArnaud Lacombe			my $replacement = {
2476c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
2477c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
2478c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
2479c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
2480c68e5878SArnaud Lacombe			};
2481c68e5878SArnaud Lacombe
2482c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
2483c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2484c68e5878SArnaud Lacombe		}
2485c68e5878SArnaud Lacombe
2486bff5da43SRob Herring# check for DT compatible documentation
24877dd05b38SFlorian Vaussard		if (defined $root &&
24887dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
24897dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
24907dd05b38SFlorian Vaussard
2491bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2492bff5da43SRob Herring
2493cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
2494cc93319bSFlorian Vaussard			my $vp_file = $dt_path . "vendor-prefixes.txt";
2495cc93319bSFlorian Vaussard
2496bff5da43SRob Herring			foreach my $compat (@compats) {
2497bff5da43SRob Herring				my $compat2 = $compat;
2498185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2499185d566bSRob Herring				my $compat3 = $compat;
2500185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2501185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2502bff5da43SRob Herring				if ( $? >> 8 ) {
2503bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2504bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2505bff5da43SRob Herring				}
2506bff5da43SRob Herring
25074fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
25084fbf32a6SFlorian Vaussard				my $vendor = $1;
2509cc93319bSFlorian Vaussard				`grep -Eq "^$vendor\\b" $vp_file`;
2510bff5da43SRob Herring				if ( $? >> 8 ) {
2511bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2512cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2513bff5da43SRob Herring				}
2514bff5da43SRob Herring			}
2515bff5da43SRob Herring		}
2516bff5da43SRob Herring
25175368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
2518de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);
25195368df20SAndy Whitcroft
25206cd7f386SJoe Perches#line length limit
2521c45dcabdSAndy Whitcroft		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
2522f4c014c0SAndy Whitcroft		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
252329a3c466SJoe Perches		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||
252429a3c466SJoe Perches		      $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
252529a3c466SJoe Perches		      $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&
25266cd7f386SJoe Perches		    $length > $max_line_length)
2527c45dcabdSAndy Whitcroft		{
2528000d1cc1SJoe Perches			WARN("LONG_LINE",
25296cd7f386SJoe Perches			     "line over $max_line_length characters\n" . $herecurr);
25300a920b5bSAndy Whitcroft		}
25310a920b5bSAndy Whitcroft
25328905a67cSAndy Whitcroft# check for adding lines without a newline.
25338905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2534000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
2535000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
25368905a67cSAndy Whitcroft		}
25378905a67cSAndy Whitcroft
253842e41c54SMike Frysinger# Blackfin: use hi/lo macros
253942e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
254042e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
254142e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2542000d1cc1SJoe Perches				ERROR("LO_MACRO",
2543000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
254442e41c54SMike Frysinger			}
254542e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
254642e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2547000d1cc1SJoe Perches				ERROR("HI_MACRO",
2548000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
254942e41c54SMike Frysinger			}
255042e41c54SMike Frysinger		}
255142e41c54SMike Frysinger
2552b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
2553de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
25540a920b5bSAndy Whitcroft
25550a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
25560a920b5bSAndy Whitcroft# more than 8 must use tabs.
2557c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
2558c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
2559c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2560d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
25613705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
25623705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
25633705ce5bSJoe Perches			    $fix) {
2564194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
25653705ce5bSJoe Perches			}
25660a920b5bSAndy Whitcroft		}
25670a920b5bSAndy Whitcroft
256808e44365SAlberto Panizzo# check for space before tabs.
256908e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
257008e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
25713705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
25723705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
25733705ce5bSJoe Perches			    $fix) {
2574194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2575d2207ccbSJoe Perches					   s/(^\+.*) {8,8}\t/$1\t\t/) {}
2576194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2577c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
25783705ce5bSJoe Perches			}
257908e44365SAlberto Panizzo		}
258008e44365SAlberto Panizzo
2581d1fe9c09SJoe Perches# check for && or || at the start of a line
2582d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2583d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
2584d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
2585d1fe9c09SJoe Perches		}
2586d1fe9c09SJoe Perches
2587d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
2588d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
258991cb5195SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
2590d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
2591d1fe9c09SJoe Perches			my $oldindent = $1;
2592d1fe9c09SJoe Perches			my $rest = $2;
2593d1fe9c09SJoe Perches
2594d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
2595d1fe9c09SJoe Perches			if ($pos >= 0) {
2596b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
2597b34a26f3SJoe Perches				my $newindent = $2;
2598d1fe9c09SJoe Perches
2599d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
2600d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
2601d1fe9c09SJoe Perches					" "  x ($pos % 8);
2602d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
2603d1fe9c09SJoe Perches
2604d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
2605d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
26063705ce5bSJoe Perches
26073705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
26083705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
26093705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
2610194f66fcSJoe Perches						$fixed[$fixlinenr] =~
26113705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
26123705ce5bSJoe Perches					}
2613d1fe9c09SJoe Perches				}
2614d1fe9c09SJoe Perches			}
2615d1fe9c09SJoe Perches		}
2616d1fe9c09SJoe Perches
26176ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
26186ab3a970SJoe Perches# avoid checking a few false positives:
26196ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
26206ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
26216ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
26226ab3a970SJoe Perches#   multiline macros that define functions
26236ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
26246ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
26256ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
26263705ce5bSJoe Perches			if (CHK("SPACING",
2627f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
26283705ce5bSJoe Perches			    $fix) {
2629194f66fcSJoe Perches				$fixed[$fixlinenr] =~
2630f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
26313705ce5bSJoe Perches			}
2632aad4f614SJoe Perches		}
2633aad4f614SJoe Perches
263405880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2635fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
263685ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
263785ad978cSJoe Perches		    $realline > 2) {
263805880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
263905880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
264005880600SJoe Perches		}
264105880600SJoe Perches
264205880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2643a605e32eSJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*
2644a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
264561135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
2646a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
2647a605e32eSJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2648a605e32eSJoe Perches			     "networking block comments start with * on subsequent lines\n" . $hereprev);
2649a605e32eSJoe Perches		}
2650a605e32eSJoe Perches
2651a605e32eSJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2652c24f9f19SJoe Perches		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
2653c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
2654c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
2655c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
265605880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
265705880600SJoe Perches			     "networking block comments put the trailing */ on a separate line\n" . $herecurr);
265805880600SJoe Perches		}
265905880600SJoe Perches
26607f619191SJoe Perches# check for missing blank lines after struct/union declarations
26617f619191SJoe Perches# with exceptions for various attributes and macros
26627f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
26637f619191SJoe Perches		    $line =~ /^\+/ &&
26647f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
26657f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
26667f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
26677f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
26687f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
26697f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
26707f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
26717f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
2672d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
2673d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
2674d752fcc8SJoe Perches			    $fix) {
2675f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
2676d752fcc8SJoe Perches			}
26777f619191SJoe Perches		}
26787f619191SJoe Perches
2679365dd4eaSJoe Perches# check for multiple consecutive blank lines
2680365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
2681365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
2682365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
2683d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
2684d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
2685d752fcc8SJoe Perches			    $fix) {
2686f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
2687d752fcc8SJoe Perches			}
2688d752fcc8SJoe Perches
2689365dd4eaSJoe Perches			$last_blank_line = $linenr;
2690365dd4eaSJoe Perches		}
2691365dd4eaSJoe Perches
26923b617e3bSJoe Perches# check for missing blank lines after declarations
26933f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
26943f7bac03SJoe Perches			# actual declarations
26953f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
26965a4e1fd3SJoe Perches			# function pointer declarations
26975a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
26983f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
26993f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
27003f7bac03SJoe Perches			# known declaration macros
27013f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
27023f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
27033f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
27043f7bac03SJoe Perches			# other possible extensions of declaration lines
27053f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
27063f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
27073f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
27083f7bac03SJoe Perches			# looks like a declaration
27093f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
27105a4e1fd3SJoe Perches			# function pointer declarations
27115a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
27123f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
27133f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
27143f7bac03SJoe Perches			# known declaration macros
27153f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
27163f7bac03SJoe Perches			# start of struct or union or enum
27173b617e3bSJoe Perches		      $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
27183f7bac03SJoe Perches			# start or end of block or continuation of declaration
27193f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
27203f7bac03SJoe Perches			# bitfield continuation
27213f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
27223f7bac03SJoe Perches			# other possible extensions of declaration lines
27233f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
27243f7bac03SJoe Perches			# indentation of previous and current line are the same
27253f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
2726d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
2727d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
2728d752fcc8SJoe Perches			    $fix) {
2729f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
2730d752fcc8SJoe Perches			}
27313b617e3bSJoe Perches		}
27323b617e3bSJoe Perches
27335f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
27346b4c5bebSAndy Whitcroft# Exceptions:
27356b4c5bebSAndy Whitcroft#  1) within comments
27366b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
27376b4c5bebSAndy Whitcroft#  3) hanging labels
27383705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
27395f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27403705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
27413705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
27423705ce5bSJoe Perches			    $fix) {
2743194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
27443705ce5bSJoe Perches			}
27455f7ddae6SRaffaele Recalcati		}
27465f7ddae6SRaffaele Recalcati
2747b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
2748b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
2749b9ea10d6SAndy Whitcroft
2750032a4c0fSJoe Perches# check indentation of any line with a bare else
2751840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
2752032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
2753032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
2754032a4c0fSJoe Perches			my $tabs = length($1) + 1;
2755840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
2756840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
2757840080a0SJoe Perches			     defined $lines[$linenr] &&
2758840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
2759032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
2760032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
2761032a4c0fSJoe Perches			}
2762032a4c0fSJoe Perches		}
2763032a4c0fSJoe Perches
2764c00df19aSJoe Perches# check indentation of a line with a break;
2765c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
2766c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
2767c00df19aSJoe Perches			my $tabs = $1;
2768c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
2769c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
2770c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
2771c00df19aSJoe Perches			}
2772c00df19aSJoe Perches		}
2773c00df19aSJoe Perches
27741ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
27751ba8dfd1SKees Cook		if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
27761ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
27771ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
27781ba8dfd1SKees Cook		}
27791ba8dfd1SKees Cook
2780c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
2781cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2782000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
2783000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2784c2fdda0dSAndy Whitcroft		}
278522f2a2efSAndy Whitcroft
278642e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
278742e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
278842e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2789000d1cc1SJoe Perches			ERROR("CSYNC",
2790000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
279142e41c54SMike Frysinger		}
279242e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
279342e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2794000d1cc1SJoe Perches			ERROR("SSYNC",
2795000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
279642e41c54SMike Frysinger		}
279742e41c54SMike Frysinger
279856e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
279956e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
280056e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
280156e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
280256e77d70SJoe Perches		}
280356e77d70SJoe Perches
28049c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
28052b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
28062b474a1aSAndy Whitcroft		    $realline_next);
28073e469cdcSAndy Whitcroft#print "LINE<$line>\n";
28083e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
28091b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
2810170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2811f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
2812171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
2813171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
2814171ae1a4SAndy Whitcroft
28153e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
28163e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
28173e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
28183e469cdcSAndy Whitcroft			# until we hit end of it.
28193e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
28203e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
28213e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
28223e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
28233e469cdcSAndy Whitcroft			}
2824f74bd194SAndy Whitcroft
28252b474a1aSAndy Whitcroft			# Find the real next line.
28262b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
28272b474a1aSAndy Whitcroft			if (defined $realline_next &&
28282b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
28292b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
28302b474a1aSAndy Whitcroft				$realline_next++;
28312b474a1aSAndy Whitcroft			}
28322b474a1aSAndy Whitcroft
2833171ae1a4SAndy Whitcroft			my $s = $stat;
2834171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
2835cf655043SAndy Whitcroft
2836c2fdda0dSAndy Whitcroft			# Ignore goto labels.
2837171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
2838c2fdda0dSAndy Whitcroft
2839c2fdda0dSAndy Whitcroft			# Ignore functions being called
2840171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2841c2fdda0dSAndy Whitcroft
2842463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
2843463f2864SAndy Whitcroft
2844c45dcabdSAndy Whitcroft			# declarations always start with types
2845d2506586SAndy 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) {
2846c45dcabdSAndy Whitcroft				my $type = $1;
2847c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
2848c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
2849c45dcabdSAndy Whitcroft
28506c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
2851a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2852c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
2853c2fdda0dSAndy Whitcroft			}
28548905a67cSAndy Whitcroft
28556c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
285665863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2857c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
28589c0ca6f9SAndy Whitcroft			}
28598905a67cSAndy Whitcroft
28608905a67cSAndy Whitcroft			# Check for any sort of function declaration.
28618905a67cSAndy Whitcroft			# int foo(something bar, other baz);
28628905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
2863171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
28648905a67cSAndy Whitcroft				my ($name_len) = length($1);
28658905a67cSAndy Whitcroft
2866cf655043SAndy Whitcroft				my $ctx = $s;
2867773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
28688905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
2869cf655043SAndy Whitcroft
28708905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
2871c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
28728905a67cSAndy Whitcroft
2873c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
28748905a67cSAndy Whitcroft					}
28758905a67cSAndy Whitcroft				}
28768905a67cSAndy Whitcroft			}
28778905a67cSAndy Whitcroft
28789c0ca6f9SAndy Whitcroft		}
28799c0ca6f9SAndy Whitcroft
288000df344fSAndy Whitcroft#
288100df344fSAndy Whitcroft# Checks which may be anchored in the context.
288200df344fSAndy Whitcroft#
288300df344fSAndy Whitcroft
288400df344fSAndy Whitcroft# Check for switch () and associated case and default
288500df344fSAndy Whitcroft# statements should be at the same indent.
288600df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
288700df344fSAndy Whitcroft			my $err = '';
288800df344fSAndy Whitcroft			my $sep = '';
288900df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
289000df344fSAndy Whitcroft			shift(@ctx);
289100df344fSAndy Whitcroft			for my $ctx (@ctx) {
289200df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
289300df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
289400df344fSAndy Whitcroft							$indent != $cindent) {
289500df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
289600df344fSAndy Whitcroft					$sep = '';
289700df344fSAndy Whitcroft				} else {
289800df344fSAndy Whitcroft					$sep = "[...]\n";
289900df344fSAndy Whitcroft				}
290000df344fSAndy Whitcroft			}
290100df344fSAndy Whitcroft			if ($err ne '') {
2902000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
2903000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
2904de7d4f0eSAndy Whitcroft			}
2905de7d4f0eSAndy Whitcroft		}
2906de7d4f0eSAndy Whitcroft
2907de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
2908de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
29090fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2910773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
2911773647a0SAndy Whitcroft
29129c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
29138eef05ddSJoe Perches
29148eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
29158eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
29168eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
29178eef05ddSJoe Perches			}
29188eef05ddSJoe Perches
2919de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
2920de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
2921de7d4f0eSAndy Whitcroft
2922548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
2923548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
2924de7d4f0eSAndy Whitcroft
2925548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2926548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
2927548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
2928548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2929548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2930773647a0SAndy Whitcroft				$ctx_ln++;
2931773647a0SAndy Whitcroft			}
2932548596d5SAndy Whitcroft
293353210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
293453210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2935773647a0SAndy Whitcroft
2936773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2937000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
2938000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
293901464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
294000df344fSAndy Whitcroft			}
2941773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2942773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
2943773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
2944773647a0SAndy Whitcroft			{
29459c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
29469c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
2947000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
2948000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
294901464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
29509c0ca6f9SAndy Whitcroft				}
29519c0ca6f9SAndy Whitcroft			}
295200df344fSAndy Whitcroft		}
295300df344fSAndy Whitcroft
29544d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
29550fe3dc2bSJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
29563e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
29573e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
29583e469cdcSAndy Whitcroft					if (!defined $stat);
29594d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
29604d001e4dSAndy Whitcroft
29614d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
29624d001e4dSAndy Whitcroft
29634d001e4dSAndy Whitcroft			# Make sure we remove the line prefixes as we have
29644d001e4dSAndy Whitcroft			# none on the first line, and are going to readd them
29654d001e4dSAndy Whitcroft			# where necessary.
29664d001e4dSAndy Whitcroft			$s =~ s/\n./\n/gs;
29674d001e4dSAndy Whitcroft
29684d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
29696f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
29706f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
29714d001e4dSAndy Whitcroft
29724d001e4dSAndy Whitcroft			# We want to check the first line inside the block
29734d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
29744d001e4dSAndy Whitcroft			#  1) any blank line termination
29754d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
29764d001e4dSAndy Whitcroft			#  3) any do (...) {
29774d001e4dSAndy Whitcroft			my $continuation = 0;
29784d001e4dSAndy Whitcroft			my $check = 0;
29794d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
29804d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
29814d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
29824d001e4dSAndy Whitcroft				$continuation = 1;
29834d001e4dSAndy Whitcroft			}
29849bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
29854d001e4dSAndy Whitcroft				$check = 1;
29864d001e4dSAndy Whitcroft				$cond_lines++;
29874d001e4dSAndy Whitcroft			}
29884d001e4dSAndy Whitcroft
29894d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
29904d001e4dSAndy Whitcroft			# preprocessor statement.
29914d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
29924d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
29934d001e4dSAndy Whitcroft				$check = 0;
29944d001e4dSAndy Whitcroft			}
29954d001e4dSAndy Whitcroft
29969bd49efeSAndy Whitcroft			my $cond_ptr = -1;
2997740504c6SAndy Whitcroft			$continuation = 0;
29989bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
29999bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
30004d001e4dSAndy Whitcroft
3001f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3002f16fa28fSAndy Whitcroft				# is not linear.
3003f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3004f16fa28fSAndy Whitcroft					$check = 0;
3005f16fa28fSAndy Whitcroft				}
3006f16fa28fSAndy Whitcroft
30079bd49efeSAndy Whitcroft				# Ignore:
30089bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
30099bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
30109bd49efeSAndy Whitcroft				#  3) labels.
3011740504c6SAndy Whitcroft				if ($continuation ||
3012740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
30139bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
30149bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3015740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
301630dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
30179bd49efeSAndy Whitcroft						$cond_lines++;
30189bd49efeSAndy Whitcroft					}
30194d001e4dSAndy Whitcroft				}
302030dad6ebSAndy Whitcroft			}
30214d001e4dSAndy Whitcroft
30224d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
30234d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
30244d001e4dSAndy Whitcroft
30254d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
30264d001e4dSAndy Whitcroft			# this is not this patch's fault.
30274d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
30284d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
30294d001e4dSAndy Whitcroft				$check = 0;
30304d001e4dSAndy Whitcroft			}
30314d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
30324d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
30334d001e4dSAndy Whitcroft			}
30344d001e4dSAndy Whitcroft
30359bd49efeSAndy 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";
30364d001e4dSAndy Whitcroft
30374d001e4dSAndy Whitcroft			if ($check && (($sindent % 8) != 0 ||
30384d001e4dSAndy Whitcroft			    ($sindent <= $indent && $s ne ''))) {
3039000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3040000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
30414d001e4dSAndy Whitcroft			}
30424d001e4dSAndy Whitcroft		}
30434d001e4dSAndy Whitcroft
30446c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
30456c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
30461f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
30471f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
30486c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3049c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3050c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3051cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3052cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
30531f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3054c2fdda0dSAndy Whitcroft		}
30556c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
30566c72ffaaSAndy Whitcroft
305700df344fSAndy Whitcroft#ignore lines not being added
30583705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
305900df344fSAndy Whitcroft
3060653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
30617429c690SAndy Whitcroft		if ($dbg_type) {
30627429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3063000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3064000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
30657429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3066000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3067000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
30687429c690SAndy Whitcroft			}
3069653d4876SAndy Whitcroft			next;
3070653d4876SAndy Whitcroft		}
3071a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3072a1ef277eSAndy Whitcroft		if ($dbg_attr) {
30739360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3074000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3075000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
30769360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3077000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3078000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3079a1ef277eSAndy Whitcroft			}
3080a1ef277eSAndy Whitcroft			next;
3081a1ef277eSAndy Whitcroft		}
3082653d4876SAndy Whitcroft
3083f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
308499423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
308599423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3086d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3087d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3088f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3089f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3090f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3091d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3092d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3093f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3094d752fcc8SJoe Perches				$fixedline = $line;
3095d752fcc8SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1/;
3096f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3097d752fcc8SJoe Perches			}
3098f0a594c1SAndy Whitcroft		}
3099f0a594c1SAndy Whitcroft
310000df344fSAndy Whitcroft#
310100df344fSAndy Whitcroft# Checks which are anchored on the added line.
310200df344fSAndy Whitcroft#
310300df344fSAndy Whitcroft
3104653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3105c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3106653d4876SAndy Whitcroft			my $path = $1;
3107653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3108000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3109495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3110495e9d84SJoe Perches			}
3111495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3112495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3113495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3114653d4876SAndy Whitcroft			}
3115653d4876SAndy Whitcroft		}
3116653d4876SAndy Whitcroft
311700df344fSAndy Whitcroft# no C99 // comments
311800df344fSAndy Whitcroft		if ($line =~ m{//}) {
31193705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
31203705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
31213705ce5bSJoe Perches			    $fix) {
3122194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
31233705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
31243705ce5bSJoe Perches					my $comment = trim($1);
3125194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
31263705ce5bSJoe Perches				}
31273705ce5bSJoe Perches			}
312800df344fSAndy Whitcroft		}
312900df344fSAndy Whitcroft		# Remove C99 comments.
31300a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
31316c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
31320a920b5bSAndy Whitcroft
31332b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
31342b474a1aSAndy Whitcroft# the whole statement.
31352b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
31362b474a1aSAndy Whitcroft		if (defined $realline_next &&
31372b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
31382b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
31392b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
31402b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
31413cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
31423cbf62dfSAndy Whitcroft			# a prefix:
31433cbf62dfSAndy Whitcroft			#   XXX(foo);
31443cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3145653d4876SAndy Whitcroft			my $name = $1;
314687a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
31473cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
31483cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
31493cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
31503cbf62dfSAndy Whitcroft
31513cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
31522b474a1aSAndy Whitcroft				\n.}\s*$|
315348012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
315448012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
315548012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
31562b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
31572b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
315848012058SAndy Whitcroft			    )/x) {
31592b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
31602b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
31612b474a1aSAndy Whitcroft			} else {
31622b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
31630a920b5bSAndy Whitcroft			}
31640a920b5bSAndy Whitcroft		}
31652b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
31662b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
31672b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
31682b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
31692b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
31702b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
31712b474a1aSAndy Whitcroft		}
31722b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
31732b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3174000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3175000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
31762b474a1aSAndy Whitcroft		}
31770a920b5bSAndy Whitcroft
31785150bda4SJoe Eloff# check for global initialisers.
31795129e87cSJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*(?:0|NULL|false)\s*;/) {
3180d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
3181000d1cc1SJoe Perches				  "do not initialise globals to 0 or NULL\n" .
3182d5e616fcSJoe Perches				      $herecurr) &&
3183d5e616fcSJoe Perches			    $fix) {
31845129e87cSJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*(0|NULL|false)\s*;/$1;/;
3185d5e616fcSJoe Perches			}
3186f0a594c1SAndy Whitcroft		}
31870a920b5bSAndy Whitcroft# check for static initialisers.
3188d5e616fcSJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
3189d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
3190000d1cc1SJoe Perches				  "do not initialise statics to 0 or NULL\n" .
3191d5e616fcSJoe Perches				      $herecurr) &&
3192d5e616fcSJoe Perches			    $fix) {
3193194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
3194d5e616fcSJoe Perches			}
31950a920b5bSAndy Whitcroft		}
31960a920b5bSAndy Whitcroft
31971813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
31981813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
31991813087dSJoe Perches			my $tmp = trim($1);
32001813087dSJoe Perches			WARN("MISORDERED_TYPE",
32011813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
32021813087dSJoe Perches		}
32031813087dSJoe Perches
3204cb710ecaSJoe Perches# check for static const char * arrays.
3205cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3206000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3207000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3208cb710ecaSJoe Perches				$herecurr);
3209cb710ecaSJoe Perches               }
3210cb710ecaSJoe Perches
3211cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3212cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3213000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3214000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3215cb710ecaSJoe Perches				$herecurr);
3216cb710ecaSJoe Perches               }
3217cb710ecaSJoe Perches
3218ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3219ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3220ab7e23f3SJoe Perches			my $found = $1;
3221ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3222ab7e23f3SJoe Perches				WARN("CONST_CONST",
3223ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3224ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3225ab7e23f3SJoe Perches				WARN("CONST_CONST",
3226ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3227ab7e23f3SJoe Perches			}
3228ab7e23f3SJoe Perches		}
3229ab7e23f3SJoe Perches
32309b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
32319b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
32329b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
32339b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
32349b0fa60dSJoe Perches				$herecurr);
32359b0fa60dSJoe Perches               }
32369b0fa60dSJoe Perches
3237b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3238b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3239b598b670SJoe Perches			my $array = $1;
3240b598b670SJoe Perches			if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
3241b598b670SJoe Perches				my $array_div = $1;
3242b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3243b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3244b598b670SJoe Perches				    $fix) {
3245b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3246b598b670SJoe Perches				}
3247b598b670SJoe Perches			}
3248b598b670SJoe Perches		}
3249b598b670SJoe Perches
3250b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
3251b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3252b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
3253b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3254b36190c5SJoe Perches			    $fix) {
3255194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3256b36190c5SJoe Perches			}
3257b36190c5SJoe Perches		}
3258b36190c5SJoe Perches
325992e112fdSJoe Perches# check for uses of DEFINE_PCI_DEVICE_TABLE
326092e112fdSJoe Perches		if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) {
326192e112fdSJoe Perches			if (WARN("DEFINE_PCI_DEVICE_TABLE",
326292e112fdSJoe Perches				 "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) &&
326392e112fdSJoe Perches			    $fix) {
3264194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /;
326592e112fdSJoe Perches			}
326693ed0e2dSJoe Perches		}
326793ed0e2dSJoe Perches
3268653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
3269653d4876SAndy Whitcroft# make sense.
3270653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
32718054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3272c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
32738ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
3274653d4876SAndy Whitcroft		    $line !~ /\b__bitwise(?:__|)\b/) {
3275000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
3276000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
32770a920b5bSAndy Whitcroft		}
32780a920b5bSAndy Whitcroft
32790a920b5bSAndy Whitcroft# * goes on variable not on type
328065863862SAndy Whitcroft		# (char*[ const])
3281bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3282bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
32833705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
3284d8aaf121SAndy Whitcroft
328565863862SAndy Whitcroft			# Should start with a space.
328665863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
328765863862SAndy Whitcroft			# Should not end with a space.
328865863862SAndy Whitcroft			$to =~ s/\s+$//;
328965863862SAndy Whitcroft			# '*'s should not have spaces between.
3290f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
329165863862SAndy Whitcroft			}
3292d8aaf121SAndy Whitcroft
32933705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
329465863862SAndy Whitcroft			if ($from ne $to) {
32953705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
32963705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
32973705ce5bSJoe Perches				    $fix) {
32983705ce5bSJoe Perches					my $sub_from = $ident;
32993705ce5bSJoe Perches					my $sub_to = $ident;
33003705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3301194f66fcSJoe Perches					$fixed[$fixlinenr] =~
33023705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
33033705ce5bSJoe Perches				}
330465863862SAndy Whitcroft			}
3305bfcb2cc7SAndy Whitcroft		}
3306bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3307bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
33083705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3309d8aaf121SAndy Whitcroft
331065863862SAndy Whitcroft			# Should start with a space.
331165863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
331265863862SAndy Whitcroft			# Should not end with a space.
331365863862SAndy Whitcroft			$to =~ s/\s+$//;
331465863862SAndy Whitcroft			# '*'s should not have spaces between.
3315f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
331665863862SAndy Whitcroft			}
331765863862SAndy Whitcroft			# Modifiers should have spaces.
331865863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
331965863862SAndy Whitcroft
33203705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
3321667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
33223705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
33233705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
33243705ce5bSJoe Perches				    $fix) {
33253705ce5bSJoe Perches
33263705ce5bSJoe Perches					my $sub_from = $match;
33273705ce5bSJoe Perches					my $sub_to = $match;
33283705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3329194f66fcSJoe Perches					$fixed[$fixlinenr] =~
33303705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
33313705ce5bSJoe Perches				}
333265863862SAndy Whitcroft			}
33330a920b5bSAndy Whitcroft		}
33340a920b5bSAndy Whitcroft
33350a920b5bSAndy Whitcroft# # no BUG() or BUG_ON()
33360a920b5bSAndy Whitcroft# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {
33370a920b5bSAndy Whitcroft# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
33380a920b5bSAndy Whitcroft# 			print "$herecurr";
33390a920b5bSAndy Whitcroft# 			$clean = 0;
33400a920b5bSAndy Whitcroft# 		}
33410a920b5bSAndy Whitcroft
33428905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3343000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
3344000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
33458905a67cSAndy Whitcroft		}
33468905a67cSAndy Whitcroft
334717441227SJoe Perches# check for uses of printk_ratelimit
334817441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
3349000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
3350000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
335117441227SJoe Perches		}
335217441227SJoe Perches
335300df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
335400df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
335500df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
335625985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
335700df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
3358f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
335900df344fSAndy Whitcroft			my $ok = 0;
336000df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
336100df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
336225985edcSLucas De Marchi				# we have a preceding printk if it ends
336300df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
336400df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
336500df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
336600df344fSAndy Whitcroft						$ok = 1;
336700df344fSAndy Whitcroft					}
336800df344fSAndy Whitcroft					last;
336900df344fSAndy Whitcroft				}
337000df344fSAndy Whitcroft			}
337100df344fSAndy Whitcroft			if ($ok == 0) {
3372000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
3373000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
33740a920b5bSAndy Whitcroft			}
337500df344fSAndy Whitcroft		}
33760a920b5bSAndy Whitcroft
3377243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3378243f3803SJoe Perches			my $orig = $1;
3379243f3803SJoe Perches			my $level = lc($orig);
3380243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
33818f26b837SJoe Perches			my $level2 = $level;
33828f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
3383243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
3384daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
3385243f3803SJoe Perches		}
3386243f3803SJoe Perches
3387243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
3388d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
3389d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3390d5e616fcSJoe Perches			    $fix) {
3391194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3392d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
3393d5e616fcSJoe Perches			}
3394243f3803SJoe Perches		}
3395243f3803SJoe Perches
3396dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3397dc139313SJoe Perches			my $orig = $1;
3398dc139313SJoe Perches			my $level = lc($orig);
3399dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
3400dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
3401dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
3402dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3403dc139313SJoe Perches		}
3404dc139313SJoe Perches
340591c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
340691c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
340791c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
340891c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
340991c9afafSAndy Lutomirski			WARN("ENOSYS",
341091c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
341191c9afafSAndy Lutomirski		}
341291c9afafSAndy Lutomirski
3413653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
3414653d4876SAndy Whitcroft# or if closed on same line
34158d182478SJoe Perches		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
3416c45dcabdSAndy Whitcroft		    !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
34178d182478SJoe Perches			if (ERROR("OPEN_BRACE",
34188d182478SJoe Perches				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
34198d182478SJoe Perches			    $fix) {
34208d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
34218d182478SJoe Perches				my $fixed_line = $rawline;
34228d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
34238d182478SJoe Perches				my $line1 = $1;
34248d182478SJoe Perches				my $line2 = $2;
34258d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
34268d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
34278d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
34288d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
34298d182478SJoe Perches				}
34308d182478SJoe Perches			}
34310a920b5bSAndy Whitcroft		}
3432653d4876SAndy Whitcroft
34338905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
34348905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
34358905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
34368d182478SJoe Perches			if (ERROR("OPEN_BRACE",
34378d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
34388d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
34398d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
34408d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
34418d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
34428d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
34438d182478SJoe Perches				$fixedline = $rawline;
34448d182478SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1\t/;
34458d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
34468d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
34478d182478SJoe Perches				}
34488d182478SJoe Perches			}
34498905a67cSAndy Whitcroft		}
34508905a67cSAndy Whitcroft
34510c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
34523705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
34533705ce5bSJoe Perches			if (WARN("SPACING",
34543705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
34553705ce5bSJoe Perches			    $fix) {
3456194f66fcSJoe Perches				$fixed[$fixlinenr] =~
34573705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
34583705ce5bSJoe Perches			}
34590c73b4ebSAndy Whitcroft		}
34600c73b4ebSAndy Whitcroft
346131070b5dSJoe Perches# Function pointer declarations
346231070b5dSJoe Perches# check spacing between type, funcptr, and args
346331070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
346491f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
346531070b5dSJoe Perches			my $declare = $1;
346631070b5dSJoe Perches			my $pre_pointer_space = $2;
346731070b5dSJoe Perches			my $post_pointer_space = $3;
346831070b5dSJoe Perches			my $funcname = $4;
346931070b5dSJoe Perches			my $post_funcname_space = $5;
347031070b5dSJoe Perches			my $pre_args_space = $6;
347131070b5dSJoe Perches
347291f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
347391f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
347491f72e9cSJoe Perches# don't need a space so don't warn for those.
347591f72e9cSJoe Perches			my $post_declare_space = "";
347691f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
347791f72e9cSJoe Perches				$post_declare_space = $1;
347891f72e9cSJoe Perches				$declare = rtrim($declare);
347991f72e9cSJoe Perches			}
348091f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
348131070b5dSJoe Perches				WARN("SPACING",
348231070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
348391f72e9cSJoe Perches				$post_declare_space = " ";
348431070b5dSJoe Perches			}
348531070b5dSJoe Perches
348631070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
348791f72e9cSJoe Perches# This test is not currently implemented because these declarations are
348891f72e9cSJoe Perches# equivalent to
348991f72e9cSJoe Perches#	int  foo(int bar, ...)
349091f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
349191f72e9cSJoe Perches#
349291f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
349391f72e9cSJoe Perches#				WARN("SPACING",
349491f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
349591f72e9cSJoe Perches#			}
349631070b5dSJoe Perches
349731070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
349831070b5dSJoe Perches			if (defined $pre_pointer_space &&
349931070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
350031070b5dSJoe Perches				WARN("SPACING",
350131070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
350231070b5dSJoe Perches			}
350331070b5dSJoe Perches
350431070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
350531070b5dSJoe Perches			if (defined $post_pointer_space &&
350631070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
350731070b5dSJoe Perches				WARN("SPACING",
350831070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
350931070b5dSJoe Perches			}
351031070b5dSJoe Perches
351131070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
351231070b5dSJoe Perches			if (defined $post_funcname_space &&
351331070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
351431070b5dSJoe Perches				WARN("SPACING",
351531070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
351631070b5dSJoe Perches			}
351731070b5dSJoe Perches
351831070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
351931070b5dSJoe Perches			if (defined $pre_args_space &&
352031070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
352131070b5dSJoe Perches				WARN("SPACING",
352231070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
352331070b5dSJoe Perches			}
352431070b5dSJoe Perches
352531070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
3526194f66fcSJoe Perches				$fixed[$fixlinenr] =~
352791f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
352831070b5dSJoe Perches			}
352931070b5dSJoe Perches		}
353031070b5dSJoe Perches
35318d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
35328d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
3533fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
3534fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
35358d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
35368d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
35378d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
3538fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
3539daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
35403705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
35413705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
35423705ce5bSJoe Perches				    $fix) {
3543194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
35443705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
35453705ce5bSJoe Perches				}
35468d31cfceSAndy Whitcroft			}
35478d31cfceSAndy Whitcroft		}
35488d31cfceSAndy Whitcroft
3549f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
35506c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
3551c2fdda0dSAndy Whitcroft			my $name = $1;
3552773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
3553773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
3554c2fdda0dSAndy Whitcroft
3555c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
3556773647a0SAndy Whitcroft			if ($name =~ /^(?:
3557773647a0SAndy Whitcroft				if|for|while|switch|return|case|
3558773647a0SAndy Whitcroft				volatile|__volatile__|
3559773647a0SAndy Whitcroft				__attribute__|format|__extension__|
3560773647a0SAndy Whitcroft				asm|__asm__)$/x)
3561773647a0SAndy Whitcroft			{
3562c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
3563c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
3564c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
3565c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
3566773647a0SAndy Whitcroft
3567773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
3568c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
3569c2fdda0dSAndy Whitcroft
3570c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
3571c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
3572773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
3573c2fdda0dSAndy Whitcroft
3574c2fdda0dSAndy Whitcroft			} else {
35753705ce5bSJoe Perches				if (WARN("SPACING",
35763705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
35773705ce5bSJoe Perches					     $fix) {
3578194f66fcSJoe Perches					$fixed[$fixlinenr] =~
35793705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
35803705ce5bSJoe Perches				}
3581f0a594c1SAndy Whitcroft			}
35826c72ffaaSAndy Whitcroft		}
35839a4cad4eSEric Nelson
3584653d4876SAndy Whitcroft# Check operator spacing.
35850a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
35863705ce5bSJoe Perches			my $fixed_line = "";
35873705ce5bSJoe Perches			my $line_fixed = 0;
35883705ce5bSJoe Perches
35899c0ca6f9SAndy Whitcroft			my $ops = qr{
35909c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
35919c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
35929c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
35931f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
359484731623SJoe Perches				\?:|\?|:
35959c0ca6f9SAndy Whitcroft			}x;
3596cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
35973705ce5bSJoe Perches
35983705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
35993705ce5bSJoe Perches##			foreach my $el (@elements) {
36003705ce5bSJoe Perches##				print("el: <$el>\n");
36013705ce5bSJoe Perches##			}
36023705ce5bSJoe Perches
36033705ce5bSJoe Perches			my @fix_elements = ();
360400df344fSAndy Whitcroft			my $off = 0;
36056c72ffaaSAndy Whitcroft
36063705ce5bSJoe Perches			foreach my $el (@elements) {
36073705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
36083705ce5bSJoe Perches				$off += length($el);
36093705ce5bSJoe Perches			}
36103705ce5bSJoe Perches
36113705ce5bSJoe Perches			$off = 0;
36123705ce5bSJoe Perches
36136c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
3614b34c648bSJoe Perches			my $last_after = -1;
36156c72ffaaSAndy Whitcroft
36160a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
36173705ce5bSJoe Perches
36183705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
36193705ce5bSJoe Perches
36203705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
36213705ce5bSJoe Perches
36224a0df2efSAndy Whitcroft				$off += length($elements[$n]);
36234a0df2efSAndy Whitcroft
362425985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
3625773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
3626773647a0SAndy Whitcroft				my $cc = '';
3627773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
3628773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
3629773647a0SAndy Whitcroft				}
3630773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
3631773647a0SAndy Whitcroft
36324a0df2efSAndy Whitcroft				my $a = '';
36334a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
36344a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
3635cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
36364a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
36374a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
3638773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
36394a0df2efSAndy Whitcroft
36400a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
36414a0df2efSAndy Whitcroft
36424a0df2efSAndy Whitcroft				my $c = '';
36430a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
36444a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
36454a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
3646cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
36474a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
36484a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
36498b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
36504a0df2efSAndy Whitcroft				} else {
36514a0df2efSAndy Whitcroft					$c = 'E';
36520a920b5bSAndy Whitcroft				}
36530a920b5bSAndy Whitcroft
36544a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
36554a0df2efSAndy Whitcroft
36564a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
36574a0df2efSAndy Whitcroft
36586c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
3659de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
36600a920b5bSAndy Whitcroft
366174048ed8SAndy Whitcroft				# Pull out the value of this operator.
36626c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
36630a920b5bSAndy Whitcroft
36641f65f947SAndy Whitcroft				# Get the full operator variant.
36651f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
36661f65f947SAndy Whitcroft
366713214adfSAndy Whitcroft				# Ignore operators passed as parameters.
366813214adfSAndy Whitcroft				if ($op_type ne 'V' &&
3669d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
367013214adfSAndy Whitcroft
3671cf655043SAndy Whitcroft#				# Ignore comments
3672cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
367313214adfSAndy Whitcroft
3674d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
367513214adfSAndy Whitcroft				} elsif ($op eq ';') {
3676cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
3677cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
36783705ce5bSJoe Perches						if (ERROR("SPACING",
36793705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
3680b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
36813705ce5bSJoe Perches							$line_fixed = 1;
36823705ce5bSJoe Perches						}
3683d8aaf121SAndy Whitcroft					}
3684d8aaf121SAndy Whitcroft
3685d8aaf121SAndy Whitcroft				# // is a comment
3686d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
36870a920b5bSAndy Whitcroft
3688b00e4814SJoe Perches				#   :   when part of a bitfield
3689b00e4814SJoe Perches				} elsif ($opv eq ':B') {
3690b00e4814SJoe Perches					# skip the bitfield test for now
3691b00e4814SJoe Perches
36921f65f947SAndy Whitcroft				# No spaces for:
36931f65f947SAndy Whitcroft				#   ->
3694b00e4814SJoe Perches				} elsif ($op eq '->') {
36954a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
36963705ce5bSJoe Perches						if (ERROR("SPACING",
36973705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
3698b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
36993705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
37003705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
37013705ce5bSJoe Perches							}
3702b34c648bSJoe Perches							$line_fixed = 1;
37033705ce5bSJoe Perches						}
37040a920b5bSAndy Whitcroft					}
37050a920b5bSAndy Whitcroft
37062381097bSJoe Perches				# , must not have a space before and must have a space on the right.
37070a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
37082381097bSJoe Perches					my $rtrim_before = 0;
37092381097bSJoe Perches					my $space_after = 0;
37102381097bSJoe Perches					if ($ctx =~ /Wx./) {
37112381097bSJoe Perches						if (ERROR("SPACING",
37122381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
37132381097bSJoe Perches							$line_fixed = 1;
37142381097bSJoe Perches							$rtrim_before = 1;
37152381097bSJoe Perches						}
37162381097bSJoe Perches					}
3717cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
37183705ce5bSJoe Perches						if (ERROR("SPACING",
37193705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
37203705ce5bSJoe Perches							$line_fixed = 1;
3721b34c648bSJoe Perches							$last_after = $n;
37222381097bSJoe Perches							$space_after = 1;
37232381097bSJoe Perches						}
37242381097bSJoe Perches					}
37252381097bSJoe Perches					if ($rtrim_before || $space_after) {
37262381097bSJoe Perches						if ($rtrim_before) {
37272381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
37282381097bSJoe Perches						} else {
37292381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
37302381097bSJoe Perches						}
37312381097bSJoe Perches						if ($space_after) {
37322381097bSJoe Perches							$good .= " ";
37333705ce5bSJoe Perches						}
37340a920b5bSAndy Whitcroft					}
37350a920b5bSAndy Whitcroft
37369c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
373774048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
37389c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
37399c0ca6f9SAndy Whitcroft
37409c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
37419c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
37429c0ca6f9SAndy Whitcroft				# unary operator, or a cast
37439c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
374474048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
37450d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
3746cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
37473705ce5bSJoe Perches						if (ERROR("SPACING",
37483705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
3749b34c648bSJoe Perches							if ($n != $last_after + 2) {
3750b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
37513705ce5bSJoe Perches								$line_fixed = 1;
37523705ce5bSJoe Perches							}
37530a920b5bSAndy Whitcroft						}
3754b34c648bSJoe Perches					}
3755a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
3756171ae1a4SAndy Whitcroft						# A unary '*' may be const
3757171ae1a4SAndy Whitcroft
3758171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
37593705ce5bSJoe Perches						if (ERROR("SPACING",
37603705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
3761b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
37623705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
37633705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
37643705ce5bSJoe Perches							}
3765b34c648bSJoe Perches							$line_fixed = 1;
37663705ce5bSJoe Perches						}
37670a920b5bSAndy Whitcroft					}
37680a920b5bSAndy Whitcroft
37690a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
37700a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
3771773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
37723705ce5bSJoe Perches						if (ERROR("SPACING",
37733705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
3774b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
37753705ce5bSJoe Perches							$line_fixed = 1;
37763705ce5bSJoe Perches						}
37770a920b5bSAndy Whitcroft					}
3778773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
3779773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
37803705ce5bSJoe Perches						if (ERROR("SPACING",
37813705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
3782b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
37833705ce5bSJoe Perches							$line_fixed = 1;
37843705ce5bSJoe Perches						}
3785653d4876SAndy Whitcroft					}
3786773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
37873705ce5bSJoe Perches						if (ERROR("SPACING",
37883705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
3789b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
37903705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
37913705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
3792773647a0SAndy Whitcroft							}
3793b34c648bSJoe Perches							$line_fixed = 1;
37943705ce5bSJoe Perches						}
37953705ce5bSJoe Perches					}
37960a920b5bSAndy Whitcroft
37970a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
37989c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
37999c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
38009c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
3801c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
3802c2fdda0dSAndy Whitcroft					 $op eq '%')
38030a920b5bSAndy Whitcroft				{
3804d2e025f3SJoe Perches					if ($check) {
3805d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
3806d2e025f3SJoe Perches							if (CHK("SPACING",
3807d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
3808d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
3809d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
3810d2e025f3SJoe Perches								$line_fixed = 1;
3811d2e025f3SJoe Perches							}
3812d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
3813d2e025f3SJoe Perches							if (CHK("SPACING",
3814d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
3815d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
3816d2e025f3SJoe Perches								$line_fixed = 1;
3817d2e025f3SJoe Perches							}
3818d2e025f3SJoe Perches						}
3819d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
38203705ce5bSJoe Perches						if (ERROR("SPACING",
38213705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
3822b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
3823b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
3824b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
3825b34c648bSJoe Perches							}
38263705ce5bSJoe Perches							$line_fixed = 1;
38273705ce5bSJoe Perches						}
38280a920b5bSAndy Whitcroft					}
38290a920b5bSAndy Whitcroft
38301f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
38311f65f947SAndy Whitcroft				# terminating a case value or a label.
38321f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
38331f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
38343705ce5bSJoe Perches						if (ERROR("SPACING",
38353705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
3836b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
38373705ce5bSJoe Perches							$line_fixed = 1;
38383705ce5bSJoe Perches						}
38391f65f947SAndy Whitcroft					}
38401f65f947SAndy Whitcroft
38410a920b5bSAndy Whitcroft				# All the others need spaces both sides.
3842cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
38431f65f947SAndy Whitcroft					my $ok = 0;
38441f65f947SAndy Whitcroft
384522f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
38461f65f947SAndy Whitcroft					if (($op eq '<' &&
38471f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
38481f65f947SAndy Whitcroft					    ($op eq '>' &&
38491f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
38501f65f947SAndy Whitcroft					{
38511f65f947SAndy Whitcroft					    	$ok = 1;
38521f65f947SAndy Whitcroft					}
38531f65f947SAndy Whitcroft
3854e0df7e1fSJoe Perches					# for asm volatile statements
3855e0df7e1fSJoe Perches					# ignore a colon with another
3856e0df7e1fSJoe Perches					# colon immediately before or after
3857e0df7e1fSJoe Perches					if (($op eq ':') &&
3858e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
3859e0df7e1fSJoe Perches						$ok = 1;
3860e0df7e1fSJoe Perches					}
3861e0df7e1fSJoe Perches
386284731623SJoe Perches					# messages are ERROR, but ?: are CHK
38631f65f947SAndy Whitcroft					if ($ok == 0) {
386484731623SJoe Perches						my $msg_type = \&ERROR;
386584731623SJoe Perches						$msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
386684731623SJoe Perches
386784731623SJoe Perches						if (&{$msg_type}("SPACING",
38683705ce5bSJoe Perches								 "spaces required around that '$op' $at\n" . $hereptr)) {
3869b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
3870b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
3871b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
3872b34c648bSJoe Perches							}
38733705ce5bSJoe Perches							$line_fixed = 1;
38743705ce5bSJoe Perches						}
38750a920b5bSAndy Whitcroft					}
387622f2a2efSAndy Whitcroft				}
38774a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
38783705ce5bSJoe Perches
38793705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
38803705ce5bSJoe Perches
38813705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
38820a920b5bSAndy Whitcroft			}
38833705ce5bSJoe Perches
38843705ce5bSJoe Perches			if (($#elements % 2) == 0) {
38853705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
38863705ce5bSJoe Perches			}
38873705ce5bSJoe Perches
3888194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
3889194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
38903705ce5bSJoe Perches			}
38913705ce5bSJoe Perches
38923705ce5bSJoe Perches
38930a920b5bSAndy Whitcroft		}
38940a920b5bSAndy Whitcroft
3895786b6326SJoe Perches# check for whitespace before a non-naked semicolon
3896d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
3897786b6326SJoe Perches			if (WARN("SPACING",
3898786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
3899786b6326SJoe Perches			    $fix) {
3900194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
3901786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
3902786b6326SJoe Perches			}
3903786b6326SJoe Perches		}
3904786b6326SJoe Perches
3905f0a594c1SAndy Whitcroft# check for multiple assignments
3906f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
3907000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
3908000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
3909f0a594c1SAndy Whitcroft		}
3910f0a594c1SAndy Whitcroft
391122f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
391222f2a2efSAndy Whitcroft## # continuation.
391322f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
391422f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
391522f2a2efSAndy Whitcroft##
391622f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
391722f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
391822f2a2efSAndy Whitcroft## 			my $ln = $line;
391922f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
392022f2a2efSAndy Whitcroft## 			}
392122f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
3922000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
3923000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
392422f2a2efSAndy Whitcroft## 			}
392522f2a2efSAndy Whitcroft## 		}
3926f0a594c1SAndy Whitcroft
39270a920b5bSAndy Whitcroft#need space before brace following if, while, etc
392822f2a2efSAndy Whitcroft		if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
392922f2a2efSAndy Whitcroft		    $line =~ /do{/) {
39303705ce5bSJoe Perches			if (ERROR("SPACING",
39313705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
39323705ce5bSJoe Perches			    $fix) {
3933194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/;
39343705ce5bSJoe Perches			}
3935de7d4f0eSAndy Whitcroft		}
3936de7d4f0eSAndy Whitcroft
3937c4a62ef9SJoe Perches## # check for blank lines before declarations
3938c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
3939c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
3940c4a62ef9SJoe Perches##			WARN("SPACING",
3941c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
3942c4a62ef9SJoe Perches##		}
3943c4a62ef9SJoe Perches##
3944c4a62ef9SJoe Perches
3945de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
3946de7d4f0eSAndy Whitcroft# on the line
3947de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
3948d5e616fcSJoe Perches			if (ERROR("SPACING",
3949d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
3950d5e616fcSJoe Perches			    $fix) {
3951194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3952d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
3953d5e616fcSJoe Perches			}
39540a920b5bSAndy Whitcroft		}
39550a920b5bSAndy Whitcroft
395622f2a2efSAndy Whitcroft# check spacing on square brackets
395722f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
39583705ce5bSJoe Perches			if (ERROR("SPACING",
39593705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
39603705ce5bSJoe Perches			    $fix) {
3961194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39623705ce5bSJoe Perches				    s/\[\s+/\[/;
39633705ce5bSJoe Perches			}
396422f2a2efSAndy Whitcroft		}
396522f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
39663705ce5bSJoe Perches			if (ERROR("SPACING",
39673705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
39683705ce5bSJoe Perches			    $fix) {
3969194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39703705ce5bSJoe Perches				    s/\s+\]/\]/;
39713705ce5bSJoe Perches			}
397222f2a2efSAndy Whitcroft		}
397322f2a2efSAndy Whitcroft
3974c45dcabdSAndy Whitcroft# check spacing on parentheses
39759c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
39769c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
39773705ce5bSJoe Perches			if (ERROR("SPACING",
39783705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
39793705ce5bSJoe Perches			    $fix) {
3980194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39813705ce5bSJoe Perches				    s/\(\s+/\(/;
39823705ce5bSJoe Perches			}
398322f2a2efSAndy Whitcroft		}
398413214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
3985c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
3986c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
39873705ce5bSJoe Perches			if (ERROR("SPACING",
39883705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
39893705ce5bSJoe Perches			    $fix) {
3990194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39913705ce5bSJoe Perches				    s/\s+\)/\)/;
39923705ce5bSJoe Perches			}
399322f2a2efSAndy Whitcroft		}
399422f2a2efSAndy Whitcroft
3995e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
3996e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
3997e2826fd0SJoe Perches
3998e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
3999ea4acbb1SJoe Perches			my $var = $1;
4000ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4001ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4002ea4acbb1SJoe Perches			    $fix) {
4003ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4004ea4acbb1SJoe Perches			}
4005ea4acbb1SJoe Perches		}
4006ea4acbb1SJoe Perches
4007ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4008ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4009ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4010ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4011ea4acbb1SJoe Perches			my $var = $2;
4012ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4013ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4014ea4acbb1SJoe Perches			    $fix) {
4015ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4016ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4017ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4018ea4acbb1SJoe Perches			}
4019e2826fd0SJoe Perches		}
4020e2826fd0SJoe Perches
40210a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
40224a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
40230a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
40243705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
40253705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
40263705ce5bSJoe Perches			    $fix) {
4027194f66fcSJoe Perches				$fixed[$fixlinenr] =~
40283705ce5bSJoe Perches				    s/^(.)\s+/$1/;
40293705ce5bSJoe Perches			}
40300a920b5bSAndy Whitcroft		}
40310a920b5bSAndy Whitcroft
40325b9553abSJoe Perches# return is not a function
4033507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4034c45dcabdSAndy Whitcroft			my $spacing = $1;
4035507e5141SJoe Perches			if ($^V && $^V ge 5.10.0 &&
40365b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
40375b9553abSJoe Perches				my $value = $1;
40385b9553abSJoe Perches				$value = deparenthesize($value);
40395b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4040000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4041000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
40425b9553abSJoe Perches				}
4043c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4044000d1cc1SJoe Perches				ERROR("SPACING",
4045000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4046c45dcabdSAndy Whitcroft			}
4047c45dcabdSAndy Whitcroft		}
4048507e5141SJoe Perches
4049b43ae21bSJoe Perches# unnecessary return in a void function
4050b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4051b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4052b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4053b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4054b43ae21bSJoe Perches		    $linenr >= 3 &&
4055b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4056b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
40579819cf25SJoe Perches			WARN("RETURN_VOID",
4058b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
40599819cf25SJoe Perches               }
40609819cf25SJoe Perches
4061189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
4062189248d8SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4063189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4064189248d8SJoe Perches			my $openparens = $1;
4065189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4066189248d8SJoe Perches			my $msg = "";
4067189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4068189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4069189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4070189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4071189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4072189248d8SJoe Perches			}
4073189248d8SJoe Perches		}
4074189248d8SJoe Perches
4075f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4076f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
407753a3c448SAndy Whitcroft			my $name = $1;
407853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4079000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4080f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
408153a3c448SAndy Whitcroft			}
408253a3c448SAndy Whitcroft		}
4083c45dcabdSAndy Whitcroft
40840a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
40854a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
40863705ce5bSJoe Perches			if (ERROR("SPACING",
40873705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
40883705ce5bSJoe Perches			    $fix) {
4089194f66fcSJoe Perches				$fixed[$fixlinenr] =~
40903705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
40913705ce5bSJoe Perches			}
40920a920b5bSAndy Whitcroft		}
40930a920b5bSAndy Whitcroft
4094f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4095f5fe35ddSAndy Whitcroft# statements after the conditional.
4096170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
40973e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
40983e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
40993e469cdcSAndy Whitcroft					if (!defined $stat);
4100170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4101170d3a22SAndy Whitcroft						$remain_next, $off_next);
4102170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4103170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4104170d3a22SAndy Whitcroft
4105170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4106170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4107170d3a22SAndy Whitcroft				# then count those as offsets.
4108170d3a22SAndy Whitcroft				my ($whitespace) =
4109170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4110170d3a22SAndy Whitcroft				my $offset =
4111170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4112170d3a22SAndy Whitcroft
4113170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4114170d3a22SAndy Whitcroft								$offset} = 1;
4115170d3a22SAndy Whitcroft			}
4116170d3a22SAndy Whitcroft		}
4117170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4118c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4119170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4120171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
41218905a67cSAndy Whitcroft
4122b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4123000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4124000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
41258905a67cSAndy Whitcroft			}
41268905a67cSAndy Whitcroft
41278905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
41288905a67cSAndy Whitcroft			# conditional.
4129773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
41308905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
413113214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
413253210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
413353210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4134773647a0SAndy Whitcroft			{
4135bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4136bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4137bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
413842bdf74cSHidetoshi Seto				my $stat_real = '';
4139bb44ad39SAndy Whitcroft
414042bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
414142bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4142bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4143bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4144bb44ad39SAndy Whitcroft				}
4145bb44ad39SAndy Whitcroft
4146000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4147000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
41488905a67cSAndy Whitcroft			}
41498905a67cSAndy Whitcroft		}
41508905a67cSAndy Whitcroft
415113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
415213214adfSAndy Whitcroft		if ($line =~ /
415313214adfSAndy Whitcroft			(?:
415413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
415513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
415613214adfSAndy Whitcroft				(?:\&\&|\|\|)
415713214adfSAndy Whitcroft			|
415813214adfSAndy Whitcroft				(?:\&\&|\|\|)
415913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
416013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
416113214adfSAndy Whitcroft			)/x)
416213214adfSAndy Whitcroft		{
4163000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4164000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
416513214adfSAndy Whitcroft		}
416613214adfSAndy Whitcroft
41678905a67cSAndy Whitcroft# if and else should not have general statements after it
416813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
416913214adfSAndy Whitcroft			my $s = $1;
417013214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
417113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4172000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4173000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
41740a920b5bSAndy Whitcroft			}
417513214adfSAndy Whitcroft		}
417639667782SAndy Whitcroft# if should not continue a brace
417739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4178000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4179048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
418039667782SAndy Whitcroft				$herecurr);
418139667782SAndy Whitcroft		}
4182a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4183a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4184a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
41853fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4186a1080bf8SAndy Whitcroft			\s*return\s+
4187a1080bf8SAndy Whitcroft		    )/xg)
4188a1080bf8SAndy Whitcroft		{
4189000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4190000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4191a1080bf8SAndy Whitcroft		}
41920a920b5bSAndy Whitcroft
41930a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
41940a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
41958b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
41960a920b5bSAndy Whitcroft		    $previndent == $indent) {
41978b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
41988b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
41998b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
42008b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
42018b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
42028b8856f4SJoe Perches				my $fixedline = $prevrawline;
42038b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
42048b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
42058b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
42068b8856f4SJoe Perches				}
42078b8856f4SJoe Perches				$fixedline = $rawline;
42088b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
42098b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
42108b8856f4SJoe Perches			}
42110a920b5bSAndy Whitcroft		}
42120a920b5bSAndy Whitcroft
42138b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4214c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
4215c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4216c2fdda0dSAndy Whitcroft
4217c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
4218c2fdda0dSAndy Whitcroft			# conditional.
4219773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
4220c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
4221c2fdda0dSAndy Whitcroft
4222c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
42238b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
42248b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
42258b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
42268b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
42278b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
42288b8856f4SJoe Perches					my $fixedline = $prevrawline;
42298b8856f4SJoe Perches					my $trailing = $rawline;
42308b8856f4SJoe Perches					$trailing =~ s/^\+//;
42318b8856f4SJoe Perches					$trailing = trim($trailing);
42328b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
42338b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
42348b8856f4SJoe Perches				}
4235c2fdda0dSAndy Whitcroft			}
4236c2fdda0dSAndy Whitcroft		}
4237c2fdda0dSAndy Whitcroft
423895e2c602SJoe Perches#Specific variable tests
4239323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
4240323c1260SJoe Perches			my $var = $1;
424195e2c602SJoe Perches
424295e2c602SJoe Perches#gcc binary extension
424395e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
4244d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
4245d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4246d5e616fcSJoe Perches				    $fix) {
4247d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
4248194f66fcSJoe Perches					$fixed[$fixlinenr] =~
4249d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
4250d5e616fcSJoe Perches				}
425195e2c602SJoe Perches			}
425295e2c602SJoe Perches
425395e2c602SJoe Perches#CamelCase
4254807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
4255be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
425622735ce8SJoe Perches#Ignore Page<foo> variants
4257807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
425822735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4259f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4260f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
4261f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
42627e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
42637e781f67SJoe Perches					my $word = $1;
42647e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4265d8b07710SJoe Perches					if ($check) {
4266d8b07710SJoe Perches						seed_camelcase_includes();
4267d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
4268d8b07710SJoe Perches							seed_camelcase_file($realfile);
4269d8b07710SJoe Perches							$camelcase_file_seeded = 1;
4270d8b07710SJoe Perches						}
4271d8b07710SJoe Perches					}
42727e781f67SJoe Perches					if (!defined $camelcase{$word}) {
42737e781f67SJoe Perches						$camelcase{$word} = 1;
4274be79794bSJoe Perches						CHK("CAMELCASE",
42757e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
42767e781f67SJoe Perches					}
4277323c1260SJoe Perches				}
4278323c1260SJoe Perches			}
42793445686aSJoe Perches		}
42800a920b5bSAndy Whitcroft
42810a920b5bSAndy Whitcroft#no spaces allowed after \ in define
4282d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
4283d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4284d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4285d5e616fcSJoe Perches			    $fix) {
4286194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
4287d5e616fcSJoe Perches			}
42880a920b5bSAndy Whitcroft		}
42890a920b5bSAndy Whitcroft
42900e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
42910e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
4292c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4293e09dec48SAndy Whitcroft			my $file = "$1.h";
4294e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
4295e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
4296e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
42977840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
4298c45dcabdSAndy Whitcroft			{
42990e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
43000e212e0aSFabian Frederick				if ($asminclude > 0) {
4301e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
4302000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
4303000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4304e09dec48SAndy Whitcroft					} else {
4305000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
4306000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4307e09dec48SAndy Whitcroft					}
43080a920b5bSAndy Whitcroft				}
43090a920b5bSAndy Whitcroft			}
43100e212e0aSFabian Frederick		}
43110a920b5bSAndy Whitcroft
4312653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
4313653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
4314cf655043SAndy Whitcroft# in a known good container
4315b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
4316b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4317d8aaf121SAndy Whitcroft			my $ln = $linenr;
4318d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
4319c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
4320c45dcabdSAndy Whitcroft			my $ctx = '';
432108a2843eSJoe Perches			my $has_flow_statement = 0;
432208a2843eSJoe Perches			my $has_arg_concat = 0;
4323c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
4324f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4325f74bd194SAndy Whitcroft			$ctx = $dstat;
4326c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4327a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4328c45dcabdSAndy Whitcroft
432908a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
433008a2843eSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/);
433108a2843eSJoe Perches
4332f74bd194SAndy Whitcroft			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
4333292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
4334c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
4335c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
4336c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
4337c45dcabdSAndy Whitcroft
4338c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
4339bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4340bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
4341c81769fdSAndy Whitcroft			       $dstat =~ s/\[[^\[\]]*\]/1/)
4342bf30d6edSAndy Whitcroft			{
4343c45dcabdSAndy Whitcroft			}
4344c45dcabdSAndy Whitcroft
4345e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
4346e45bab8eSAndy Whitcroft			while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
4347e45bab8eSAndy Whitcroft			       $dstat =~ s/$Ident\s*("X*")/$1/)
4348e45bab8eSAndy Whitcroft			{
4349e45bab8eSAndy Whitcroft			}
4350e45bab8eSAndy Whitcroft
4351c45dcabdSAndy Whitcroft			my $exceptions = qr{
4352c45dcabdSAndy Whitcroft				$Declare|
4353c45dcabdSAndy Whitcroft				module_param_named|
4354a0a0a7a9SKees Cook				MODULE_PARM_DESC|
4355c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
4356c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
4357383099fdSAndy Whitcroft				__typeof__\(|
435822fd2d3eSStefani Seibold				union|
435922fd2d3eSStefani Seibold				struct|
4360ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
4361ea71a0a0SAndy Whitcroft				^\"|\"$
4362c45dcabdSAndy Whitcroft			}x;
43635eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4364f74bd194SAndy Whitcroft			if ($dstat ne '' &&
4365f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
4366f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
43673cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4368356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
4369f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
4370f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
4371e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
437272f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
4373f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
4374f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
4375f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
4376f95a7e6aSJoe Perches			    $dstat !~ /^\({/ &&						# ({...
4377f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4378c45dcabdSAndy Whitcroft			{
4379f74bd194SAndy Whitcroft				$ctx =~ s/\n*$//;
4380f74bd194SAndy Whitcroft				my $herectx = $here . "\n";
4381f74bd194SAndy Whitcroft				my $cnt = statement_rawlines($ctx);
4382f74bd194SAndy Whitcroft
4383f74bd194SAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
4384f74bd194SAndy Whitcroft					$herectx .= raw_line($linenr, $n) . "\n";
4385c45dcabdSAndy Whitcroft				}
4386c45dcabdSAndy Whitcroft
4387f74bd194SAndy Whitcroft				if ($dstat =~ /;/) {
4388f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4389f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4390f74bd194SAndy Whitcroft				} else {
4391000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
4392388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4393d8aaf121SAndy Whitcroft				}
43940a920b5bSAndy Whitcroft			}
43955023d347SJoe Perches
439608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
439708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
439808a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
439908a2843eSJoe Perches				my $herectx = $here . "\n";
440008a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
440108a2843eSJoe Perches
440208a2843eSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
440308a2843eSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
440408a2843eSJoe Perches				}
440508a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
440608a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
440708a2843eSJoe Perches			}
440808a2843eSJoe Perches
4409481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
44105023d347SJoe Perches
44115023d347SJoe Perches		} else {
44125023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
4413481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
4414481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
44155023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
44165023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
44175023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
44185023d347SJoe Perches			}
4419653d4876SAndy Whitcroft		}
44200a920b5bSAndy Whitcroft
4421b13edf7fSJoe Perches# do {} while (0) macro tests:
4422b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
4423b13edf7fSJoe Perches# macro should not end with a semicolon
4424b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4425b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
4426b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
4427b13edf7fSJoe Perches			my $ln = $linenr;
4428b13edf7fSJoe Perches			my $cnt = $realcnt;
4429b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
4430b13edf7fSJoe Perches			my $ctx = '';
4431b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
4432b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
4433b13edf7fSJoe Perches			$ctx = $dstat;
4434b13edf7fSJoe Perches
4435b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
44361b36b201SJoe Perches			$dstat =~ s/$;/ /g;
4437b13edf7fSJoe Perches
4438b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
4439b13edf7fSJoe Perches				my $stmts = $2;
4440b13edf7fSJoe Perches				my $semis = $3;
4441b13edf7fSJoe Perches
4442b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
4443b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
4444b13edf7fSJoe Perches				my $herectx = $here . "\n";
4445b13edf7fSJoe Perches
4446b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4447b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4448b13edf7fSJoe Perches				}
4449b13edf7fSJoe Perches
4450ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
4451ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
4452b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
4453b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
4454b13edf7fSJoe Perches				}
4455b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
4456b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
4457b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
4458b13edf7fSJoe Perches				}
4459f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
4460f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
4461f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
4462f5ef95b1SJoe Perches				my $herectx = $here . "\n";
4463f5ef95b1SJoe Perches
4464f5ef95b1SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4465f5ef95b1SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4466f5ef95b1SJoe Perches				}
4467f5ef95b1SJoe Perches
4468f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
4469f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
4470b13edf7fSJoe Perches			}
4471b13edf7fSJoe Perches		}
4472b13edf7fSJoe Perches
4473080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
4474080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
4475080ba929SMike Frysinger#	.
4476080ba929SMike Frysinger#	ALIGN(...)
4477080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
4478080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
4479000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
4480000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
4481080ba929SMike Frysinger		}
4482080ba929SMike Frysinger
4483f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
448413214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
448513214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
4486cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
448713214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
4488cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
4489cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
4490aad4f614SJoe Perches				my @allowed = ();
4491aad4f614SJoe Perches				my $allow = 0;
449213214adfSAndy Whitcroft				my $seen = 0;
4493773647a0SAndy Whitcroft				my $herectx = $here . "\n";
4494cf655043SAndy Whitcroft				my $ln = $linenr - 1;
449513214adfSAndy Whitcroft				for my $chunk (@chunks) {
449613214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
449713214adfSAndy Whitcroft
4498773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
4499773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
4500773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
4501773647a0SAndy Whitcroft
4502aad4f614SJoe Perches					$allowed[$allow] = 0;
4503773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
4504773647a0SAndy Whitcroft
4505773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
4506773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
4507773647a0SAndy Whitcroft
4508773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
4509cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
4510cf655043SAndy Whitcroft
4511773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
451213214adfSAndy Whitcroft
451313214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
451413214adfSAndy Whitcroft
4515aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
4516cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
4517cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
4518aad4f614SJoe Perches						$allowed[$allow] = 1;
451913214adfSAndy Whitcroft					}
452013214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
4521cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
4522aad4f614SJoe Perches						$allowed[$allow] = 1;
452313214adfSAndy Whitcroft					}
4524cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
4525cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
4526aad4f614SJoe Perches						$allowed[$allow] = 1;
452713214adfSAndy Whitcroft					}
4528aad4f614SJoe Perches					$allow++;
452913214adfSAndy Whitcroft				}
4530aad4f614SJoe Perches				if ($seen) {
4531aad4f614SJoe Perches					my $sum_allowed = 0;
4532aad4f614SJoe Perches					foreach (@allowed) {
4533aad4f614SJoe Perches						$sum_allowed += $_;
4534aad4f614SJoe Perches					}
4535aad4f614SJoe Perches					if ($sum_allowed == 0) {
4536000d1cc1SJoe Perches						WARN("BRACES",
4537000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
4538aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
4539aad4f614SJoe Perches						 $seen != $allow) {
4540aad4f614SJoe Perches						CHK("BRACES",
4541aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
4542aad4f614SJoe Perches					}
454313214adfSAndy Whitcroft				}
454413214adfSAndy Whitcroft			}
454513214adfSAndy Whitcroft		}
4546773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
454713214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
4548cf655043SAndy Whitcroft			my $allowed = 0;
4549f0a594c1SAndy Whitcroft
4550cf655043SAndy Whitcroft			# Check the pre-context.
4551cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
4552cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
4553cf655043SAndy Whitcroft				$allowed = 1;
4554f0a594c1SAndy Whitcroft			}
4555773647a0SAndy Whitcroft
4556773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
4557773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
4558773647a0SAndy Whitcroft
4559cf655043SAndy Whitcroft			# Check the condition.
4560cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
4561773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
4562cf655043SAndy Whitcroft			if (defined $cond) {
4563773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
4564cf655043SAndy Whitcroft			}
4565cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
4566cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
4567cf655043SAndy Whitcroft				$allowed = 1;
4568cf655043SAndy Whitcroft			}
4569cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
4570cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
4571cf655043SAndy Whitcroft				$allowed = 1;
4572cf655043SAndy Whitcroft			}
4573cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
4574cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
4575cf655043SAndy Whitcroft				$allowed = 1;
4576cf655043SAndy Whitcroft			}
4577cf655043SAndy Whitcroft			# Check the post-context.
4578cf655043SAndy Whitcroft			if (defined $chunks[1]) {
4579cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
4580cf655043SAndy Whitcroft				if (defined $cond) {
4581773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
4582cf655043SAndy Whitcroft				}
4583cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
4584cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
4585cf655043SAndy Whitcroft					$allowed = 1;
4586cf655043SAndy Whitcroft				}
4587cf655043SAndy Whitcroft			}
4588cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
458969932487SJustin P. Mattock				my $herectx = $here . "\n";
4590f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
4591cf655043SAndy Whitcroft
4592f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
459369932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
4594cf655043SAndy Whitcroft				}
4595cf655043SAndy Whitcroft
4596000d1cc1SJoe Perches				WARN("BRACES",
4597000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
4598f0a594c1SAndy Whitcroft			}
4599f0a594c1SAndy Whitcroft		}
4600f0a594c1SAndy Whitcroft
46010979ae66SJoe Perches# check for unnecessary blank lines around braces
460277b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
4603f8e58219SJoe Perches			if (CHK("BRACES",
4604f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
4605f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
4606f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4607f8e58219SJoe Perches			}
46080979ae66SJoe Perches		}
460977b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
4610f8e58219SJoe Perches			if (CHK("BRACES",
4611f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
4612f8e58219SJoe Perches			    $fix) {
4613f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4614f8e58219SJoe Perches			}
46150979ae66SJoe Perches		}
46160979ae66SJoe Perches
46174a0df2efSAndy Whitcroft# no volatiles please
46186c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
46196c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
4620000d1cc1SJoe Perches			WARN("VOLATILE",
4621000d1cc1SJoe Perches			     "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
46224a0df2efSAndy Whitcroft		}
46234a0df2efSAndy Whitcroft
46245e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
46255e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
46265e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
46275e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
46285e4f6ba5SJoe Perches		if ($line =~ /^\+\s*"[X\t]*"/ &&
46295e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
46305e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
46315e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
46325e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
46335e4f6ba5SJoe Perches				     $fix &&
46345e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
46355e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
46365e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
46375e4f6ba5SJoe Perches				my $comma_close = "";
46385e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
46395e4f6ba5SJoe Perches					$comma_close = $1;
46405e4f6ba5SJoe Perches				}
46415e4f6ba5SJoe Perches
46425e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46435e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46445e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
46455e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
46465e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
46475e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
46485e4f6ba5SJoe Perches				$fixedline = $rawline;
46495e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
46505e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
46515e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46525e4f6ba5SJoe Perches				}
46535e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
46545e4f6ba5SJoe Perches			}
46555e4f6ba5SJoe Perches		}
46565e4f6ba5SJoe Perches
46575e4f6ba5SJoe Perches# check for missing a space in a string concatenation
46585e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
46595e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
46605e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
46615e4f6ba5SJoe Perches		}
46625e4f6ba5SJoe Perches
46635e4f6ba5SJoe Perches# check for spaces before a quoted newline
46645e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
46655e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
46665e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
46675e4f6ba5SJoe Perches			    $fix) {
46685e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
46695e4f6ba5SJoe Perches			}
46705e4f6ba5SJoe Perches
46715e4f6ba5SJoe Perches		}
46725e4f6ba5SJoe Perches
4673f17dba4fSJoe Perches# concatenated string without spaces between elements
4674f17dba4fSJoe Perches		if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {
4675f17dba4fSJoe Perches			CHK("CONCATENATED_STRING",
4676f17dba4fSJoe Perches			    "Concatenated strings should use spaces between elements\n" . $herecurr);
4677f17dba4fSJoe Perches		}
4678f17dba4fSJoe Perches
467990ad30e5SJoe Perches# uncoalesced string fragments
468090ad30e5SJoe Perches		if ($line =~ /"X*"\s*"/) {
468190ad30e5SJoe Perches			WARN("STRING_FRAGMENTS",
468290ad30e5SJoe Perches			     "Consecutive strings are generally better as a single string\n" . $herecurr);
468390ad30e5SJoe Perches		}
468490ad30e5SJoe Perches
46855e4f6ba5SJoe Perches# check for %L{u,d,i} in strings
46865e4f6ba5SJoe Perches		my $string;
46875e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
46885e4f6ba5SJoe Perches			$string = substr($rawline, $-[1], $+[1] - $-[1]);
46895e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
46905e4f6ba5SJoe Perches			if ($string =~ /(?<!%)%L[udi]/) {
46915e4f6ba5SJoe Perches				WARN("PRINTF_L",
46925e4f6ba5SJoe Perches				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
46935e4f6ba5SJoe Perches				last;
46945e4f6ba5SJoe Perches			}
46955e4f6ba5SJoe Perches		}
46965e4f6ba5SJoe Perches
46975e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
46985e4f6ba5SJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
46995e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
47005e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
47015e4f6ba5SJoe Perches		}
47025e4f6ba5SJoe Perches
470300df344fSAndy Whitcroft# warn about #if 0
4704c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
4705000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
4706000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
4707de7d4f0eSAndy Whitcroft				$herecurr);
47084a0df2efSAndy Whitcroft		}
47094a0df2efSAndy Whitcroft
471003df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
471103df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
471203df4b51SAndy Whitcroft			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
471303df4b51SAndy Whitcroft			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
471403df4b51SAndy Whitcroft				WARN('NEEDLESS_IF',
471515160f90SFabio Estevam				     "$1(NULL) is safe and this check is probably not required\n" . $hereprev);
47164c432a8fSGreg Kroah-Hartman			}
47174c432a8fSGreg Kroah-Hartman		}
4718f0a594c1SAndy Whitcroft
4719ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
4720ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
4721ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
4722ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
4723ebfdc409SJoe Perches		    $linenr > 3) {
4724ebfdc409SJoe Perches			my $testval = $2;
4725ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
4726ebfdc409SJoe Perches
4727ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
4728ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
4729ebfdc409SJoe Perches
4730ebfdc409SJoe Perches			if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) {
4731ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
4732ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
4733ebfdc409SJoe Perches			}
4734ebfdc409SJoe Perches		}
4735ebfdc409SJoe Perches
4736f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
4737dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
4738f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
4739f78d98f6SJoe Perches			my $level = $1;
4740f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
4741f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
4742f78d98f6SJoe Perches			    $fix) {
4743f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
4744f78d98f6SJoe Perches			}
4745f78d98f6SJoe Perches		}
4746f78d98f6SJoe Perches
4747abb08a53SJoe Perches# check for mask then right shift without a parentheses
4748abb08a53SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4749abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
4750abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
4751abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
4752abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
4753abb08a53SJoe Perches		}
4754abb08a53SJoe Perches
4755b75ac618SJoe Perches# check for pointer comparisons to NULL
4756b75ac618SJoe Perches		if ($^V && $^V ge 5.10.0) {
4757b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
4758b75ac618SJoe Perches				my $val = $1;
4759b75ac618SJoe Perches				my $equal = "!";
4760b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
4761b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
4762b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
4763b75ac618SJoe Perches					    $fix) {
4764b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
4765b75ac618SJoe Perches				}
4766b75ac618SJoe Perches			}
4767b75ac618SJoe Perches		}
4768b75ac618SJoe Perches
47698716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
47708716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
47718716de38SJoe Perches			my $attr = $1;
47728716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
47738716de38SJoe Perches				my $ptr = $1;
47748716de38SJoe Perches				my $var = $2;
47758716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
47768716de38SJoe Perches				      ERROR("MISPLACED_INIT",
47778716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
47788716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
47798716de38SJoe Perches				      WARN("MISPLACED_INIT",
47808716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
47818716de38SJoe Perches				    $fix) {
4782194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
47838716de38SJoe Perches				}
47848716de38SJoe Perches			}
47858716de38SJoe Perches		}
47868716de38SJoe Perches
4787e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
4788e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
4789e970b884SJoe Perches			my $attr = $1;
4790e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
4791e970b884SJoe Perches			my $attr_prefix = $1;
4792e970b884SJoe Perches			my $attr_type = $2;
4793e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
4794e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
4795e970b884SJoe Perches			    $fix) {
4796194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4797e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
4798e970b884SJoe Perches			}
4799e970b884SJoe Perches		}
4800e970b884SJoe Perches
4801e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
4802e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
4803e970b884SJoe Perches			my $attr = $1;
4804e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
4805e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
4806e970b884SJoe Perches			    $fix) {
4807194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
4808e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
4809e970b884SJoe Perches				$lead = rtrim($1);
4810e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
4811e970b884SJoe Perches				$lead = "${lead}const ";
4812194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
4813e970b884SJoe Perches			}
4814e970b884SJoe Perches		}
4815e970b884SJoe Perches
4816c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
4817c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
4818c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
4819c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
4820c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
4821c17893c7SJoe Perches			    $fix) {
4822c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
4823c17893c7SJoe Perches			}
4824c17893c7SJoe Perches		}
4825c17893c7SJoe Perches
4826fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
4827fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
4828fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
4829fbdb8138SJoe Perches			my $constant_func = $1;
4830fbdb8138SJoe Perches			my $func = $constant_func;
4831fbdb8138SJoe Perches			$func =~ s/^__constant_//;
4832fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
4833fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
4834fbdb8138SJoe Perches			    $fix) {
4835194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
4836fbdb8138SJoe Perches			}
4837fbdb8138SJoe Perches		}
4838fbdb8138SJoe Perches
48391a15a250SPatrick Pannuto# prefer usleep_range over udelay
484037581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
484143c1d77cSJoe Perches			my $delay = $1;
48421a15a250SPatrick Pannuto			# ignore udelay's < 10, however
484343c1d77cSJoe Perches			if (! ($delay < 10) ) {
4844000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
484543c1d77cSJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
484643c1d77cSJoe Perches			}
484743c1d77cSJoe Perches			if ($delay > 2000) {
484843c1d77cSJoe Perches				WARN("LONG_UDELAY",
484943c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
48501a15a250SPatrick Pannuto			}
48511a15a250SPatrick Pannuto		}
48521a15a250SPatrick Pannuto
485309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
485409ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
485509ef8725SPatrick Pannuto			if ($1 < 20) {
4856000d1cc1SJoe Perches				WARN("MSLEEP",
485743c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
485809ef8725SPatrick Pannuto			}
485909ef8725SPatrick Pannuto		}
486009ef8725SPatrick Pannuto
486136ec1939SJoe Perches# check for comparisons of jiffies
486236ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
486336ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
486436ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
486536ec1939SJoe Perches		}
486636ec1939SJoe Perches
48679d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
48689d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
48699d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
48709d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
48719d7a34a5SJoe Perches		}
48729d7a34a5SJoe Perches
487300df344fSAndy Whitcroft# warn about #ifdefs in C files
4874c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
487500df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
487600df344fSAndy Whitcroft#			print "$herecurr";
487700df344fSAndy Whitcroft#			$clean = 0;
487800df344fSAndy Whitcroft#		}
487900df344fSAndy Whitcroft
488022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
4881c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
48823705ce5bSJoe Perches			if (ERROR("SPACING",
48833705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
48843705ce5bSJoe Perches			    $fix) {
4885194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48863705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
48873705ce5bSJoe Perches			}
48883705ce5bSJoe Perches
488922f2a2efSAndy Whitcroft		}
489022f2a2efSAndy Whitcroft
48914a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
4892171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
4893171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
48944a0df2efSAndy Whitcroft			my $which = $1;
48954a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
4896000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
4897000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
48984a0df2efSAndy Whitcroft			}
48994a0df2efSAndy Whitcroft		}
49004a0df2efSAndy Whitcroft# check for memory barriers without a comment.
49014a0df2efSAndy Whitcroft		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
49024a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
4903c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
4904000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
49054a0df2efSAndy Whitcroft			}
49064a0df2efSAndy Whitcroft		}
4907cb426e99SJoe Perches# check for waitqueue_active without a comment.
4908cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
4909cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
4910cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
4911cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
4912cb426e99SJoe Perches			}
4913cb426e99SJoe Perches		}
49144a0df2efSAndy Whitcroft# check of hardware specific defines
4915c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
4916000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
4917000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
49180a920b5bSAndy Whitcroft		}
4919653d4876SAndy Whitcroft
4920d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
4921d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
4922000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
4923000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
4924d4977c78STobias Klauser		}
4925d4977c78STobias Klauser
4926de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
4927de7d4f0eSAndy Whitcroft# storage class and type.
49289c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
49299c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
4930000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
4931000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
4932de7d4f0eSAndy Whitcroft		}
4933de7d4f0eSAndy Whitcroft
49348905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
49352b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
49362b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
4937d5e616fcSJoe Perches			if (WARN("INLINE",
4938d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
4939d5e616fcSJoe Perches			    $fix) {
4940194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
4941d5e616fcSJoe Perches
4942d5e616fcSJoe Perches			}
49438905a67cSAndy Whitcroft		}
49448905a67cSAndy Whitcroft
49453d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
49462b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
49472b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
4948000d1cc1SJoe Perches			WARN("PREFER_PACKED",
4949000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
49503d130fd0SJoe Perches		}
49513d130fd0SJoe Perches
495239b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
49532b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
49542b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
4955000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
4956000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
495739b7e287SJoe Perches		}
495839b7e287SJoe Perches
49595f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
49602b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
49612b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
4962d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
4963d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
4964d5e616fcSJoe Perches			    $fix) {
4965194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
4966d5e616fcSJoe Perches
4967d5e616fcSJoe Perches			}
49685f14d3bdSJoe Perches		}
49695f14d3bdSJoe Perches
49706061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
49712b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
49722b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
4973d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
4974d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
4975d5e616fcSJoe Perches			    $fix) {
4976194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
4977d5e616fcSJoe Perches			}
49786061d949SJoe Perches		}
49796061d949SJoe Perches
4980619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
4981619a908aSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4982619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
4983619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
4984619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
4985619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
4986619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
4987619a908aSJoe Perches		}
4988619a908aSJoe Perches
4989e6176fa4SJoe Perches# check for c99 types like uint8_t used outside of uapi/
4990e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
4991e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
4992e6176fa4SJoe Perches			my $type = $1;
4993e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
4994e6176fa4SJoe Perches				$type = $1;
4995e6176fa4SJoe Perches				my $kernel_type = 'u';
4996e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
4997e6176fa4SJoe Perches				$type =~ /(\d+)/;
4998e6176fa4SJoe Perches				$kernel_type .= $1;
4999e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5000e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5001e6176fa4SJoe Perches				    $fix) {
5002e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5003e6176fa4SJoe Perches				}
5004e6176fa4SJoe Perches			}
5005e6176fa4SJoe Perches		}
5006e6176fa4SJoe Perches
50078f53a9b8SJoe Perches# check for sizeof(&)
50088f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5009000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5010000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
50118f53a9b8SJoe Perches		}
50128f53a9b8SJoe Perches
501366c80b60SJoe Perches# check for sizeof without parenthesis
501466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5015d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5016d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5017d5e616fcSJoe Perches			    $fix) {
5018194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5019d5e616fcSJoe Perches			}
502066c80b60SJoe Perches		}
502166c80b60SJoe Perches
502288982feaSJoe Perches# check for struct spinlock declarations
502388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
502488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
502588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
502688982feaSJoe Perches		}
502788982feaSJoe Perches
5028a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
502906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5030a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5031caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5032caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5033d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5034d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5035d5e616fcSJoe Perches				    $fix) {
5036194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5037d5e616fcSJoe Perches				}
5038a6962d72SJoe Perches			}
5039a6962d72SJoe Perches		}
5040a6962d72SJoe Perches
5041554e165cSAndy Whitcroft# Check for misused memsets
5042d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5043d1fe9c09SJoe Perches		    defined $stat &&
5044d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
5045554e165cSAndy Whitcroft
5046d7c76ba7SJoe Perches			my $ms_addr = $2;
5047d1fe9c09SJoe Perches			my $ms_val = $7;
5048d1fe9c09SJoe Perches			my $ms_size = $12;
5049d7c76ba7SJoe Perches
5050554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
5051554e165cSAndy Whitcroft				ERROR("MEMSET",
5052d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5053554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
5054554e165cSAndy Whitcroft				WARN("MEMSET",
5055d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5056d7c76ba7SJoe Perches			}
5057d7c76ba7SJoe Perches		}
5058d7c76ba7SJoe Perches
505998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
506098a9bba5SJoe Perches		if ($^V && $^V ge 5.10.0 &&
506198a9bba5SJoe Perches		    $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) {
506298a9bba5SJoe Perches			if (WARN("PREFER_ETHER_ADDR_COPY",
506398a9bba5SJoe Perches				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) &&
506498a9bba5SJoe Perches			    $fix) {
5065194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
506698a9bba5SJoe Perches			}
506798a9bba5SJoe Perches		}
506898a9bba5SJoe Perches
5069d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
5070d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5071d1fe9c09SJoe Perches		    defined $stat &&
5072d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5073d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
5074d7c76ba7SJoe Perches				my $call = $1;
5075d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
5076d7c76ba7SJoe Perches				my $arg1 = $3;
5077d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
5078d1fe9c09SJoe Perches				my $arg2 = $8;
5079d7c76ba7SJoe Perches				my $cast;
5080d7c76ba7SJoe Perches
5081d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5082d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
5083d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
5084d7c76ba7SJoe Perches					$cast = $cast1;
5085d7c76ba7SJoe Perches				} else {
5086d7c76ba7SJoe Perches					$cast = $cast2;
5087d7c76ba7SJoe Perches				}
5088d7c76ba7SJoe Perches				WARN("MINMAX",
5089d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5090554e165cSAndy Whitcroft			}
5091554e165cSAndy Whitcroft		}
5092554e165cSAndy Whitcroft
50934a273195SJoe Perches# check usleep_range arguments
50944a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
50954a273195SJoe Perches		    defined $stat &&
50964a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
50974a273195SJoe Perches			my $min = $1;
50984a273195SJoe Perches			my $max = $7;
50994a273195SJoe Perches			if ($min eq $max) {
51004a273195SJoe Perches				WARN("USLEEP_RANGE",
51014a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
51024a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
51034a273195SJoe Perches				 $min > $max) {
51044a273195SJoe Perches				WARN("USLEEP_RANGE",
51054a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
51064a273195SJoe Perches			}
51074a273195SJoe Perches		}
51084a273195SJoe Perches
5109823b794cSJoe Perches# check for naked sscanf
5110823b794cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5111823b794cSJoe Perches		    defined $stat &&
51126c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
5113823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5114823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5115823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5116823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
5117823b794cSJoe Perches			$lc = $lc + $linenr;
5118823b794cSJoe Perches			my $stat_real = raw_line($linenr, 0);
5119823b794cSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5120823b794cSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5121823b794cSJoe Perches			}
5122823b794cSJoe Perches			WARN("NAKED_SSCANF",
5123823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5124823b794cSJoe Perches		}
5125823b794cSJoe Perches
5126afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
5127afc819abSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5128afc819abSJoe Perches		    defined $stat &&
5129afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
5130afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
5131afc819abSJoe Perches			$lc = $lc + $linenr;
5132afc819abSJoe Perches			my $stat_real = raw_line($linenr, 0);
5133afc819abSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5134afc819abSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5135afc819abSJoe Perches			}
5136afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5137afc819abSJoe Perches				my $format = $6;
5138afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
5139afc819abSJoe Perches				if ($count == 1 &&
5140afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5141afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
5142afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5143afc819abSJoe Perches				}
5144afc819abSJoe Perches			}
5145afc819abSJoe Perches		}
5146afc819abSJoe Perches
514770dc8a48SJoe Perches# check for new externs in .h files.
514870dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
514970dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5150d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
515170dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
515270dc8a48SJoe Perches			    $fix) {
5153194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
515470dc8a48SJoe Perches			}
515570dc8a48SJoe Perches		}
515670dc8a48SJoe Perches
5157de7d4f0eSAndy Whitcroft# check for new externs in .c files.
5158171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
5159c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5160171ae1a4SAndy Whitcroft		{
5161c45dcabdSAndy Whitcroft			my $function_name = $1;
5162c45dcabdSAndy Whitcroft			my $paren_space = $2;
5163171ae1a4SAndy Whitcroft
5164171ae1a4SAndy Whitcroft			my $s = $stat;
5165171ae1a4SAndy Whitcroft			if (defined $cond) {
5166171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
5167171ae1a4SAndy Whitcroft			}
5168c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
5169c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
5170c45dcabdSAndy Whitcroft			{
5171000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
5172000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
5173de7d4f0eSAndy Whitcroft			}
5174de7d4f0eSAndy Whitcroft
5175171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
5176000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
5177000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
5178171ae1a4SAndy Whitcroft			}
51799c9ba34eSAndy Whitcroft
51809c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
51819c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
51829c9ba34eSAndy Whitcroft		{
5183000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
5184000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
5185171ae1a4SAndy Whitcroft		}
5186171ae1a4SAndy Whitcroft
5187de7d4f0eSAndy Whitcroft# checks for new __setup's
5188de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
5189de7d4f0eSAndy Whitcroft			my $name = $1;
5190de7d4f0eSAndy Whitcroft
5191de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
5192000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
5193000d1cc1SJoe Perches				    "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
5194de7d4f0eSAndy Whitcroft			}
5195653d4876SAndy Whitcroft		}
51969c0ca6f9SAndy Whitcroft
51979c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
5198caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
5199000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
5200000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
52019c0ca6f9SAndy Whitcroft		}
520213214adfSAndy Whitcroft
5203a640d25cSJoe Perches# alloc style
5204a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
5205a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5206a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
5207a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
5208a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
5209a640d25cSJoe Perches		}
5210a640d25cSJoe Perches
521160a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
521260a55369SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5213e367455aSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
521460a55369SJoe Perches			my $oldfunc = $3;
521560a55369SJoe Perches			my $a1 = $4;
521660a55369SJoe Perches			my $a2 = $10;
521760a55369SJoe Perches			my $newfunc = "kmalloc_array";
521860a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
521960a55369SJoe Perches			my $r1 = $a1;
522060a55369SJoe Perches			my $r2 = $a2;
522160a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
522260a55369SJoe Perches				$r1 = $a2;
522360a55369SJoe Perches				$r2 = $a1;
522460a55369SJoe Perches			}
5225e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
5226e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
5227e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
5228e367455aSJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herecurr) &&
5229e367455aSJoe Perches				    $fix) {
5230194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
523160a55369SJoe Perches
523260a55369SJoe Perches				}
523360a55369SJoe Perches			}
523460a55369SJoe Perches		}
523560a55369SJoe Perches
5236972fdea2SJoe Perches# check for krealloc arg reuse
5237972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5238972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
5239972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
5240972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
5241972fdea2SJoe Perches		}
5242972fdea2SJoe Perches
52435ce59ae0SJoe Perches# check for alloc argument mismatch
52445ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
52455ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
52465ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
52475ce59ae0SJoe Perches		}
52485ce59ae0SJoe Perches
5249caf2a54fSJoe Perches# check for multiple semicolons
5250caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
5251d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
5252d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
5253d5e616fcSJoe Perches			    $fix) {
5254194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
5255d5e616fcSJoe Perches			}
5256d1e2ad07SJoe Perches		}
5257d1e2ad07SJoe Perches
52580ab90191SJoe Perches# check for #defines like: 1 << <digit> that could be BIT(digit)
52590ab90191SJoe Perches		if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
52600ab90191SJoe Perches			my $ull = "";
52610ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
52620ab90191SJoe Perches			if (CHK("BIT_MACRO",
52630ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
52640ab90191SJoe Perches			    $fix) {
52650ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
52660ab90191SJoe Perches			}
52670ab90191SJoe Perches		}
52680ab90191SJoe Perches
5269e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
5270c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
5271c34c09a8SJoe Perches			my $has_break = 0;
5272c34c09a8SJoe Perches			my $has_statement = 0;
5273c34c09a8SJoe Perches			my $count = 0;
5274c34c09a8SJoe Perches			my $prevline = $linenr;
5275e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
5276c34c09a8SJoe Perches				$prevline--;
5277c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
5278c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
5279c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
5280c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
5281c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
5282c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
5283c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
5284c34c09a8SJoe Perches				$has_statement = 1;
5285c34c09a8SJoe Perches				$count++;
5286c34c09a8SJoe Perches				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
5287c34c09a8SJoe Perches			}
5288c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
5289c34c09a8SJoe Perches				WARN("MISSING_BREAK",
5290c34c09a8SJoe Perches				     "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr);
5291c34c09a8SJoe Perches			}
5292c34c09a8SJoe Perches		}
5293c34c09a8SJoe Perches
5294d1e2ad07SJoe Perches# check for switch/default statements without a break;
5295d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5296d1e2ad07SJoe Perches		    defined $stat &&
5297d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
5298d1e2ad07SJoe Perches			my $ctx = '';
5299d1e2ad07SJoe Perches			my $herectx = $here . "\n";
5300d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
5301d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
5302d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
5303d1e2ad07SJoe Perches			}
5304d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
5305d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
5306caf2a54fSJoe Perches		}
5307caf2a54fSJoe Perches
530813214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
5309d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
5310d5e616fcSJoe Perches			if (WARN("USE_FUNC",
5311d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
5312d5e616fcSJoe Perches			    $fix) {
5313194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
5314d5e616fcSJoe Perches			}
531513214adfSAndy Whitcroft		}
5316773647a0SAndy Whitcroft
531762ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
531862ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
531962ec818fSJoe Perches			ERROR("DATE_TIME",
532062ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
532162ec818fSJoe Perches		}
532262ec818fSJoe Perches
53232c92488aSJoe Perches# check for use of yield()
53242c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
53252c92488aSJoe Perches			WARN("YIELD",
53262c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
53272c92488aSJoe Perches		}
53282c92488aSJoe Perches
5329179f8f40SJoe Perches# check for comparisons against true and false
5330179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
5331179f8f40SJoe Perches			my $lead = $1;
5332179f8f40SJoe Perches			my $arg = $2;
5333179f8f40SJoe Perches			my $test = $3;
5334179f8f40SJoe Perches			my $otype = $4;
5335179f8f40SJoe Perches			my $trail = $5;
5336179f8f40SJoe Perches			my $op = "!";
5337179f8f40SJoe Perches
5338179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
5339179f8f40SJoe Perches
5340179f8f40SJoe Perches			my $type = lc($otype);
5341179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
5342179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
5343179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
5344179f8f40SJoe Perches					$op = "";
5345179f8f40SJoe Perches				}
5346179f8f40SJoe Perches
5347179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
5348179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
5349179f8f40SJoe Perches
5350179f8f40SJoe Perches## maybe suggesting a correct construct would better
5351179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
5352179f8f40SJoe Perches
5353179f8f40SJoe Perches			}
5354179f8f40SJoe Perches		}
5355179f8f40SJoe Perches
53564882720bSThomas Gleixner# check for semaphores initialized locked
53574882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
5358000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
5359000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
5360773647a0SAndy Whitcroft		}
53616712d858SJoe Perches
536267d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
536367d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
5364000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
536567d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
5366773647a0SAndy Whitcroft		}
53676712d858SJoe Perches
5368ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
5369f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
5370000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
5371ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
5372f3db6639SMichael Ellerman		}
53736712d858SJoe Perches
53740f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
53750f3c5aabSJoe Perches		my $const_structs = qr{
53760f3c5aabSJoe Perches				acpi_dock_ops|
537779404849SEmese Revfy				address_space_operations|
537879404849SEmese Revfy				backlight_ops|
537979404849SEmese Revfy				block_device_operations|
538079404849SEmese Revfy				dentry_operations|
538179404849SEmese Revfy				dev_pm_ops|
538279404849SEmese Revfy				dma_map_ops|
538379404849SEmese Revfy				extent_io_ops|
538479404849SEmese Revfy				file_lock_operations|
538579404849SEmese Revfy				file_operations|
538679404849SEmese Revfy				hv_ops|
538779404849SEmese Revfy				ide_dma_ops|
538879404849SEmese Revfy				intel_dvo_dev_ops|
538979404849SEmese Revfy				item_operations|
539079404849SEmese Revfy				iwl_ops|
539179404849SEmese Revfy				kgdb_arch|
539279404849SEmese Revfy				kgdb_io|
539379404849SEmese Revfy				kset_uevent_ops|
539479404849SEmese Revfy				lock_manager_operations|
539579404849SEmese Revfy				microcode_ops|
539679404849SEmese Revfy				mtrr_ops|
539779404849SEmese Revfy				neigh_ops|
539879404849SEmese Revfy				nlmsvc_binding|
53990f3c5aabSJoe Perches				of_device_id|
540079404849SEmese Revfy				pci_raw_ops|
540179404849SEmese Revfy				pipe_buf_operations|
540279404849SEmese Revfy				platform_hibernation_ops|
540379404849SEmese Revfy				platform_suspend_ops|
540479404849SEmese Revfy				proto_ops|
540579404849SEmese Revfy				rpc_pipe_ops|
540679404849SEmese Revfy				seq_operations|
540779404849SEmese Revfy				snd_ac97_build_ops|
540879404849SEmese Revfy				soc_pcmcia_socket_ops|
540979404849SEmese Revfy				stacktrace_ops|
541079404849SEmese Revfy				sysfs_ops|
541179404849SEmese Revfy				tty_operations|
54126d07d01bSJoe Perches				uart_ops|
541379404849SEmese Revfy				usb_mon_operations|
541479404849SEmese Revfy				wd_ops}x;
54156903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
54160f3c5aabSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b/) {
5417000d1cc1SJoe Perches			WARN("CONST_STRUCT",
5418000d1cc1SJoe Perches			     "struct $1 should normally be const\n" .
54196903ffb2SAndy Whitcroft				$herecurr);
54202b6db5cbSAndy Whitcroft		}
5421773647a0SAndy Whitcroft
5422773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
5423773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
5424773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
5425c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
5426c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
5427171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
5428171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
5429171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
5430773647a0SAndy Whitcroft		{
5431000d1cc1SJoe Perches			WARN("NR_CPUS",
5432000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
5433773647a0SAndy Whitcroft		}
54349c9ba34eSAndy Whitcroft
543552ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
543652ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
543752ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
543852ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
543952ea8506SJoe Perches		}
544052ea8506SJoe Perches
5441acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
5442acd9362cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5443acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
5444acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
5445acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
5446acd9362cSJoe Perches		}
5447acd9362cSJoe Perches
5448691d77b6SAndy Whitcroft# whine mightly about in_atomic
5449691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
5450691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
5451000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
5452000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
5453f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
5454000d1cc1SJoe Perches				WARN("IN_ATOMIC",
5455000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
5456691d77b6SAndy Whitcroft			}
5457691d77b6SAndy Whitcroft		}
54581704f47bSPeter Zijlstra
54591704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
54601704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
54611704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
54621704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
54631704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
54641704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
5465000d1cc1SJoe Perches				ERROR("LOCKDEP",
5466000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
54671704f47bSPeter Zijlstra			}
54681704f47bSPeter Zijlstra		}
546988f8831cSDave Jones
5470b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
5471b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
5472000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
5473000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
547488f8831cSDave Jones		}
54752435880fSJoe Perches
5476515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
5477515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
5478515a235eSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5479515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
54802435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
54812435880fSJoe Perches				my $func = $entry->[0];
54822435880fSJoe Perches				my $arg_pos = $entry->[1];
54832435880fSJoe Perches
54842435880fSJoe Perches				my $skip_args = "";
54852435880fSJoe Perches				if ($arg_pos > 1) {
54862435880fSJoe Perches					$arg_pos--;
54872435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
54882435880fSJoe Perches				}
54892435880fSJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
5490515a235eSJoe Perches				if ($line =~ /$test/) {
54912435880fSJoe Perches					my $val = $1;
54922435880fSJoe Perches					$val = $6 if ($skip_args ne "");
54932435880fSJoe Perches
54941727cc70SJoe Perches					if ($val !~ /^0$/ &&
54951727cc70SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
54961727cc70SJoe Perches					     length($val) ne 4)) {
54972435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
54981727cc70SJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
5499c0a5c898SJoe Perches					} elsif ($val =~ /^$Octal$/ && (oct($val) & 02)) {
5500c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
5501c0a5c898SJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
55022435880fSJoe Perches					}
55032435880fSJoe Perches				}
55042435880fSJoe Perches			}
550513214adfSAndy Whitcroft		}
5506515a235eSJoe Perches	}
550713214adfSAndy Whitcroft
550813214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
550913214adfSAndy Whitcroft	# so just keep quiet.
551013214adfSAndy Whitcroft	if ($#rawlines == -1) {
551113214adfSAndy Whitcroft		exit(0);
55120a920b5bSAndy Whitcroft	}
55130a920b5bSAndy Whitcroft
55148905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
55158905a67cSAndy Whitcroft	# things that appear to be patches.
55168905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
55178905a67cSAndy Whitcroft		exit(0);
55188905a67cSAndy Whitcroft	}
55198905a67cSAndy Whitcroft
55208905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
55218905a67cSAndy Whitcroft	# just keep quiet.
55228905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
55238905a67cSAndy Whitcroft		exit(0);
55248905a67cSAndy Whitcroft	}
55258905a67cSAndy Whitcroft
55268905a67cSAndy Whitcroft	if (!$is_patch) {
5527000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
5528000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
55290a920b5bSAndy Whitcroft	}
55300a920b5bSAndy Whitcroft	if ($is_patch && $chk_signoff && $signoff == 0) {
5531000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
5532000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
55330a920b5bSAndy Whitcroft	}
55340a920b5bSAndy Whitcroft
5535f0a594c1SAndy Whitcroft	print report_dump();
553613214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
553713214adfSAndy Whitcroft		print "$filename " if ($summary_file);
55386c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
55396c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
55406c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
55418905a67cSAndy Whitcroft		print "\n" if ($quiet == 0);
55426c72ffaaSAndy Whitcroft	}
55438905a67cSAndy Whitcroft
5544d2c0a235SAndy Whitcroft	if ($quiet == 0) {
5545d1fe9c09SJoe Perches
5546d1fe9c09SJoe Perches		if ($^V lt 5.10.0) {
5547d1fe9c09SJoe Perches			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
5548d1fe9c09SJoe Perches			print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
5549d1fe9c09SJoe Perches		}
5550d1fe9c09SJoe Perches
5551d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
5552d2c0a235SAndy Whitcroft		# then suggest that.
5553d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
5554d2c0a235SAndy Whitcroft			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
5555d2c0a235SAndy Whitcroft			print "      scripts/cleanfile\n\n";
5556b0781216SMike Frysinger			$rpt_cleaners = 0;
5557d2c0a235SAndy Whitcroft		}
5558d2c0a235SAndy Whitcroft	}
5559d2c0a235SAndy Whitcroft
556091bfe484SJoe Perches	hash_show_words(\%use_type, "Used");
556191bfe484SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
5562000d1cc1SJoe Perches
5563d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
5564d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
5565d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
55669624b8d6SJoe Perches		my $newfile = $filename;
55679624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
55683705ce5bSJoe Perches		my $linecount = 0;
55693705ce5bSJoe Perches		my $f;
55703705ce5bSJoe Perches
5571d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
5572d752fcc8SJoe Perches
55733705ce5bSJoe Perches		open($f, '>', $newfile)
55743705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
55753705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
55763705ce5bSJoe Perches			$linecount++;
55773705ce5bSJoe Perches			if ($file) {
55783705ce5bSJoe Perches				if ($linecount > 3) {
55793705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
55803705ce5bSJoe Perches					print $f $fixed_line . "\n";
55813705ce5bSJoe Perches				}
55823705ce5bSJoe Perches			} else {
55833705ce5bSJoe Perches				print $f $fixed_line . "\n";
55843705ce5bSJoe Perches			}
55853705ce5bSJoe Perches		}
55863705ce5bSJoe Perches		close($f);
55873705ce5bSJoe Perches
55883705ce5bSJoe Perches		if (!$quiet) {
55893705ce5bSJoe Perches			print << "EOM";
55903705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
55913705ce5bSJoe Perches
55923705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
55933705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
55943705ce5bSJoe Perches
55953705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
55963705ce5bSJoe PerchesNo warranties, expressed or implied...
55973705ce5bSJoe Perches
55983705ce5bSJoe PerchesEOM
55993705ce5bSJoe Perches		}
56003705ce5bSJoe Perches	}
56013705ce5bSJoe Perches
56020a920b5bSAndy Whitcroft	if ($clean == 1 && $quiet == 0) {
5603c2fdda0dSAndy Whitcroft		print "$vname has no obvious style problems and is ready for submission.\n"
56040a920b5bSAndy Whitcroft	}
56050a920b5bSAndy Whitcroft	if ($clean == 0 && $quiet == 0) {
5606000d1cc1SJoe Perches		print << "EOM";
5607000d1cc1SJoe Perches$vname has style problems, please review.
5608000d1cc1SJoe Perches
5609000d1cc1SJoe PerchesIf any of these errors are false positives, please report
5610000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS.
5611000d1cc1SJoe PerchesEOM
56120a920b5bSAndy Whitcroft	}
561313214adfSAndy Whitcroft
56140a920b5bSAndy Whitcroft	return $clean;
56150a920b5bSAndy Whitcroft}
5616