xref: /linux-6.15/scripts/checkpatch.pl (revision d62a201f)
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;
100a920b5bSAndy Whitcroft
110a920b5bSAndy Whitcroftmy $P = $0;
1200df344fSAndy Whitcroft$P =~ s@.*/@@g;
130a920b5bSAndy Whitcroft
14000d1cc1SJoe Perchesmy $V = '0.32';
150a920b5bSAndy Whitcroft
160a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
170a920b5bSAndy Whitcroft
180a920b5bSAndy Whitcroftmy $quiet = 0;
190a920b5bSAndy Whitcroftmy $tree = 1;
200a920b5bSAndy Whitcroftmy $chk_signoff = 1;
210a920b5bSAndy Whitcroftmy $chk_patch = 1;
22773647a0SAndy Whitcroftmy $tst_only;
236c72ffaaSAndy Whitcroftmy $emacs = 0;
248905a67cSAndy Whitcroftmy $terse = 0;
256c72ffaaSAndy Whitcroftmy $file = 0;
266c72ffaaSAndy Whitcroftmy $check = 0;
278905a67cSAndy Whitcroftmy $summary = 1;
288905a67cSAndy Whitcroftmy $mailback = 0;
2913214adfSAndy Whitcroftmy $summary_file = 0;
30000d1cc1SJoe Perchesmy $show_types = 0;
313705ce5bSJoe Perchesmy $fix = 0;
326c72ffaaSAndy Whitcroftmy $root;
33c2fdda0dSAndy Whitcroftmy %debug;
34000d1cc1SJoe Perchesmy %ignore_type = ();
353445686aSJoe Perchesmy %camelcase = ();
36000d1cc1SJoe Perchesmy @ignore = ();
3777f5b10aSHannes Edermy $help = 0;
38000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
396cd7f386SJoe Perchesmy $max_line_length = 80;
40*d62a201fSDave Hansenmy $ignore_perl_version = 0;
41*d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
4277f5b10aSHannes Eder
4377f5b10aSHannes Edersub help {
4477f5b10aSHannes Eder	my ($exitcode) = @_;
4577f5b10aSHannes Eder
4677f5b10aSHannes Eder	print << "EOM";
4777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
4877f5b10aSHannes EderVersion: $V
4977f5b10aSHannes Eder
5077f5b10aSHannes EderOptions:
5177f5b10aSHannes Eder  -q, --quiet                quiet
5277f5b10aSHannes Eder  --no-tree                  run without a kernel tree
5377f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
5477f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
5577f5b10aSHannes Eder  --emacs                    emacs compile window format
5677f5b10aSHannes Eder  --terse                    one line per report
5777f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
5877f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
59000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
606cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
61000d1cc1SJoe Perches  --show-types               show the message "types" in the output
6277f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
6377f5b10aSHannes Eder  --no-summary               suppress the per-file summary
6477f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
6577f5b10aSHannes Eder  --summary-file             include the filename in summary
6677f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
6777f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
6877f5b10aSHannes Eder                             is all off)
6977f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
7077f5b10aSHannes Eder                             literally
713705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
723705ce5bSJoe Perches                             If correctable single-line errors exist, create
733705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
743705ce5bSJoe Perches                             with potential errors corrected to the preferred
753705ce5bSJoe Perches                             checkpatch style
76*d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
77*d62a201fSDave Hansen                             runtime errors.
7877f5b10aSHannes Eder  -h, --help, --version      display this help and exit
7977f5b10aSHannes Eder
8077f5b10aSHannes EderWhen FILE is - read standard input.
8177f5b10aSHannes EderEOM
8277f5b10aSHannes Eder
8377f5b10aSHannes Eder	exit($exitcode);
8477f5b10aSHannes Eder}
8577f5b10aSHannes Eder
86000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
87000d1cc1SJoe Perchesif (-f $conf) {
88000d1cc1SJoe Perches	my @conf_args;
89000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
90000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
91000d1cc1SJoe Perches
92000d1cc1SJoe Perches	while (<$conffile>) {
93000d1cc1SJoe Perches		my $line = $_;
94000d1cc1SJoe Perches
95000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
96000d1cc1SJoe Perches		$line =~ s/^\s*//g;
97000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
98000d1cc1SJoe Perches
99000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
100000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
101000d1cc1SJoe Perches
102000d1cc1SJoe Perches		my @words = split(" ", $line);
103000d1cc1SJoe Perches		foreach my $word (@words) {
104000d1cc1SJoe Perches			last if ($word =~ m/^#/);
105000d1cc1SJoe Perches			push (@conf_args, $word);
106000d1cc1SJoe Perches		}
107000d1cc1SJoe Perches	}
108000d1cc1SJoe Perches	close($conffile);
109000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
110000d1cc1SJoe Perches}
111000d1cc1SJoe Perches
1120a920b5bSAndy WhitcroftGetOptions(
1136c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1140a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1150a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1160a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1176c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1188905a67cSAndy Whitcroft	'terse!'	=> \$terse,
11977f5b10aSHannes Eder	'f|file!'	=> \$file,
1206c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1216c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
122000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
123000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
1246cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
1256c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
1268905a67cSAndy Whitcroft	'summary!'	=> \$summary,
1278905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
12813214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
1293705ce5bSJoe Perches	'fix!'		=> \$fix,
130*d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
131c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
132773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
13377f5b10aSHannes Eder	'h|help'	=> \$help,
13477f5b10aSHannes Eder	'version'	=> \$help
13577f5b10aSHannes Eder) or help(1);
13677f5b10aSHannes Eder
13777f5b10aSHannes Ederhelp(0) if ($help);
1380a920b5bSAndy Whitcroft
1390a920b5bSAndy Whitcroftmy $exit = 0;
1400a920b5bSAndy Whitcroft
141*d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
142*d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
143*d62a201fSDave Hansen	if (!$ignore_perl_version) {
144*d62a201fSDave Hansen		exit(1);
145*d62a201fSDave Hansen	}
146*d62a201fSDave Hansen}
147*d62a201fSDave Hansen
1480a920b5bSAndy Whitcroftif ($#ARGV < 0) {
14977f5b10aSHannes Eder	print "$P: no input files\n";
1500a920b5bSAndy Whitcroft	exit(1);
1510a920b5bSAndy Whitcroft}
1520a920b5bSAndy Whitcroft
153000d1cc1SJoe Perches@ignore = split(/,/, join(',',@ignore));
154000d1cc1SJoe Perchesforeach my $word (@ignore) {
155000d1cc1SJoe Perches	$word =~ s/\s*\n?$//g;
156000d1cc1SJoe Perches	$word =~ s/^\s*//g;
157000d1cc1SJoe Perches	$word =~ s/\s+/ /g;
158000d1cc1SJoe Perches	$word =~ tr/[a-z]/[A-Z]/;
159000d1cc1SJoe Perches
160000d1cc1SJoe Perches	next if ($word =~ m/^\s*#/);
161000d1cc1SJoe Perches	next if ($word =~ m/^\s*$/);
162000d1cc1SJoe Perches
163000d1cc1SJoe Perches	$ignore_type{$word}++;
164000d1cc1SJoe Perches}
165000d1cc1SJoe Perches
166c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
167c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
1687429c690SAndy Whitcroftmy $dbg_type = 0;
169a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
170c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
17121caa13cSAndy Whitcroft	## no critic
17221caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
17321caa13cSAndy Whitcroft	die "$@" if ($@);
174c2fdda0dSAndy Whitcroft}
175c2fdda0dSAndy Whitcroft
176d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
177d2c0a235SAndy Whitcroft
1788905a67cSAndy Whitcroftif ($terse) {
1798905a67cSAndy Whitcroft	$emacs = 1;
1808905a67cSAndy Whitcroft	$quiet++;
1818905a67cSAndy Whitcroft}
1828905a67cSAndy Whitcroft
1836c72ffaaSAndy Whitcroftif ($tree) {
1846c72ffaaSAndy Whitcroft	if (defined $root) {
1856c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
1866c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
1876c72ffaaSAndy Whitcroft		}
1886c72ffaaSAndy Whitcroft	} else {
1896c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
1906c72ffaaSAndy Whitcroft			$root = '.';
1916c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
1926c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
1936c72ffaaSAndy Whitcroft			$root = $1;
1946c72ffaaSAndy Whitcroft		}
1956c72ffaaSAndy Whitcroft	}
1966c72ffaaSAndy Whitcroft
1976c72ffaaSAndy Whitcroft	if (!defined $root) {
1980a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
1990a920b5bSAndy Whitcroft		exit(2);
2000a920b5bSAndy Whitcroft	}
2016c72ffaaSAndy Whitcroft}
2026c72ffaaSAndy Whitcroft
2036c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
2046c72ffaaSAndy Whitcroft
2052ceb532bSAndy Whitcroftour $Ident	= qr{
2062ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
2072ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
2082ceb532bSAndy Whitcroft		}x;
2096c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
2106c72ffaaSAndy Whitcroftour $Sparse	= qr{
2116c72ffaaSAndy Whitcroft			__user|
2126c72ffaaSAndy Whitcroft			__kernel|
2136c72ffaaSAndy Whitcroft			__force|
2146c72ffaaSAndy Whitcroft			__iomem|
2156c72ffaaSAndy Whitcroft			__must_check|
2166c72ffaaSAndy Whitcroft			__init_refok|
217417495edSAndy Whitcroft			__kprobes|
218165e72a6SSven Eckelmann			__ref|
219165e72a6SSven Eckelmann			__rcu
2206c72ffaaSAndy Whitcroft		}x;
22152131292SWolfram Sang
22252131292SWolfram Sang# Notes to $Attribute:
22352131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
2246c72ffaaSAndy Whitcroftour $Attribute	= qr{
2256c72ffaaSAndy Whitcroft			const|
22603f1df7dSJoe Perches			__percpu|
22703f1df7dSJoe Perches			__nocast|
22803f1df7dSJoe Perches			__safe|
22903f1df7dSJoe Perches			__bitwise__|
23003f1df7dSJoe Perches			__packed__|
23103f1df7dSJoe Perches			__packed2__|
23203f1df7dSJoe Perches			__naked|
23303f1df7dSJoe Perches			__maybe_unused|
23403f1df7dSJoe Perches			__always_unused|
23503f1df7dSJoe Perches			__noreturn|
23603f1df7dSJoe Perches			__used|
23703f1df7dSJoe Perches			__cold|
23803f1df7dSJoe Perches			__noclone|
23903f1df7dSJoe Perches			__deprecated|
2406c72ffaaSAndy Whitcroft			__read_mostly|
2416c72ffaaSAndy Whitcroft			__kprobes|
24252131292SWolfram Sang			__(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
24324e1d81aSAndy Whitcroft			____cacheline_aligned|
24424e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
2455fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
2465fe3af11SAndy Whitcroft			__weak
2476c72ffaaSAndy Whitcroft		  }x;
248c45dcabdSAndy Whitcroftour $Modifier;
2496c72ffaaSAndy Whitcroftour $Inline	= qr{inline|__always_inline|noinline};
2506c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
2516c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
2526c72ffaaSAndy Whitcroft
25395e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
25495e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
25595e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
25695e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
257326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
258326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
259326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
26074349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
26195e2c602SJoe Perchesour $Constant	= qr{$Float|$Binary|$Hex|$Int};
262326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
26386f9d059SAndy Whitcroftour $Compare    = qr{<=|>=|==|!=|<|>};
26423f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
2656c72ffaaSAndy Whitcroftour $Operators	= qr{
2666c72ffaaSAndy Whitcroft			<=|>=|==|!=|
2676c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
26823f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
2696c72ffaaSAndy Whitcroft		  }x;
2706c72ffaaSAndy Whitcroft
2718905a67cSAndy Whitcroftour $NonptrType;
2728905a67cSAndy Whitcroftour $Type;
2738905a67cSAndy Whitcroftour $Declare;
2748905a67cSAndy Whitcroft
27515662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
27615662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
277171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
278171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
279171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
280171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
281171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
282171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
283171ae1a4SAndy Whitcroft}x;
284171ae1a4SAndy Whitcroft
28515662b3eSJoe Perchesour $UTF8	= qr{
28615662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
28715662b3eSJoe Perches	| $NON_ASCII_UTF8
28815662b3eSJoe Perches}x;
28915662b3eSJoe Perches
2908ed22cadSAndy Whitcroftour $typeTypedefs = qr{(?x:
291fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
2928ed22cadSAndy Whitcroft	atomic_t
2938ed22cadSAndy Whitcroft)};
2948ed22cadSAndy Whitcroft
295691e669bSJoe Perchesour $logFunctions = qr{(?x:
2966e60c02eSJoe Perches	printk(?:_ratelimited|_once|)|
2977d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
2986e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
299b0531722SJoe Perches	panic|
300b0531722SJoe Perches	MODULE_[A-Z_]+
301691e669bSJoe Perches)};
302691e669bSJoe Perches
30320112475SJoe Perchesour $signature_tags = qr{(?xi:
30420112475SJoe Perches	Signed-off-by:|
30520112475SJoe Perches	Acked-by:|
30620112475SJoe Perches	Tested-by:|
30720112475SJoe Perches	Reviewed-by:|
30820112475SJoe Perches	Reported-by:|
3098543ae12SMugunthan V N	Suggested-by:|
31020112475SJoe Perches	To:|
31120112475SJoe Perches	Cc:
31220112475SJoe Perches)};
31320112475SJoe Perches
3148905a67cSAndy Whitcroftour @typeList = (
3158905a67cSAndy Whitcroft	qr{void},
316c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?char},
317c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?short},
318c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?int},
319c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long},
320c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+int},
321c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long},
322c45dcabdSAndy Whitcroft	qr{(?:unsigned\s+)?long\s+long\s+int},
3238905a67cSAndy Whitcroft	qr{unsigned},
3248905a67cSAndy Whitcroft	qr{float},
3258905a67cSAndy Whitcroft	qr{double},
3268905a67cSAndy Whitcroft	qr{bool},
3278905a67cSAndy Whitcroft	qr{struct\s+$Ident},
3288905a67cSAndy Whitcroft	qr{union\s+$Ident},
3298905a67cSAndy Whitcroft	qr{enum\s+$Ident},
3308905a67cSAndy Whitcroft	qr{${Ident}_t},
3318905a67cSAndy Whitcroft	qr{${Ident}_handler},
3328905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
3338905a67cSAndy Whitcroft);
334c45dcabdSAndy Whitcroftour @modifierList = (
335c45dcabdSAndy Whitcroft	qr{fastcall},
336c45dcabdSAndy Whitcroft);
3378905a67cSAndy Whitcroft
3387840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
3397840a94cSWolfram Sang	irq|
3407840a94cSWolfram Sang	memory
3417840a94cSWolfram Sang)};
3427840a94cSWolfram Sang# memory.h: ARM has a custom one
3437840a94cSWolfram Sang
3448905a67cSAndy Whitcroftsub build_types {
345d2172eb5SAndy Whitcroft	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
346d2172eb5SAndy Whitcroft	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
347c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
3488905a67cSAndy Whitcroft	$NonptrType	= qr{
349d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
350cf655043SAndy Whitcroft			(?:
3516b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
3528ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
353c45dcabdSAndy Whitcroft				(?:${all}\b)
354cf655043SAndy Whitcroft			)
355c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
3568905a67cSAndy Whitcroft		  }x;
3578905a67cSAndy Whitcroft	$Type	= qr{
358c45dcabdSAndy Whitcroft			$NonptrType
359b337d8b8SAndy Whitcroft			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
360c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
3618905a67cSAndy Whitcroft		  }x;
3628905a67cSAndy Whitcroft	$Declare	= qr{(?:$Storage\s+)?$Type};
3638905a67cSAndy Whitcroft}
3648905a67cSAndy Whitcroftbuild_types();
3656c72ffaaSAndy Whitcroft
3667d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
367d1fe9c09SJoe Perches
368d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
369d1fe9c09SJoe Perches# requires at least perl version v5.10.0
370d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
371d1fe9c09SJoe Perches
372d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
373d1fe9c09SJoe Perchesour $LvalOrFunc	= qr{($Lval)\s*($balanced_parens{0,1})\s*};
374d7c76ba7SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
3757d2367afSJoe Perches
3767d2367afSJoe Perchessub deparenthesize {
3777d2367afSJoe Perches	my ($string) = @_;
3787d2367afSJoe Perches	return "" if (!defined($string));
3797d2367afSJoe Perches	$string =~ s@^\s*\(\s*@@g;
3807d2367afSJoe Perches	$string =~ s@\s*\)\s*$@@g;
3817d2367afSJoe Perches	$string =~ s@\s+@ @g;
3827d2367afSJoe Perches	return $string;
3837d2367afSJoe Perches}
3847d2367afSJoe Perches
3853445686aSJoe Perchessub seed_camelcase_file {
3863445686aSJoe Perches	my ($file) = @_;
3873445686aSJoe Perches
3883445686aSJoe Perches	return if (!(-f $file));
3893445686aSJoe Perches
3903445686aSJoe Perches	local $/;
3913445686aSJoe Perches
3923445686aSJoe Perches	open(my $include_file, '<', "$file")
3933445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
3943445686aSJoe Perches	my $text = <$include_file>;
3953445686aSJoe Perches	close($include_file);
3963445686aSJoe Perches
3973445686aSJoe Perches	my @lines = split('\n', $text);
3983445686aSJoe Perches
3993445686aSJoe Perches	foreach my $line (@lines) {
4003445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
4013445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
4023445686aSJoe Perches			$camelcase{$1} = 1;
4033445686aSJoe Perches		}
4043445686aSJoe Perches	        elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*\(/) {
4053445686aSJoe Perches			$camelcase{$1} = 1;
4063445686aSJoe Perches		}
4073445686aSJoe Perches	}
4083445686aSJoe Perches}
4093445686aSJoe Perches
4103445686aSJoe Perchesmy $camelcase_seeded = 0;
4113445686aSJoe Perchessub seed_camelcase_includes {
4123445686aSJoe Perches	return if ($camelcase_seeded);
4133445686aSJoe Perches
4143445686aSJoe Perches	my $files;
415c707a81dSJoe Perches	my $camelcase_cache = "";
416c707a81dSJoe Perches	my @include_files = ();
417c707a81dSJoe Perches
418c707a81dSJoe Perches	$camelcase_seeded = 1;
419351b2a1fSJoe Perches
4203445686aSJoe Perches	if (-d ".git") {
421351b2a1fSJoe Perches		my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
422351b2a1fSJoe Perches		chomp $git_last_include_commit;
423c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
424c707a81dSJoe Perches	} else {
425c707a81dSJoe Perches		my $last_mod_date = 0;
426c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
427c707a81dSJoe Perches		@include_files = split('\n', $files);
428c707a81dSJoe Perches		foreach my $file (@include_files) {
429c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
430c707a81dSJoe Perches						   localtime((stat $file)[9]));
431c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
432c707a81dSJoe Perches		}
433c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
434c707a81dSJoe Perches	}
435c707a81dSJoe Perches
436c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
437c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
438c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
439351b2a1fSJoe Perches		while (<$camelcase_file>) {
440351b2a1fSJoe Perches			chomp;
441351b2a1fSJoe Perches			$camelcase{$_} = 1;
442351b2a1fSJoe Perches		}
443351b2a1fSJoe Perches		close($camelcase_file);
444351b2a1fSJoe Perches
445351b2a1fSJoe Perches		return;
446351b2a1fSJoe Perches	}
447c707a81dSJoe Perches
448c707a81dSJoe Perches	if (-d ".git") {
449c707a81dSJoe Perches		$files = `git ls-files "include/*.h"`;
450c707a81dSJoe Perches		@include_files = split('\n', $files);
4513445686aSJoe Perches	}
452c707a81dSJoe Perches
4533445686aSJoe Perches	foreach my $file (@include_files) {
4543445686aSJoe Perches		seed_camelcase_file($file);
4553445686aSJoe Perches	}
456351b2a1fSJoe Perches
457c707a81dSJoe Perches	if ($camelcase_cache ne "") {
458351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
459c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
460c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
461351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
462351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
463351b2a1fSJoe Perches		}
464351b2a1fSJoe Perches		close($camelcase_file);
465351b2a1fSJoe Perches	}
4663445686aSJoe Perches}
4673445686aSJoe Perches
4686c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
4690a920b5bSAndy Whitcroft
47000df344fSAndy Whitcroftmy @rawlines = ();
471c2fdda0dSAndy Whitcroftmy @lines = ();
4723705ce5bSJoe Perchesmy @fixed = ();
473c2fdda0dSAndy Whitcroftmy $vname;
4746c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
47521caa13cSAndy Whitcroft	my $FILE;
4766c72ffaaSAndy Whitcroft	if ($file) {
47721caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
4786c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
47921caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
48021caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
4816c72ffaaSAndy Whitcroft	} else {
48221caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
4836c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
4846c72ffaaSAndy Whitcroft	}
485c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
486c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
487c2fdda0dSAndy Whitcroft	} else {
488c2fdda0dSAndy Whitcroft		$vname = $filename;
489c2fdda0dSAndy Whitcroft	}
49021caa13cSAndy Whitcroft	while (<$FILE>) {
4910a920b5bSAndy Whitcroft		chomp;
49200df344fSAndy Whitcroft		push(@rawlines, $_);
4936c72ffaaSAndy Whitcroft	}
49421caa13cSAndy Whitcroft	close($FILE);
495c2fdda0dSAndy Whitcroft	if (!process($filename)) {
4960a920b5bSAndy Whitcroft		$exit = 1;
4970a920b5bSAndy Whitcroft	}
49800df344fSAndy Whitcroft	@rawlines = ();
49913214adfSAndy Whitcroft	@lines = ();
5003705ce5bSJoe Perches	@fixed = ();
5010a920b5bSAndy Whitcroft}
5020a920b5bSAndy Whitcroft
5030a920b5bSAndy Whitcroftexit($exit);
5040a920b5bSAndy Whitcroft
5050a920b5bSAndy Whitcroftsub top_of_kernel_tree {
5066c72ffaaSAndy Whitcroft	my ($root) = @_;
5076c72ffaaSAndy Whitcroft
5086c72ffaaSAndy Whitcroft	my @tree_check = (
5096c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
5106c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
5116c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
5126c72ffaaSAndy Whitcroft	);
5136c72ffaaSAndy Whitcroft
5146c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
5156c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
5160a920b5bSAndy Whitcroft			return 0;
5170a920b5bSAndy Whitcroft		}
5186c72ffaaSAndy Whitcroft	}
5196c72ffaaSAndy Whitcroft	return 1;
5206c72ffaaSAndy Whitcroft}
5210a920b5bSAndy Whitcroft
52220112475SJoe Perchessub parse_email {
52320112475SJoe Perches	my ($formatted_email) = @_;
52420112475SJoe Perches
52520112475SJoe Perches	my $name = "";
52620112475SJoe Perches	my $address = "";
52720112475SJoe Perches	my $comment = "";
52820112475SJoe Perches
52920112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
53020112475SJoe Perches		$name = $1;
53120112475SJoe Perches		$address = $2;
53220112475SJoe Perches		$comment = $3 if defined $3;
53320112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
53420112475SJoe Perches		$address = $1;
53520112475SJoe Perches		$comment = $2 if defined $2;
53620112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
53720112475SJoe Perches		$address = $1;
53820112475SJoe Perches		$comment = $2 if defined $2;
53920112475SJoe Perches		$formatted_email =~ s/$address.*$//;
54020112475SJoe Perches		$name = $formatted_email;
5413705ce5bSJoe Perches		$name = trim($name);
54220112475SJoe Perches		$name =~ s/^\"|\"$//g;
54320112475SJoe Perches		# If there's a name left after stripping spaces and
54420112475SJoe Perches		# leading quotes, and the address doesn't have both
54520112475SJoe Perches		# leading and trailing angle brackets, the address
54620112475SJoe Perches		# is invalid. ie:
54720112475SJoe Perches		#   "joe smith [email protected]" bad
54820112475SJoe Perches		#   "joe smith <[email protected]" bad
54920112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
55020112475SJoe Perches			$name = "";
55120112475SJoe Perches			$address = "";
55220112475SJoe Perches			$comment = "";
55320112475SJoe Perches		}
55420112475SJoe Perches	}
55520112475SJoe Perches
5563705ce5bSJoe Perches	$name = trim($name);
55720112475SJoe Perches	$name =~ s/^\"|\"$//g;
5583705ce5bSJoe Perches	$address = trim($address);
55920112475SJoe Perches	$address =~ s/^\<|\>$//g;
56020112475SJoe Perches
56120112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
56220112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
56320112475SJoe Perches		$name = "\"$name\"";
56420112475SJoe Perches	}
56520112475SJoe Perches
56620112475SJoe Perches	return ($name, $address, $comment);
56720112475SJoe Perches}
56820112475SJoe Perches
56920112475SJoe Perchessub format_email {
57020112475SJoe Perches	my ($name, $address) = @_;
57120112475SJoe Perches
57220112475SJoe Perches	my $formatted_email;
57320112475SJoe Perches
5743705ce5bSJoe Perches	$name = trim($name);
57520112475SJoe Perches	$name =~ s/^\"|\"$//g;
5763705ce5bSJoe Perches	$address = trim($address);
57720112475SJoe Perches
57820112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
57920112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
58020112475SJoe Perches		$name = "\"$name\"";
58120112475SJoe Perches	}
58220112475SJoe Perches
58320112475SJoe Perches	if ("$name" eq "") {
58420112475SJoe Perches		$formatted_email = "$address";
58520112475SJoe Perches	} else {
58620112475SJoe Perches		$formatted_email = "$name <$address>";
58720112475SJoe Perches	}
58820112475SJoe Perches
58920112475SJoe Perches	return $formatted_email;
59020112475SJoe Perches}
59120112475SJoe Perches
592000d1cc1SJoe Perchessub which_conf {
593000d1cc1SJoe Perches	my ($conf) = @_;
594000d1cc1SJoe Perches
595000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
596000d1cc1SJoe Perches		if (-e "$path/$conf") {
597000d1cc1SJoe Perches			return "$path/$conf";
598000d1cc1SJoe Perches		}
599000d1cc1SJoe Perches	}
600000d1cc1SJoe Perches
601000d1cc1SJoe Perches	return "";
602000d1cc1SJoe Perches}
603000d1cc1SJoe Perches
6040a920b5bSAndy Whitcroftsub expand_tabs {
6050a920b5bSAndy Whitcroft	my ($str) = @_;
6060a920b5bSAndy Whitcroft
6070a920b5bSAndy Whitcroft	my $res = '';
6080a920b5bSAndy Whitcroft	my $n = 0;
6090a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
6100a920b5bSAndy Whitcroft		if ($c eq "\t") {
6110a920b5bSAndy Whitcroft			$res .= ' ';
6120a920b5bSAndy Whitcroft			$n++;
6130a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
6140a920b5bSAndy Whitcroft				$res .= ' ';
6150a920b5bSAndy Whitcroft			}
6160a920b5bSAndy Whitcroft			next;
6170a920b5bSAndy Whitcroft		}
6180a920b5bSAndy Whitcroft		$res .= $c;
6190a920b5bSAndy Whitcroft		$n++;
6200a920b5bSAndy Whitcroft	}
6210a920b5bSAndy Whitcroft
6220a920b5bSAndy Whitcroft	return $res;
6230a920b5bSAndy Whitcroft}
6246c72ffaaSAndy Whitcroftsub copy_spacing {
625773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
6266c72ffaaSAndy Whitcroft	return $res;
6276c72ffaaSAndy Whitcroft}
6280a920b5bSAndy Whitcroft
6294a0df2efSAndy Whitcroftsub line_stats {
6304a0df2efSAndy Whitcroft	my ($line) = @_;
6314a0df2efSAndy Whitcroft
6324a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
6334a0df2efSAndy Whitcroft	$line =~ s/^.//;
6344a0df2efSAndy Whitcroft	$line = expand_tabs($line);
6354a0df2efSAndy Whitcroft
6364a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
6374a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
6384a0df2efSAndy Whitcroft
6394a0df2efSAndy Whitcroft	return (length($line), length($white));
6404a0df2efSAndy Whitcroft}
6414a0df2efSAndy Whitcroft
642773647a0SAndy Whitcroftmy $sanitise_quote = '';
643773647a0SAndy Whitcroft
644773647a0SAndy Whitcroftsub sanitise_line_reset {
645773647a0SAndy Whitcroft	my ($in_comment) = @_;
646773647a0SAndy Whitcroft
647773647a0SAndy Whitcroft	if ($in_comment) {
648773647a0SAndy Whitcroft		$sanitise_quote = '*/';
649773647a0SAndy Whitcroft	} else {
650773647a0SAndy Whitcroft		$sanitise_quote = '';
651773647a0SAndy Whitcroft	}
652773647a0SAndy Whitcroft}
65300df344fSAndy Whitcroftsub sanitise_line {
65400df344fSAndy Whitcroft	my ($line) = @_;
65500df344fSAndy Whitcroft
65600df344fSAndy Whitcroft	my $res = '';
65700df344fSAndy Whitcroft	my $l = '';
65800df344fSAndy Whitcroft
659c2fdda0dSAndy Whitcroft	my $qlen = 0;
660773647a0SAndy Whitcroft	my $off = 0;
661773647a0SAndy Whitcroft	my $c;
66200df344fSAndy Whitcroft
663773647a0SAndy Whitcroft	# Always copy over the diff marker.
664773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
665773647a0SAndy Whitcroft
666773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
667773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
668773647a0SAndy Whitcroft
669773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
670773647a0SAndy Whitcroft		# and end, all to $;.
671773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
672773647a0SAndy Whitcroft			$sanitise_quote = '*/';
673773647a0SAndy Whitcroft
674773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
675773647a0SAndy Whitcroft			$off++;
67600df344fSAndy Whitcroft			next;
677773647a0SAndy Whitcroft		}
67881bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
679773647a0SAndy Whitcroft			$sanitise_quote = '';
680773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
681773647a0SAndy Whitcroft			$off++;
682773647a0SAndy Whitcroft			next;
683773647a0SAndy Whitcroft		}
684113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
685113f04a8SDaniel Walker			$sanitise_quote = '//';
686113f04a8SDaniel Walker
687113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
688113f04a8SDaniel Walker			$off++;
689113f04a8SDaniel Walker			next;
690113f04a8SDaniel Walker		}
691773647a0SAndy Whitcroft
692773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
693773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
694773647a0SAndy Whitcroft		    $c eq "\\") {
695773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
696773647a0SAndy Whitcroft			$off++;
697773647a0SAndy Whitcroft			next;
698773647a0SAndy Whitcroft		}
699773647a0SAndy Whitcroft		# Regular quotes.
700773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
701773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
702773647a0SAndy Whitcroft				$sanitise_quote = $c;
703773647a0SAndy Whitcroft
704773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
705773647a0SAndy Whitcroft				next;
706773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
707773647a0SAndy Whitcroft				$sanitise_quote = '';
70800df344fSAndy Whitcroft			}
70900df344fSAndy Whitcroft		}
710773647a0SAndy Whitcroft
711fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
712773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
713773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
714113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
715113f04a8SDaniel Walker			substr($res, $off, 1, $;);
716773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
717773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
71800df344fSAndy Whitcroft		} else {
719773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
72000df344fSAndy Whitcroft		}
721c2fdda0dSAndy Whitcroft	}
722c2fdda0dSAndy Whitcroft
723113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
724113f04a8SDaniel Walker		$sanitise_quote = '';
725113f04a8SDaniel Walker	}
726113f04a8SDaniel Walker
727c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
728c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
729c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
730c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
731c2fdda0dSAndy Whitcroft
732c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
733c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
734c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
735c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
736c2fdda0dSAndy Whitcroft	}
737c2fdda0dSAndy Whitcroft
73800df344fSAndy Whitcroft	return $res;
73900df344fSAndy Whitcroft}
74000df344fSAndy Whitcroft
741a6962d72SJoe Perchessub get_quoted_string {
742a6962d72SJoe Perches	my ($line, $rawline) = @_;
743a6962d72SJoe Perches
744a6962d72SJoe Perches	return "" if ($line !~ m/(\"[X]+\")/g);
745a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
746a6962d72SJoe Perches}
747a6962d72SJoe Perches
7488905a67cSAndy Whitcroftsub ctx_statement_block {
7498905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
7508905a67cSAndy Whitcroft	my $line = $linenr - 1;
7518905a67cSAndy Whitcroft	my $blk = '';
7528905a67cSAndy Whitcroft	my $soff = $off;
7538905a67cSAndy Whitcroft	my $coff = $off - 1;
754773647a0SAndy Whitcroft	my $coff_set = 0;
7558905a67cSAndy Whitcroft
75613214adfSAndy Whitcroft	my $loff = 0;
75713214adfSAndy Whitcroft
7588905a67cSAndy Whitcroft	my $type = '';
7598905a67cSAndy Whitcroft	my $level = 0;
760a2750645SAndy Whitcroft	my @stack = ();
761cf655043SAndy Whitcroft	my $p;
7628905a67cSAndy Whitcroft	my $c;
7638905a67cSAndy Whitcroft	my $len = 0;
76413214adfSAndy Whitcroft
76513214adfSAndy Whitcroft	my $remainder;
7668905a67cSAndy Whitcroft	while (1) {
767a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
768a2750645SAndy Whitcroft
769773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
7708905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
7718905a67cSAndy Whitcroft		# context.
7728905a67cSAndy Whitcroft		if ($off >= $len) {
7738905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
774dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
775c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
7768905a67cSAndy Whitcroft				$remain--;
77713214adfSAndy Whitcroft				$loff = $len;
778c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
7798905a67cSAndy Whitcroft				$len = length($blk);
7808905a67cSAndy Whitcroft				$line++;
7818905a67cSAndy Whitcroft				last;
7828905a67cSAndy Whitcroft			}
7838905a67cSAndy Whitcroft			# Bail if there is no further context.
7848905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
78513214adfSAndy Whitcroft			if ($off >= $len) {
7868905a67cSAndy Whitcroft				last;
7878905a67cSAndy Whitcroft			}
788f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
789f74bd194SAndy Whitcroft				$level++;
790f74bd194SAndy Whitcroft				$type = '#';
791f74bd194SAndy Whitcroft			}
7928905a67cSAndy Whitcroft		}
793cf655043SAndy Whitcroft		$p = $c;
7948905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
79513214adfSAndy Whitcroft		$remainder = substr($blk, $off);
7968905a67cSAndy Whitcroft
797773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
7984635f4fbSAndy Whitcroft
7994635f4fbSAndy Whitcroft		# Handle nested #if/#else.
8004635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
8014635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
8024635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
8034635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
8044635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
8054635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
8064635f4fbSAndy Whitcroft		}
8074635f4fbSAndy Whitcroft
8088905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
8098905a67cSAndy Whitcroft		# outermost level.
8108905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
8118905a67cSAndy Whitcroft			last;
8128905a67cSAndy Whitcroft		}
8138905a67cSAndy Whitcroft
81413214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
815773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
816773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
817773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
818773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
819773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
820773647a0SAndy Whitcroft			$coff_set = 1;
821773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
822773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
82313214adfSAndy Whitcroft		}
82413214adfSAndy Whitcroft
8258905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
8268905a67cSAndy Whitcroft			$level++;
8278905a67cSAndy Whitcroft			$type = '(';
8288905a67cSAndy Whitcroft		}
8298905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
8308905a67cSAndy Whitcroft			$level--;
8318905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
8328905a67cSAndy Whitcroft
8338905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
8348905a67cSAndy Whitcroft				$coff = $off;
835773647a0SAndy Whitcroft				$coff_set = 1;
836773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
8378905a67cSAndy Whitcroft			}
8388905a67cSAndy Whitcroft		}
8398905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
8408905a67cSAndy Whitcroft			$level++;
8418905a67cSAndy Whitcroft			$type = '{';
8428905a67cSAndy Whitcroft		}
8438905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
8448905a67cSAndy Whitcroft			$level--;
8458905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
8468905a67cSAndy Whitcroft
8478905a67cSAndy Whitcroft			if ($level == 0) {
848b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
849b998e001SPatrick Pannuto					$off++;
850b998e001SPatrick Pannuto				}
8518905a67cSAndy Whitcroft				last;
8528905a67cSAndy Whitcroft			}
8538905a67cSAndy Whitcroft		}
854f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
855f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
856f74bd194SAndy Whitcroft			$level--;
857f74bd194SAndy Whitcroft			$type = '';
858f74bd194SAndy Whitcroft			$off++;
859f74bd194SAndy Whitcroft			last;
860f74bd194SAndy Whitcroft		}
8618905a67cSAndy Whitcroft		$off++;
8628905a67cSAndy Whitcroft	}
863a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
86413214adfSAndy Whitcroft	if ($off == $len) {
865a3bb97a7SAndy Whitcroft		$loff = $len + 1;
86613214adfSAndy Whitcroft		$line++;
86713214adfSAndy Whitcroft		$remain--;
86813214adfSAndy Whitcroft	}
8698905a67cSAndy Whitcroft
8708905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
8718905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
8728905a67cSAndy Whitcroft
8738905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
8748905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
8758905a67cSAndy Whitcroft
876773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
87713214adfSAndy Whitcroft
87813214adfSAndy Whitcroft	return ($statement, $condition,
87913214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
88013214adfSAndy Whitcroft}
88113214adfSAndy Whitcroft
882cf655043SAndy Whitcroftsub statement_lines {
883cf655043SAndy Whitcroft	my ($stmt) = @_;
884cf655043SAndy Whitcroft
885cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
886cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
887cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
888cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
889cf655043SAndy Whitcroft
890cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
891cf655043SAndy Whitcroft
892cf655043SAndy Whitcroft	return $#stmt_lines + 2;
893cf655043SAndy Whitcroft}
894cf655043SAndy Whitcroft
895cf655043SAndy Whitcroftsub statement_rawlines {
896cf655043SAndy Whitcroft	my ($stmt) = @_;
897cf655043SAndy Whitcroft
898cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
899cf655043SAndy Whitcroft
900cf655043SAndy Whitcroft	return $#stmt_lines + 2;
901cf655043SAndy Whitcroft}
902cf655043SAndy Whitcroft
903cf655043SAndy Whitcroftsub statement_block_size {
904cf655043SAndy Whitcroft	my ($stmt) = @_;
905cf655043SAndy Whitcroft
906cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
907cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
908cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
909cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
910cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
911cf655043SAndy Whitcroft
912cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
913cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
914cf655043SAndy Whitcroft
915cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
916cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
917cf655043SAndy Whitcroft
918cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
919cf655043SAndy Whitcroft		return $stmt_lines;
920cf655043SAndy Whitcroft	} else {
921cf655043SAndy Whitcroft		return $stmt_statements;
922cf655043SAndy Whitcroft	}
923cf655043SAndy Whitcroft}
924cf655043SAndy Whitcroft
92513214adfSAndy Whitcroftsub ctx_statement_full {
92613214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
92713214adfSAndy Whitcroft	my ($statement, $condition, $level);
92813214adfSAndy Whitcroft
92913214adfSAndy Whitcroft	my (@chunks);
93013214adfSAndy Whitcroft
931cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
93213214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
93313214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
934773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
93513214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
936cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
937cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
938cf655043SAndy Whitcroft	}
939cf655043SAndy Whitcroft
940cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
941cf655043SAndy Whitcroft	# could continue the statement.
942cf655043SAndy Whitcroft	for (;;) {
94313214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
94413214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
945cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
946773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
947cf655043SAndy Whitcroft		#print "C: push\n";
948cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
94913214adfSAndy Whitcroft	}
95013214adfSAndy Whitcroft
95113214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
9528905a67cSAndy Whitcroft}
9538905a67cSAndy Whitcroft
9544a0df2efSAndy Whitcroftsub ctx_block_get {
955f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
9564a0df2efSAndy Whitcroft	my $line;
9574a0df2efSAndy Whitcroft	my $start = $linenr - 1;
9584a0df2efSAndy Whitcroft	my $blk = '';
9594a0df2efSAndy Whitcroft	my @o;
9604a0df2efSAndy Whitcroft	my @c;
9614a0df2efSAndy Whitcroft	my @res = ();
9624a0df2efSAndy Whitcroft
963f0a594c1SAndy Whitcroft	my $level = 0;
9644635f4fbSAndy Whitcroft	my @stack = ($level);
96500df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
96600df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
96700df344fSAndy Whitcroft		$remain--;
96800df344fSAndy Whitcroft
96900df344fSAndy Whitcroft		$blk .= $rawlines[$line];
9704635f4fbSAndy Whitcroft
9714635f4fbSAndy Whitcroft		# Handle nested #if/#else.
97201464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
9734635f4fbSAndy Whitcroft			push(@stack, $level);
97401464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
9754635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
97601464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
9774635f4fbSAndy Whitcroft			$level = pop(@stack);
9784635f4fbSAndy Whitcroft		}
9794635f4fbSAndy Whitcroft
98001464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
981f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
982f0a594c1SAndy Whitcroft			if ($off > 0) {
983f0a594c1SAndy Whitcroft				$off--;
984f0a594c1SAndy Whitcroft				next;
985f0a594c1SAndy Whitcroft			}
9864a0df2efSAndy Whitcroft
987f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
988f0a594c1SAndy Whitcroft				$level--;
989f0a594c1SAndy Whitcroft				last if ($level == 0);
990f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
991f0a594c1SAndy Whitcroft				$level++;
992f0a594c1SAndy Whitcroft			}
993f0a594c1SAndy Whitcroft		}
9944a0df2efSAndy Whitcroft
995f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
99600df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
9974a0df2efSAndy Whitcroft		}
9984a0df2efSAndy Whitcroft
999f0a594c1SAndy Whitcroft		last if ($level == 0);
10004a0df2efSAndy Whitcroft	}
10014a0df2efSAndy Whitcroft
1002f0a594c1SAndy Whitcroft	return ($level, @res);
10034a0df2efSAndy Whitcroft}
10044a0df2efSAndy Whitcroftsub ctx_block_outer {
10054a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
10064a0df2efSAndy Whitcroft
1007f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1008f0a594c1SAndy Whitcroft	return @r;
10094a0df2efSAndy Whitcroft}
10104a0df2efSAndy Whitcroftsub ctx_block {
10114a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
10124a0df2efSAndy Whitcroft
1013f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1014f0a594c1SAndy Whitcroft	return @r;
1015653d4876SAndy Whitcroft}
1016653d4876SAndy Whitcroftsub ctx_statement {
1017f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1018f0a594c1SAndy Whitcroft
1019f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1020f0a594c1SAndy Whitcroft	return @r;
1021f0a594c1SAndy Whitcroft}
1022f0a594c1SAndy Whitcroftsub ctx_block_level {
1023653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1024653d4876SAndy Whitcroft
1025f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
10264a0df2efSAndy Whitcroft}
10279c0ca6f9SAndy Whitcroftsub ctx_statement_level {
10289c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
10299c0ca6f9SAndy Whitcroft
10309c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
10319c0ca6f9SAndy Whitcroft}
10324a0df2efSAndy Whitcroft
10334a0df2efSAndy Whitcroftsub ctx_locate_comment {
10344a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
10354a0df2efSAndy Whitcroft
10364a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1037beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
10384a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
10394a0df2efSAndy Whitcroft
10404a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
10414a0df2efSAndy Whitcroft	# comment.
10424a0df2efSAndy Whitcroft	my $in_comment = 0;
10434a0df2efSAndy Whitcroft	$current_comment = '';
10444a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
104500df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
104600df344fSAndy Whitcroft		#warn "           $line\n";
10474a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
10484a0df2efSAndy Whitcroft			$in_comment = 1;
10494a0df2efSAndy Whitcroft		}
10504a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
10514a0df2efSAndy Whitcroft			$in_comment = 1;
10524a0df2efSAndy Whitcroft		}
10534a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
10544a0df2efSAndy Whitcroft			$current_comment = '';
10554a0df2efSAndy Whitcroft		}
10564a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
10574a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
10584a0df2efSAndy Whitcroft			$in_comment = 0;
10594a0df2efSAndy Whitcroft		}
10604a0df2efSAndy Whitcroft	}
10614a0df2efSAndy Whitcroft
10624a0df2efSAndy Whitcroft	chomp($current_comment);
10634a0df2efSAndy Whitcroft	return($current_comment);
10644a0df2efSAndy Whitcroft}
10654a0df2efSAndy Whitcroftsub ctx_has_comment {
10664a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
10674a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
10684a0df2efSAndy Whitcroft
106900df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
10704a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
10714a0df2efSAndy Whitcroft
10724a0df2efSAndy Whitcroft	return ($cmt ne '');
10734a0df2efSAndy Whitcroft}
10744a0df2efSAndy Whitcroft
10754d001e4dSAndy Whitcroftsub raw_line {
10764d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
10774d001e4dSAndy Whitcroft
10784d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
10794d001e4dSAndy Whitcroft	$cnt++;
10804d001e4dSAndy Whitcroft
10814d001e4dSAndy Whitcroft	my $line;
10824d001e4dSAndy Whitcroft	while ($cnt) {
10834d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
10844d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
10854d001e4dSAndy Whitcroft		$cnt--;
10864d001e4dSAndy Whitcroft	}
10874d001e4dSAndy Whitcroft
10884d001e4dSAndy Whitcroft	return $line;
10894d001e4dSAndy Whitcroft}
10904d001e4dSAndy Whitcroft
10910a920b5bSAndy Whitcroftsub cat_vet {
10920a920b5bSAndy Whitcroft	my ($vet) = @_;
10939c0ca6f9SAndy Whitcroft	my ($res, $coded);
10940a920b5bSAndy Whitcroft
10959c0ca6f9SAndy Whitcroft	$res = '';
10966c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
10976c72ffaaSAndy Whitcroft		$res .= $1;
10986c72ffaaSAndy Whitcroft		if ($2 ne '') {
10999c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
11006c72ffaaSAndy Whitcroft			$res .= $coded;
11016c72ffaaSAndy Whitcroft		}
11029c0ca6f9SAndy Whitcroft	}
11039c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
11040a920b5bSAndy Whitcroft
11059c0ca6f9SAndy Whitcroft	return $res;
11060a920b5bSAndy Whitcroft}
11070a920b5bSAndy Whitcroft
1108c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1109cf655043SAndy Whitcroftmy $av_pending;
1110c2fdda0dSAndy Whitcroftmy @av_paren_type;
11111f65f947SAndy Whitcroftmy $av_pend_colon;
1112c2fdda0dSAndy Whitcroft
1113c2fdda0dSAndy Whitcroftsub annotate_reset {
1114c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1115cf655043SAndy Whitcroft	$av_pending = '_';
1116cf655043SAndy Whitcroft	@av_paren_type = ('E');
11171f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1118c2fdda0dSAndy Whitcroft}
1119c2fdda0dSAndy Whitcroft
11206c72ffaaSAndy Whitcroftsub annotate_values {
11216c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
11226c72ffaaSAndy Whitcroft
11236c72ffaaSAndy Whitcroft	my $res;
11241f65f947SAndy Whitcroft	my $var = '_' x length($stream);
11256c72ffaaSAndy Whitcroft	my $cur = $stream;
11266c72ffaaSAndy Whitcroft
1127c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
11286c72ffaaSAndy Whitcroft
11296c72ffaaSAndy Whitcroft	while (length($cur)) {
1130773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1131cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1132171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
11336c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1134c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1135c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1136cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1137c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
11386c72ffaaSAndy Whitcroft			}
11396c72ffaaSAndy Whitcroft
1140c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
11419446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
11429446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1143addcdceaSAndy Whitcroft			$type = 'c';
11449446ef56SAndy Whitcroft
1145e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1146c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
11476c72ffaaSAndy Whitcroft			$type = 'T';
11486c72ffaaSAndy Whitcroft
1149389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1150389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1151389a2fe5SAndy Whitcroft			$type = 'T';
1152389a2fe5SAndy Whitcroft
1153c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1154171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1155c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1156171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1157171ae1a4SAndy Whitcroft			if ($2 ne '') {
1158cf655043SAndy Whitcroft				$av_pending = 'N';
1159171ae1a4SAndy Whitcroft			}
1160171ae1a4SAndy Whitcroft			$type = 'E';
1161171ae1a4SAndy Whitcroft
1162c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1163171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1164171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1165171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
11666c72ffaaSAndy Whitcroft
1167c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1168cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1169c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1170cf655043SAndy Whitcroft
1171cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1172cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1173171ae1a4SAndy Whitcroft			$type = 'E';
1174cf655043SAndy Whitcroft
1175c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1176cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1177cf655043SAndy Whitcroft			$av_preprocessor = 1;
1178cf655043SAndy Whitcroft
1179cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1180cf655043SAndy Whitcroft
1181171ae1a4SAndy Whitcroft			$type = 'E';
1182cf655043SAndy Whitcroft
1183c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1184cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1185cf655043SAndy Whitcroft
1186cf655043SAndy Whitcroft			$av_preprocessor = 1;
1187cf655043SAndy Whitcroft
1188cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1189cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1190cf655043SAndy Whitcroft			pop(@av_paren_type);
1191cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1192171ae1a4SAndy Whitcroft			$type = 'E';
11936c72ffaaSAndy Whitcroft
11946c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1195c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
11966c72ffaaSAndy Whitcroft
1197171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1198171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1199171ae1a4SAndy Whitcroft			$av_pending = $type;
1200171ae1a4SAndy Whitcroft			$type = 'N';
1201171ae1a4SAndy Whitcroft
12026c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1203c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
12046c72ffaaSAndy Whitcroft			if (defined $2) {
1205cf655043SAndy Whitcroft				$av_pending = 'V';
12066c72ffaaSAndy Whitcroft			}
12076c72ffaaSAndy Whitcroft			$type = 'N';
12086c72ffaaSAndy Whitcroft
120914b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1210c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
121114b111c1SAndy Whitcroft			$av_pending = 'E';
12126c72ffaaSAndy Whitcroft			$type = 'N';
12136c72ffaaSAndy Whitcroft
12141f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
12151f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
12161f65f947SAndy Whitcroft			$av_pend_colon = 'C';
12171f65f947SAndy Whitcroft			$type = 'N';
12181f65f947SAndy Whitcroft
121914b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1220c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
12216c72ffaaSAndy Whitcroft			$type = 'N';
12226c72ffaaSAndy Whitcroft
12236c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1224c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1225cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1226cf655043SAndy Whitcroft			$av_pending = '_';
12276c72ffaaSAndy Whitcroft			$type = 'N';
12286c72ffaaSAndy Whitcroft
12296c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1230cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1231cf655043SAndy Whitcroft			if ($new_type ne '_') {
1232cf655043SAndy Whitcroft				$type = $new_type;
1233c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1234c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
12356c72ffaaSAndy Whitcroft			} else {
1236c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
12376c72ffaaSAndy Whitcroft			}
12386c72ffaaSAndy Whitcroft
1239c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1240c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1241c8cb2ca3SAndy Whitcroft			$type = 'V';
1242cf655043SAndy Whitcroft			$av_pending = 'V';
12436c72ffaaSAndy Whitcroft
12448e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
12458e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
12461f65f947SAndy Whitcroft				$av_pend_colon = 'B';
12478e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
12488e761b04SAndy Whitcroft				$av_pend_colon = 'L';
12491f65f947SAndy Whitcroft			}
12501f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
12511f65f947SAndy Whitcroft			$type = 'V';
12521f65f947SAndy Whitcroft
12536c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1254c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
12556c72ffaaSAndy Whitcroft			$type = 'V';
12566c72ffaaSAndy Whitcroft
12576c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1258c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
12596c72ffaaSAndy Whitcroft			$type = 'N';
12606c72ffaaSAndy Whitcroft
1261cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1262c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
126313214adfSAndy Whitcroft			$type = 'E';
12641f65f947SAndy Whitcroft			$av_pend_colon = 'O';
126513214adfSAndy Whitcroft
12668e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
12678e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
12688e761b04SAndy Whitcroft			$type = 'C';
12698e761b04SAndy Whitcroft
12701f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
12711f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
12721f65f947SAndy Whitcroft			$type = 'N';
12731f65f947SAndy Whitcroft
12741f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
12751f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
12761f65f947SAndy Whitcroft
12771f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
12781f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
12791f65f947SAndy Whitcroft				$type = 'E';
12801f65f947SAndy Whitcroft			} else {
12811f65f947SAndy Whitcroft				$type = 'N';
12821f65f947SAndy Whitcroft			}
12831f65f947SAndy Whitcroft			$av_pend_colon = 'O';
12841f65f947SAndy Whitcroft
12858e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
128613214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
12876c72ffaaSAndy Whitcroft			$type = 'N';
12886c72ffaaSAndy Whitcroft
12890d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
129074048ed8SAndy Whitcroft			my $variant;
129174048ed8SAndy Whitcroft
129274048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
129374048ed8SAndy Whitcroft			if ($type eq 'V') {
129474048ed8SAndy Whitcroft				$variant = 'B';
129574048ed8SAndy Whitcroft			} else {
129674048ed8SAndy Whitcroft				$variant = 'U';
129774048ed8SAndy Whitcroft			}
129874048ed8SAndy Whitcroft
129974048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
130074048ed8SAndy Whitcroft			$type = 'N';
130174048ed8SAndy Whitcroft
13026c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1303c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
13046c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
13056c72ffaaSAndy Whitcroft				$type = 'N';
13066c72ffaaSAndy Whitcroft			}
13076c72ffaaSAndy Whitcroft
13086c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1309c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
13106c72ffaaSAndy Whitcroft		}
13116c72ffaaSAndy Whitcroft		if (defined $1) {
13126c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
13136c72ffaaSAndy Whitcroft			$res .= $type x length($1);
13146c72ffaaSAndy Whitcroft		}
13156c72ffaaSAndy Whitcroft	}
13166c72ffaaSAndy Whitcroft
13171f65f947SAndy Whitcroft	return ($res, $var);
13186c72ffaaSAndy Whitcroft}
13196c72ffaaSAndy Whitcroft
13208905a67cSAndy Whitcroftsub possible {
132113214adfSAndy Whitcroft	my ($possible, $line) = @_;
13229a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
13230776e594SAndy Whitcroft		^(?:
13240776e594SAndy Whitcroft			$Modifier|
13250776e594SAndy Whitcroft			$Storage|
13260776e594SAndy Whitcroft			$Type|
13279a974fdbSAndy Whitcroft			DEFINE_\S+
13289a974fdbSAndy Whitcroft		)$|
13299a974fdbSAndy Whitcroft		^(?:
13300776e594SAndy Whitcroft			goto|
13310776e594SAndy Whitcroft			return|
13320776e594SAndy Whitcroft			case|
13330776e594SAndy Whitcroft			else|
13340776e594SAndy Whitcroft			asm|__asm__|
133589a88353SAndy Whitcroft			do|
133689a88353SAndy Whitcroft			\#|
133789a88353SAndy Whitcroft			\#\#|
13389a974fdbSAndy Whitcroft		)(?:\s|$)|
13390776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
13409a974fdbSAndy Whitcroft	    )}x;
13419a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
13429a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1343c45dcabdSAndy Whitcroft		# Check for modifiers.
1344c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1345c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1346c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1347c45dcabdSAndy Whitcroft
1348c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1349c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1350d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
13519a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1352d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1353d2506586SAndy Whitcroft					push(@modifierList, $modifier);
1354d2506586SAndy Whitcroft				}
13559a974fdbSAndy Whitcroft			}
1356c45dcabdSAndy Whitcroft
1357c45dcabdSAndy Whitcroft		} else {
135813214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
13598905a67cSAndy Whitcroft			push(@typeList, $possible);
1360c45dcabdSAndy Whitcroft		}
13618905a67cSAndy Whitcroft		build_types();
13620776e594SAndy Whitcroft	} else {
13630776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
13648905a67cSAndy Whitcroft	}
13658905a67cSAndy Whitcroft}
13668905a67cSAndy Whitcroft
13676c72ffaaSAndy Whitcroftmy $prefix = '';
13686c72ffaaSAndy Whitcroft
1369000d1cc1SJoe Perchessub show_type {
1370000d1cc1SJoe Perches       return !defined $ignore_type{$_[0]};
1371000d1cc1SJoe Perches}
1372000d1cc1SJoe Perches
1373f0a594c1SAndy Whitcroftsub report {
1374000d1cc1SJoe Perches	if (!show_type($_[1]) ||
1375000d1cc1SJoe Perches	    (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) {
1376773647a0SAndy Whitcroft		return 0;
1377773647a0SAndy Whitcroft	}
1378000d1cc1SJoe Perches	my $line;
1379000d1cc1SJoe Perches	if ($show_types) {
1380000d1cc1SJoe Perches		$line = "$prefix$_[0]:$_[1]: $_[2]\n";
1381000d1cc1SJoe Perches	} else {
1382000d1cc1SJoe Perches		$line = "$prefix$_[0]: $_[2]\n";
1383000d1cc1SJoe Perches	}
13848905a67cSAndy Whitcroft	$line = (split('\n', $line))[0] . "\n" if ($terse);
13858905a67cSAndy Whitcroft
138613214adfSAndy Whitcroft	push(our @report, $line);
1387773647a0SAndy Whitcroft
1388773647a0SAndy Whitcroft	return 1;
1389f0a594c1SAndy Whitcroft}
1390f0a594c1SAndy Whitcroftsub report_dump {
139113214adfSAndy Whitcroft	our @report;
1392f0a594c1SAndy Whitcroft}
1393000d1cc1SJoe Perches
1394de7d4f0eSAndy Whitcroftsub ERROR {
1395000d1cc1SJoe Perches	if (report("ERROR", $_[0], $_[1])) {
1396de7d4f0eSAndy Whitcroft		our $clean = 0;
13976c72ffaaSAndy Whitcroft		our $cnt_error++;
13983705ce5bSJoe Perches		return 1;
1399de7d4f0eSAndy Whitcroft	}
14003705ce5bSJoe Perches	return 0;
1401773647a0SAndy Whitcroft}
1402de7d4f0eSAndy Whitcroftsub WARN {
1403000d1cc1SJoe Perches	if (report("WARNING", $_[0], $_[1])) {
1404de7d4f0eSAndy Whitcroft		our $clean = 0;
14056c72ffaaSAndy Whitcroft		our $cnt_warn++;
14063705ce5bSJoe Perches		return 1;
1407de7d4f0eSAndy Whitcroft	}
14083705ce5bSJoe Perches	return 0;
1409773647a0SAndy Whitcroft}
1410de7d4f0eSAndy Whitcroftsub CHK {
1411000d1cc1SJoe Perches	if ($check && report("CHECK", $_[0], $_[1])) {
1412de7d4f0eSAndy Whitcroft		our $clean = 0;
14136c72ffaaSAndy Whitcroft		our $cnt_chk++;
14143705ce5bSJoe Perches		return 1;
14156c72ffaaSAndy Whitcroft	}
14163705ce5bSJoe Perches	return 0;
1417de7d4f0eSAndy Whitcroft}
1418de7d4f0eSAndy Whitcroft
14196ecd9674SAndy Whitcroftsub check_absolute_file {
14206ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
14216ecd9674SAndy Whitcroft	my $file = $absolute;
14226ecd9674SAndy Whitcroft
14236ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
14246ecd9674SAndy Whitcroft
14256ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
14266ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
14276ecd9674SAndy Whitcroft		if (-f "$root/$file") {
14286ecd9674SAndy Whitcroft			##print "file<$file>\n";
14296ecd9674SAndy Whitcroft			last;
14306ecd9674SAndy Whitcroft		}
14316ecd9674SAndy Whitcroft	}
14326ecd9674SAndy Whitcroft	if (! -f _)  {
14336ecd9674SAndy Whitcroft		return 0;
14346ecd9674SAndy Whitcroft	}
14356ecd9674SAndy Whitcroft
14366ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
14376ecd9674SAndy Whitcroft	my $prefix = $absolute;
14386ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
14396ecd9674SAndy Whitcroft
14406ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
14416ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
1442000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
1443000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
14446ecd9674SAndy Whitcroft	}
14456ecd9674SAndy Whitcroft}
14466ecd9674SAndy Whitcroft
14473705ce5bSJoe Perchessub trim {
14483705ce5bSJoe Perches	my ($string) = @_;
14493705ce5bSJoe Perches
14503705ce5bSJoe Perches	$string =~ s/(^\s+|\s+$)//g;
14513705ce5bSJoe Perches
14523705ce5bSJoe Perches	return $string;
14533705ce5bSJoe Perches}
14543705ce5bSJoe Perches
14553705ce5bSJoe Perchessub tabify {
14563705ce5bSJoe Perches	my ($leading) = @_;
14573705ce5bSJoe Perches
14583705ce5bSJoe Perches	my $source_indent = 8;
14593705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
14603705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
14613705ce5bSJoe Perches
14623705ce5bSJoe Perches	#convert leading spaces to tabs
14633705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
14643705ce5bSJoe Perches	#Remove spaces before a tab
14653705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
14663705ce5bSJoe Perches
14673705ce5bSJoe Perches	return "$leading";
14683705ce5bSJoe Perches}
14693705ce5bSJoe Perches
1470d1fe9c09SJoe Perchessub pos_last_openparen {
1471d1fe9c09SJoe Perches	my ($line) = @_;
1472d1fe9c09SJoe Perches
1473d1fe9c09SJoe Perches	my $pos = 0;
1474d1fe9c09SJoe Perches
1475d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
1476d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
1477d1fe9c09SJoe Perches
1478d1fe9c09SJoe Perches	my $last_openparen = 0;
1479d1fe9c09SJoe Perches
1480d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
1481d1fe9c09SJoe Perches		return -1;
1482d1fe9c09SJoe Perches	}
1483d1fe9c09SJoe Perches
1484d1fe9c09SJoe Perches	my $len = length($line);
1485d1fe9c09SJoe Perches
1486d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
1487d1fe9c09SJoe Perches		my $string = substr($line, $pos);
1488d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
1489d1fe9c09SJoe Perches			$pos += length($1) - 1;
1490d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
1491d1fe9c09SJoe Perches			$last_openparen = $pos;
1492d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
1493d1fe9c09SJoe Perches			last;
1494d1fe9c09SJoe Perches		}
1495d1fe9c09SJoe Perches	}
1496d1fe9c09SJoe Perches
1497d1fe9c09SJoe Perches	return $last_openparen + 1;
1498d1fe9c09SJoe Perches}
1499d1fe9c09SJoe Perches
15000a920b5bSAndy Whitcroftsub process {
15010a920b5bSAndy Whitcroft	my $filename = shift;
15020a920b5bSAndy Whitcroft
15030a920b5bSAndy Whitcroft	my $linenr=0;
15040a920b5bSAndy Whitcroft	my $prevline="";
1505c2fdda0dSAndy Whitcroft	my $prevrawline="";
15060a920b5bSAndy Whitcroft	my $stashline="";
1507c2fdda0dSAndy Whitcroft	my $stashrawline="";
15080a920b5bSAndy Whitcroft
15094a0df2efSAndy Whitcroft	my $length;
15100a920b5bSAndy Whitcroft	my $indent;
15110a920b5bSAndy Whitcroft	my $previndent=0;
15120a920b5bSAndy Whitcroft	my $stashindent=0;
15130a920b5bSAndy Whitcroft
1514de7d4f0eSAndy Whitcroft	our $clean = 1;
15150a920b5bSAndy Whitcroft	my $signoff = 0;
15160a920b5bSAndy Whitcroft	my $is_patch = 0;
15170a920b5bSAndy Whitcroft
151815662b3eSJoe Perches	my $in_header_lines = 1;
151915662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
152015662b3eSJoe Perches
1521fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
1522fa64205dSPasi Savanainen
152313214adfSAndy Whitcroft	our @report = ();
15246c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
15256c72ffaaSAndy Whitcroft	our $cnt_error = 0;
15266c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
15276c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
15286c72ffaaSAndy Whitcroft
15290a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
15300a920b5bSAndy Whitcroft	my $realfile = '';
15310a920b5bSAndy Whitcroft	my $realline = 0;
15320a920b5bSAndy Whitcroft	my $realcnt = 0;
15330a920b5bSAndy Whitcroft	my $here = '';
15340a920b5bSAndy Whitcroft	my $in_comment = 0;
1535c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
15360a920b5bSAndy Whitcroft	my $first_line = 0;
15371e855726SWolfram Sang	my $p1_prefix = '';
15380a920b5bSAndy Whitcroft
153913214adfSAndy Whitcroft	my $prev_values = 'E';
154013214adfSAndy Whitcroft
154113214adfSAndy Whitcroft	# suppression flags
1542773647a0SAndy Whitcroft	my %suppress_ifbraces;
1543170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
15442b474a1aSAndy Whitcroft	my %suppress_export;
15453e469cdcSAndy Whitcroft	my $suppress_statement = 0;
1546653d4876SAndy Whitcroft
1547323c1260SJoe Perches
1548c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
1549de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
1550c2fdda0dSAndy Whitcroft	#
1551de7d4f0eSAndy Whitcroft	my @setup_docs = ();
1552de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
1553773647a0SAndy Whitcroft
1554773647a0SAndy Whitcroft	sanitise_line_reset();
1555c2fdda0dSAndy Whitcroft	my $line;
1556c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
1557773647a0SAndy Whitcroft		$linenr++;
1558773647a0SAndy Whitcroft		$line = $rawline;
1559c2fdda0dSAndy Whitcroft
15603705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
15613705ce5bSJoe Perches
1562773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
1563de7d4f0eSAndy Whitcroft			$setup_docs = 0;
1564de7d4f0eSAndy Whitcroft			if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1565de7d4f0eSAndy Whitcroft				$setup_docs = 1;
1566de7d4f0eSAndy Whitcroft			}
1567773647a0SAndy Whitcroft			#next;
1568de7d4f0eSAndy Whitcroft		}
1569773647a0SAndy Whitcroft		if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1570773647a0SAndy Whitcroft			$realline=$1-1;
1571773647a0SAndy Whitcroft			if (defined $2) {
1572773647a0SAndy Whitcroft				$realcnt=$3+1;
1573773647a0SAndy Whitcroft			} else {
1574773647a0SAndy Whitcroft				$realcnt=1+1;
1575773647a0SAndy Whitcroft			}
1576c45dcabdSAndy Whitcroft			$in_comment = 0;
1577773647a0SAndy Whitcroft
1578773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
1579773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
1580773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
1581773647a0SAndy Whitcroft			# at context start.
1582773647a0SAndy Whitcroft			my $edge;
158301fa9147SAndy Whitcroft			my $cnt = $realcnt;
158401fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
158501fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
158601fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
158701fa9147SAndy Whitcroft				$cnt--;
158801fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
1589721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
1590fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1591fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1592fae17daeSAndy Whitcroft					($edge) = $1;
1593fae17daeSAndy Whitcroft					last;
1594fae17daeSAndy Whitcroft				}
1595773647a0SAndy Whitcroft			}
1596773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
1597773647a0SAndy Whitcroft				$in_comment = 1;
1598773647a0SAndy Whitcroft			}
1599773647a0SAndy Whitcroft
1600773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
1601773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
1602773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
1603773647a0SAndy Whitcroft			if (!defined $edge &&
160483242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1605773647a0SAndy Whitcroft			{
1606773647a0SAndy Whitcroft				$in_comment = 1;
1607773647a0SAndy Whitcroft			}
1608773647a0SAndy Whitcroft
1609773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1610773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
1611773647a0SAndy Whitcroft
1612171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1613773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
1614171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
1615773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
1616773647a0SAndy Whitcroft		}
1617773647a0SAndy Whitcroft		push(@lines, $line);
1618773647a0SAndy Whitcroft
1619773647a0SAndy Whitcroft		if ($realcnt > 1) {
1620773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
1621773647a0SAndy Whitcroft		} else {
1622773647a0SAndy Whitcroft			$realcnt = 0;
1623773647a0SAndy Whitcroft		}
1624773647a0SAndy Whitcroft
1625773647a0SAndy Whitcroft		#print "==>$rawline\n";
1626773647a0SAndy Whitcroft		#print "-->$line\n";
1627de7d4f0eSAndy Whitcroft
1628de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
1629de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
1630de7d4f0eSAndy Whitcroft		}
1631de7d4f0eSAndy Whitcroft	}
1632de7d4f0eSAndy Whitcroft
16336c72ffaaSAndy Whitcroft	$prefix = '';
16346c72ffaaSAndy Whitcroft
1635773647a0SAndy Whitcroft	$realcnt = 0;
1636773647a0SAndy Whitcroft	$linenr = 0;
16370a920b5bSAndy Whitcroft	foreach my $line (@lines) {
16380a920b5bSAndy Whitcroft		$linenr++;
16390a920b5bSAndy Whitcroft
1640c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
16416c72ffaaSAndy Whitcroft
16420a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
16436c72ffaaSAndy Whitcroft		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
16440a920b5bSAndy Whitcroft			$is_patch = 1;
16454a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
16460a920b5bSAndy Whitcroft			$realline=$1-1;
16470a920b5bSAndy Whitcroft			if (defined $2) {
16480a920b5bSAndy Whitcroft				$realcnt=$3+1;
16490a920b5bSAndy Whitcroft			} else {
16500a920b5bSAndy Whitcroft				$realcnt=1+1;
16510a920b5bSAndy Whitcroft			}
1652c2fdda0dSAndy Whitcroft			annotate_reset();
165313214adfSAndy Whitcroft			$prev_values = 'E';
165413214adfSAndy Whitcroft
1655773647a0SAndy Whitcroft			%suppress_ifbraces = ();
1656170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
16572b474a1aSAndy Whitcroft			%suppress_export = ();
16583e469cdcSAndy Whitcroft			$suppress_statement = 0;
16590a920b5bSAndy Whitcroft			next;
16600a920b5bSAndy Whitcroft
16614a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
16624a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
16634a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
1664773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
16650a920b5bSAndy Whitcroft			$realline++;
1666d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
16670a920b5bSAndy Whitcroft
16684a0df2efSAndy Whitcroft			# Measure the line length and indent.
1669c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
16700a920b5bSAndy Whitcroft
16710a920b5bSAndy Whitcroft			# Track the previous line.
16720a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
16730a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
1674c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1675c2fdda0dSAndy Whitcroft
1676773647a0SAndy Whitcroft			#warn "line<$line>\n";
16776c72ffaaSAndy Whitcroft
1678d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
1679d8aaf121SAndy Whitcroft			$realcnt--;
16800a920b5bSAndy Whitcroft		}
16810a920b5bSAndy Whitcroft
1682cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
1683cc77cdcaSAndy Whitcroft
16840a920b5bSAndy Whitcroft#make up the handle for any error we report on this line
1685773647a0SAndy Whitcroft		$prefix = "$filename:$realline: " if ($emacs && $file);
1686773647a0SAndy Whitcroft		$prefix = "$filename:$linenr: " if ($emacs && !$file);
1687773647a0SAndy Whitcroft
16886c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
16896c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
1690773647a0SAndy Whitcroft
1691773647a0SAndy Whitcroft		# extract the filename as it passes
16923bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
16933bf9a009SRabin Vincent			$realfile = $1;
16943bf9a009SRabin Vincent			$realfile =~ s@^([^/]*)/@@;
1695270c49a0SJoe Perches			$in_commit_log = 0;
16963bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1697773647a0SAndy Whitcroft			$realfile = $1;
16981e855726SWolfram Sang			$realfile =~ s@^([^/]*)/@@;
1699270c49a0SJoe Perches			$in_commit_log = 0;
17001e855726SWolfram Sang
17011e855726SWolfram Sang			$p1_prefix = $1;
1702e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
1703e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
1704000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
1705000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
17061e855726SWolfram Sang			}
1707773647a0SAndy Whitcroft
1708c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
1709000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
1710000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1711773647a0SAndy Whitcroft			}
1712773647a0SAndy Whitcroft			next;
1713773647a0SAndy Whitcroft		}
1714773647a0SAndy Whitcroft
1715389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
17160a920b5bSAndy Whitcroft
1717c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
1718c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
1719c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
17200a920b5bSAndy Whitcroft
17216c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
17226c72ffaaSAndy Whitcroft
17233bf9a009SRabin Vincent# Check for incorrect file permissions
17243bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
17253bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
172604db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
172704db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
1728000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
1729000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
17303bf9a009SRabin Vincent			}
17313bf9a009SRabin Vincent		}
17323bf9a009SRabin Vincent
173320112475SJoe Perches# Check the patch for a signoff:
1734d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
17354a0df2efSAndy Whitcroft			$signoff++;
173615662b3eSJoe Perches			$in_commit_log = 0;
17370a920b5bSAndy Whitcroft		}
173820112475SJoe Perches
173920112475SJoe Perches# Check signature styles
1740270c49a0SJoe Perches		if (!$in_header_lines &&
1741ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
174220112475SJoe Perches			my $space_before = $1;
174320112475SJoe Perches			my $sign_off = $2;
174420112475SJoe Perches			my $space_after = $3;
174520112475SJoe Perches			my $email = $4;
174620112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
174720112475SJoe Perches
1748ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
1749ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
1750ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
1751ce0338dfSJoe Perches			}
175220112475SJoe Perches			if (defined $space_before && $space_before ne "") {
17533705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17543705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
17553705ce5bSJoe Perches				    $fix) {
17563705ce5bSJoe Perches					$fixed[$linenr - 1] =
17573705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17583705ce5bSJoe Perches				}
175920112475SJoe Perches			}
176020112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
17613705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17623705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
17633705ce5bSJoe Perches				    $fix) {
17643705ce5bSJoe Perches					$fixed[$linenr - 1] =
17653705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17663705ce5bSJoe Perches				}
17673705ce5bSJoe Perches
176820112475SJoe Perches			}
176920112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
17703705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
17713705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
17723705ce5bSJoe Perches				    $fix) {
17733705ce5bSJoe Perches					$fixed[$linenr - 1] =
17743705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
17753705ce5bSJoe Perches				}
177620112475SJoe Perches			}
177720112475SJoe Perches
177820112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
177920112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
178020112475SJoe Perches			if ($suggested_email eq "") {
1781000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
1782000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
178320112475SJoe Perches			} else {
178420112475SJoe Perches				my $dequoted = $suggested_email;
178520112475SJoe Perches				$dequoted =~ s/^"//;
178620112475SJoe Perches				$dequoted =~ s/" </ </;
178720112475SJoe Perches				# Don't force email to have quotes
178820112475SJoe Perches				# Allow just an angle bracketed address
178920112475SJoe Perches				if ("$dequoted$comment" ne $email &&
179020112475SJoe Perches				    "<$email_address>$comment" ne $email &&
179120112475SJoe Perches				    "$suggested_email$comment" ne $email) {
1792000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
1793000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
179420112475SJoe Perches				}
17950a920b5bSAndy Whitcroft			}
17960a920b5bSAndy Whitcroft		}
17970a920b5bSAndy Whitcroft
179800df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
17998905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1800000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
1801000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
18026c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
1803de7d4f0eSAndy Whitcroft		}
1804de7d4f0eSAndy Whitcroft
18056ecd9674SAndy Whitcroft# Check for absolute kernel paths.
18066ecd9674SAndy Whitcroft		if ($tree) {
18076ecd9674SAndy Whitcroft			while ($line =~ m{(?:^|\s)(/\S*)}g) {
18086ecd9674SAndy Whitcroft				my $file = $1;
18096ecd9674SAndy Whitcroft
18106ecd9674SAndy Whitcroft				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
18116ecd9674SAndy Whitcroft				    check_absolute_file($1, $herecurr)) {
18126ecd9674SAndy Whitcroft					#
18136ecd9674SAndy Whitcroft				} else {
18146ecd9674SAndy Whitcroft					check_absolute_file($file, $herecurr);
18156ecd9674SAndy Whitcroft				}
18166ecd9674SAndy Whitcroft			}
18176ecd9674SAndy Whitcroft		}
18186ecd9674SAndy Whitcroft
1819de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1820de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1821171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
1822171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1823171ae1a4SAndy Whitcroft
1824171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
1825171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1826171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
1827171ae1a4SAndy Whitcroft
182834d99219SJoe Perches			CHK("INVALID_UTF8",
1829000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
183000df344fSAndy Whitcroft		}
18310a920b5bSAndy Whitcroft
183215662b3eSJoe Perches# Check if it's the start of a commit log
183315662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
183415662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
1835270c49a0SJoe Perches		    $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
183615662b3eSJoe Perches			$in_header_lines = 0;
183715662b3eSJoe Perches			$in_commit_log = 1;
183815662b3eSJoe Perches		}
183915662b3eSJoe Perches
1840fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
1841fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
1842fa64205dSPasi Savanainen		if ($in_header_lines &&
1843fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
1844fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
1845fa64205dSPasi Savanainen			$non_utf8_charset = 1;
1846fa64205dSPasi Savanainen		}
1847fa64205dSPasi Savanainen
1848fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
184915662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
1850fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
185115662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
185215662b3eSJoe Perches		}
185315662b3eSJoe Perches
185430670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
185530670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
185600df344fSAndy Whitcroft
18570a920b5bSAndy Whitcroft#trailing whitespace
18589c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
1859c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1860d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
1861d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
1862d5e616fcSJoe Perches			    $fix) {
1863d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/[\s\015]+$//;
1864d5e616fcSJoe Perches			}
1865c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1866c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
18673705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
18683705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
18693705ce5bSJoe Perches			    $fix) {
1870d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\s+$//;
18713705ce5bSJoe Perches			}
18723705ce5bSJoe Perches
1873d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
18740a920b5bSAndy Whitcroft		}
18755368df20SAndy Whitcroft
18763354957aSAndi Kleen# check for Kconfig help text having a real description
18779fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
18789fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
18793354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
1880a1385803SAndy Whitcroft		    $line =~ /.\s*config\s+/) {
18813354957aSAndi Kleen			my $length = 0;
18829fe287d7SAndy Whitcroft			my $cnt = $realcnt;
18839fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
18849fe287d7SAndy Whitcroft			my $f;
1885a1385803SAndy Whitcroft			my $is_start = 0;
18869fe287d7SAndy Whitcroft			my $is_end = 0;
1887a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
18889fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
18899fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
18909fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
18919fe287d7SAndy Whitcroft
18929fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
1893a1385803SAndy Whitcroft
1894a1385803SAndy Whitcroft				if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) {
1895a1385803SAndy Whitcroft					$is_start = 1;
1896a1385803SAndy Whitcroft				} elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) {
1897a1385803SAndy Whitcroft					$length = -1;
1898a1385803SAndy Whitcroft				}
1899a1385803SAndy Whitcroft
19009fe287d7SAndy Whitcroft				$f =~ s/^.//;
19013354957aSAndi Kleen				$f =~ s/#.*//;
19023354957aSAndi Kleen				$f =~ s/^\s+//;
19033354957aSAndi Kleen				next if ($f =~ /^$/);
19049fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
19059fe287d7SAndy Whitcroft					$is_end = 1;
19069fe287d7SAndy Whitcroft					last;
19079fe287d7SAndy Whitcroft				}
19083354957aSAndi Kleen				$length++;
19093354957aSAndi Kleen			}
1910000d1cc1SJoe Perches			WARN("CONFIG_DESCRIPTION",
1911a1385803SAndy Whitcroft			     "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4);
1912a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
19133354957aSAndi Kleen		}
19143354957aSAndi Kleen
19151ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig.
19161ba8dfd1SKees Cook		if ($realfile =~ /Kconfig/ &&
19171ba8dfd1SKees Cook		    $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) {
19181ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
19191ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
19201ba8dfd1SKees Cook		}
19211ba8dfd1SKees Cook
1922c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
1923c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
1924c68e5878SArnaud Lacombe			my $flag = $1;
1925c68e5878SArnaud Lacombe			my $replacement = {
1926c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
1927c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
1928c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
1929c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
1930c68e5878SArnaud Lacombe			};
1931c68e5878SArnaud Lacombe
1932c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
1933c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
1934c68e5878SArnaud Lacombe		}
1935c68e5878SArnaud Lacombe
19365368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
19375368df20SAndy Whitcroft		next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
19385368df20SAndy Whitcroft
19396cd7f386SJoe Perches#line length limit
1940c45dcabdSAndy Whitcroft		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1941f4c014c0SAndy Whitcroft		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
19420fccc622SJoe Perches		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
19438bbea968SJoe Perches		    $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
19446cd7f386SJoe Perches		    $length > $max_line_length)
1945c45dcabdSAndy Whitcroft		{
1946000d1cc1SJoe Perches			WARN("LONG_LINE",
19476cd7f386SJoe Perches			     "line over $max_line_length characters\n" . $herecurr);
19480a920b5bSAndy Whitcroft		}
19490a920b5bSAndy Whitcroft
1950ca56dc09SJosh Triplett# Check for user-visible strings broken across lines, which breaks the ability
1951ca56dc09SJosh Triplett# to grep for the string.  Limited to strings used as parameters (those
1952ca56dc09SJosh Triplett# following an open parenthesis), which almost completely eliminates false
1953ca56dc09SJosh Triplett# positives, as well as warning only once per parameter rather than once per
1954ca56dc09SJosh Triplett# line of the string.  Make an exception when the previous string ends in a
1955ca56dc09SJosh Triplett# newline (multiple lines in one string constant) or \n\t (common in inline
1956ca56dc09SJosh Triplett# assembly to indent the instruction on the following line).
1957ca56dc09SJosh Triplett		if ($line =~ /^\+\s*"/ &&
1958ca56dc09SJosh Triplett		    $prevline =~ /"\s*$/ &&
1959ca56dc09SJosh Triplett		    $prevline =~ /\(/ &&
1960ca56dc09SJosh Triplett		    $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
1961ca56dc09SJosh Triplett			WARN("SPLIT_STRING",
1962ca56dc09SJosh Triplett			     "quoted string split across lines\n" . $hereprev);
1963ca56dc09SJosh Triplett		}
1964ca56dc09SJosh Triplett
19655e79d96eSJoe Perches# check for spaces before a quoted newline
19665e79d96eSJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
19673705ce5bSJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
19683705ce5bSJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
19693705ce5bSJoe Perches			    $fix) {
19703705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
19713705ce5bSJoe Perches			}
19723705ce5bSJoe Perches
19735e79d96eSJoe Perches		}
19745e79d96eSJoe Perches
19758905a67cSAndy Whitcroft# check for adding lines without a newline.
19768905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1977000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
1978000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
19798905a67cSAndy Whitcroft		}
19808905a67cSAndy Whitcroft
198142e41c54SMike Frysinger# Blackfin: use hi/lo macros
198242e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
198342e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
198442e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1985000d1cc1SJoe Perches				ERROR("LO_MACRO",
1986000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
198742e41c54SMike Frysinger			}
198842e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
198942e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
1990000d1cc1SJoe Perches				ERROR("HI_MACRO",
1991000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
199242e41c54SMike Frysinger			}
199342e41c54SMike Frysinger		}
199442e41c54SMike Frysinger
1995b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
1996b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c|pl)$/);
19970a920b5bSAndy Whitcroft
19980a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
19990a920b5bSAndy Whitcroft# more than 8 must use tabs.
2000c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
2001c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
2002c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2003d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
20043705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
20053705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
20063705ce5bSJoe Perches			    $fix) {
20073705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
20083705ce5bSJoe Perches			}
20090a920b5bSAndy Whitcroft		}
20100a920b5bSAndy Whitcroft
201108e44365SAlberto Panizzo# check for space before tabs.
201208e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
201308e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
20143705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
20153705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
20163705ce5bSJoe Perches			    $fix) {
20173705ce5bSJoe Perches				$fixed[$linenr - 1] =~
20183705ce5bSJoe Perches				    s/(^\+.*) +\t/$1\t/;
20193705ce5bSJoe Perches			}
202008e44365SAlberto Panizzo		}
202108e44365SAlberto Panizzo
2022d1fe9c09SJoe Perches# check for && or || at the start of a line
2023d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2024d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
2025d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
2026d1fe9c09SJoe Perches		}
2027d1fe9c09SJoe Perches
2028d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
2029d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
2030d1fe9c09SJoe Perches		    $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
2031d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
2032d1fe9c09SJoe Perches			my $oldindent = $1;
2033d1fe9c09SJoe Perches			my $rest = $2;
2034d1fe9c09SJoe Perches
2035d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
2036d1fe9c09SJoe Perches			if ($pos >= 0) {
2037b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
2038b34a26f3SJoe Perches				my $newindent = $2;
2039d1fe9c09SJoe Perches
2040d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
2041d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
2042d1fe9c09SJoe Perches					" "  x ($pos % 8);
2043d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
2044d1fe9c09SJoe Perches
2045d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
2046d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
20473705ce5bSJoe Perches
20483705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
20493705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
20503705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
20513705ce5bSJoe Perches						$fixed[$linenr - 1] =~
20523705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
20533705ce5bSJoe Perches					}
2054d1fe9c09SJoe Perches				}
2055d1fe9c09SJoe Perches			}
2056d1fe9c09SJoe Perches		}
2057d1fe9c09SJoe Perches
205823f780c9SJoe Perches		if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
20593705ce5bSJoe Perches			if (CHK("SPACING",
20603705ce5bSJoe Perches				"No space is necessary after a cast\n" . $hereprev) &&
20613705ce5bSJoe Perches			    $fix) {
20623705ce5bSJoe Perches				$fixed[$linenr - 1] =~
20633705ce5bSJoe Perches				    s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
20643705ce5bSJoe Perches			}
2065aad4f614SJoe Perches		}
2066aad4f614SJoe Perches
206705880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2068fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
2069fdb4bcd6SJoe Perches		    $rawline =~ /^\+[ \t]*\*/) {
207005880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
207105880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
207205880600SJoe Perches		}
207305880600SJoe Perches
207405880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2075a605e32eSJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*
2076a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
2077a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
2078a605e32eSJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
2079a605e32eSJoe Perches			     "networking block comments start with * on subsequent lines\n" . $hereprev);
2080a605e32eSJoe Perches		}
2081a605e32eSJoe Perches
2082a605e32eSJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
2083c24f9f19SJoe Perches		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
2084c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
2085c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
2086c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
208705880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
208805880600SJoe Perches			     "networking block comments put the trailing */ on a separate line\n" . $herecurr);
208905880600SJoe Perches		}
209005880600SJoe Perches
20915f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
20926b4c5bebSAndy Whitcroft# Exceptions:
20936b4c5bebSAndy Whitcroft#  1) within comments
20946b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
20956b4c5bebSAndy Whitcroft#  3) hanging labels
20963705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
20975f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
20983705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
20993705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
21003705ce5bSJoe Perches			    $fix) {
21013705ce5bSJoe Perches				$fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
21023705ce5bSJoe Perches			}
21035f7ddae6SRaffaele Recalcati		}
21045f7ddae6SRaffaele Recalcati
2105b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
2106b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
2107b9ea10d6SAndy Whitcroft
21081ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def).
21091ba8dfd1SKees Cook		if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) {
21101ba8dfd1SKees Cook			WARN("CONFIG_EXPERIMENTAL",
21111ba8dfd1SKees Cook			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n");
21121ba8dfd1SKees Cook		}
21131ba8dfd1SKees Cook
2114c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
2115cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2116000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
2117000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2118c2fdda0dSAndy Whitcroft		}
211922f2a2efSAndy Whitcroft
212042e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
212142e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
212242e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2123000d1cc1SJoe Perches			ERROR("CSYNC",
2124000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
212542e41c54SMike Frysinger		}
212642e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
212742e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
2128000d1cc1SJoe Perches			ERROR("SSYNC",
2129000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
213042e41c54SMike Frysinger		}
213142e41c54SMike Frysinger
213256e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
213356e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
213456e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
213556e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
213656e77d70SJoe Perches		}
213756e77d70SJoe Perches
21389c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
21392b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
21402b474a1aSAndy Whitcroft		    $realline_next);
21413e469cdcSAndy Whitcroft#print "LINE<$line>\n";
21423e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
21433e469cdcSAndy Whitcroft		    $realcnt && $line =~ /.\s*\S/) {
2144170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2145f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
2146171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
2147171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
2148171ae1a4SAndy Whitcroft
21493e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
21503e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
21513e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
21523e469cdcSAndy Whitcroft			# until we hit end of it.
21533e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
21543e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
21553e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
21563e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
21573e469cdcSAndy Whitcroft			}
2158f74bd194SAndy Whitcroft
21592b474a1aSAndy Whitcroft			# Find the real next line.
21602b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
21612b474a1aSAndy Whitcroft			if (defined $realline_next &&
21622b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
21632b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
21642b474a1aSAndy Whitcroft				$realline_next++;
21652b474a1aSAndy Whitcroft			}
21662b474a1aSAndy Whitcroft
2167171ae1a4SAndy Whitcroft			my $s = $stat;
2168171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
2169cf655043SAndy Whitcroft
2170c2fdda0dSAndy Whitcroft			# Ignore goto labels.
2171171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
2172c2fdda0dSAndy Whitcroft
2173c2fdda0dSAndy Whitcroft			# Ignore functions being called
2174171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2175c2fdda0dSAndy Whitcroft
2176463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
2177463f2864SAndy Whitcroft
2178c45dcabdSAndy Whitcroft			# declarations always start with types
2179d2506586SAndy 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) {
2180c45dcabdSAndy Whitcroft				my $type = $1;
2181c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
2182c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
2183c45dcabdSAndy Whitcroft
21846c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
2185a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2186c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
2187c2fdda0dSAndy Whitcroft			}
21888905a67cSAndy Whitcroft
21896c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
219065863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2191c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
21929c0ca6f9SAndy Whitcroft			}
21938905a67cSAndy Whitcroft
21948905a67cSAndy Whitcroft			# Check for any sort of function declaration.
21958905a67cSAndy Whitcroft			# int foo(something bar, other baz);
21968905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
2197171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
21988905a67cSAndy Whitcroft				my ($name_len) = length($1);
21998905a67cSAndy Whitcroft
2200cf655043SAndy Whitcroft				my $ctx = $s;
2201773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
22028905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
2203cf655043SAndy Whitcroft
22048905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
2205c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
22068905a67cSAndy Whitcroft
2207c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
22088905a67cSAndy Whitcroft					}
22098905a67cSAndy Whitcroft				}
22108905a67cSAndy Whitcroft			}
22118905a67cSAndy Whitcroft
22129c0ca6f9SAndy Whitcroft		}
22139c0ca6f9SAndy Whitcroft
221400df344fSAndy Whitcroft#
221500df344fSAndy Whitcroft# Checks which may be anchored in the context.
221600df344fSAndy Whitcroft#
221700df344fSAndy Whitcroft
221800df344fSAndy Whitcroft# Check for switch () and associated case and default
221900df344fSAndy Whitcroft# statements should be at the same indent.
222000df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
222100df344fSAndy Whitcroft			my $err = '';
222200df344fSAndy Whitcroft			my $sep = '';
222300df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
222400df344fSAndy Whitcroft			shift(@ctx);
222500df344fSAndy Whitcroft			for my $ctx (@ctx) {
222600df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
222700df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
222800df344fSAndy Whitcroft							$indent != $cindent) {
222900df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
223000df344fSAndy Whitcroft					$sep = '';
223100df344fSAndy Whitcroft				} else {
223200df344fSAndy Whitcroft					$sep = "[...]\n";
223300df344fSAndy Whitcroft				}
223400df344fSAndy Whitcroft			}
223500df344fSAndy Whitcroft			if ($err ne '') {
2236000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
2237000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
2238de7d4f0eSAndy Whitcroft			}
2239de7d4f0eSAndy Whitcroft		}
2240de7d4f0eSAndy Whitcroft
2241de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
2242de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
2243c45dcabdSAndy Whitcroft		if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2244773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
2245773647a0SAndy Whitcroft
22469c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
22478eef05ddSJoe Perches
22488eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
22498eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
22508eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
22518eef05ddSJoe Perches			}
22528eef05ddSJoe Perches
2253de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
2254de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
2255de7d4f0eSAndy Whitcroft
2256548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
2257548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
2258de7d4f0eSAndy Whitcroft
2259548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2260548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
2261548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
2262548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2263548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2264773647a0SAndy Whitcroft				$ctx_ln++;
2265773647a0SAndy Whitcroft			}
2266548596d5SAndy Whitcroft
226753210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
226853210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2269773647a0SAndy Whitcroft
2270773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2271000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
2272000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
227301464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
227400df344fSAndy Whitcroft			}
2275773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2276773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
2277773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
2278773647a0SAndy Whitcroft			{
22799c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
22809c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
2281000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
2282000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
228301464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
22849c0ca6f9SAndy Whitcroft				}
22859c0ca6f9SAndy Whitcroft			}
228600df344fSAndy Whitcroft		}
228700df344fSAndy Whitcroft
22884d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
22894d001e4dSAndy Whitcroft		if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
22903e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
22913e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
22923e469cdcSAndy Whitcroft					if (!defined $stat);
22934d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
22944d001e4dSAndy Whitcroft
22954d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
22964d001e4dSAndy Whitcroft
22974d001e4dSAndy Whitcroft			# Make sure we remove the line prefixes as we have
22984d001e4dSAndy Whitcroft			# none on the first line, and are going to readd them
22994d001e4dSAndy Whitcroft			# where necessary.
23004d001e4dSAndy Whitcroft			$s =~ s/\n./\n/gs;
23014d001e4dSAndy Whitcroft
23024d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
23036f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
23046f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
23054d001e4dSAndy Whitcroft
23064d001e4dSAndy Whitcroft			# We want to check the first line inside the block
23074d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
23084d001e4dSAndy Whitcroft			#  1) any blank line termination
23094d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
23104d001e4dSAndy Whitcroft			#  3) any do (...) {
23114d001e4dSAndy Whitcroft			my $continuation = 0;
23124d001e4dSAndy Whitcroft			my $check = 0;
23134d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
23144d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
23154d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
23164d001e4dSAndy Whitcroft				$continuation = 1;
23174d001e4dSAndy Whitcroft			}
23189bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
23194d001e4dSAndy Whitcroft				$check = 1;
23204d001e4dSAndy Whitcroft				$cond_lines++;
23214d001e4dSAndy Whitcroft			}
23224d001e4dSAndy Whitcroft
23234d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
23244d001e4dSAndy Whitcroft			# preprocessor statement.
23254d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
23264d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
23274d001e4dSAndy Whitcroft				$check = 0;
23284d001e4dSAndy Whitcroft			}
23294d001e4dSAndy Whitcroft
23309bd49efeSAndy Whitcroft			my $cond_ptr = -1;
2331740504c6SAndy Whitcroft			$continuation = 0;
23329bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
23339bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
23344d001e4dSAndy Whitcroft
2335f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
2336f16fa28fSAndy Whitcroft				# is not linear.
2337f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2338f16fa28fSAndy Whitcroft					$check = 0;
2339f16fa28fSAndy Whitcroft				}
2340f16fa28fSAndy Whitcroft
23419bd49efeSAndy Whitcroft				# Ignore:
23429bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
23439bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
23449bd49efeSAndy Whitcroft				#  3) labels.
2345740504c6SAndy Whitcroft				if ($continuation ||
2346740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
23479bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
23489bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
2349740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
235030dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
23519bd49efeSAndy Whitcroft						$cond_lines++;
23529bd49efeSAndy Whitcroft					}
23534d001e4dSAndy Whitcroft				}
235430dad6ebSAndy Whitcroft			}
23554d001e4dSAndy Whitcroft
23564d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
23574d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
23584d001e4dSAndy Whitcroft
23594d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
23604d001e4dSAndy Whitcroft			# this is not this patch's fault.
23614d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
23624d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
23634d001e4dSAndy Whitcroft				$check = 0;
23644d001e4dSAndy Whitcroft			}
23654d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
23664d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
23674d001e4dSAndy Whitcroft			}
23684d001e4dSAndy Whitcroft
23699bd49efeSAndy 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";
23704d001e4dSAndy Whitcroft
23714d001e4dSAndy Whitcroft			if ($check && (($sindent % 8) != 0 ||
23724d001e4dSAndy Whitcroft			    ($sindent <= $indent && $s ne ''))) {
2373000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
2374000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
23754d001e4dSAndy Whitcroft			}
23764d001e4dSAndy Whitcroft		}
23774d001e4dSAndy Whitcroft
23786c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
23796c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
23801f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
23811f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
23826c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
2383c2fdda0dSAndy Whitcroft		if ($dbg_values) {
2384c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
2385cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
2386cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
23871f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
2388c2fdda0dSAndy Whitcroft		}
23896c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
23906c72ffaaSAndy Whitcroft
239100df344fSAndy Whitcroft#ignore lines not being added
23923705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
239300df344fSAndy Whitcroft
2394653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
23957429c690SAndy Whitcroft		if ($dbg_type) {
23967429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
2397000d1cc1SJoe Perches				ERROR("TEST_TYPE",
2398000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
23997429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
2400000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
2401000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
24027429c690SAndy Whitcroft			}
2403653d4876SAndy Whitcroft			next;
2404653d4876SAndy Whitcroft		}
2405a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
2406a1ef277eSAndy Whitcroft		if ($dbg_attr) {
24079360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
2408000d1cc1SJoe Perches				ERROR("TEST_ATTR",
2409000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
24109360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
2411000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
2412000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
2413a1ef277eSAndy Whitcroft			}
2414a1ef277eSAndy Whitcroft			next;
2415a1ef277eSAndy Whitcroft		}
2416653d4876SAndy Whitcroft
2417f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
241899423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
241999423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
2420000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2421000d1cc1SJoe Perches			      "that open brace { should be on the previous line\n" . $hereprev);
2422f0a594c1SAndy Whitcroft		}
2423f0a594c1SAndy Whitcroft
242400df344fSAndy Whitcroft#
242500df344fSAndy Whitcroft# Checks which are anchored on the added line.
242600df344fSAndy Whitcroft#
242700df344fSAndy Whitcroft
2428653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
2429c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
2430653d4876SAndy Whitcroft			my $path = $1;
2431653d4876SAndy Whitcroft			if ($path =~ m{//}) {
2432000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
2433495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
2434495e9d84SJoe Perches			}
2435495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
2436495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
2437495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
2438653d4876SAndy Whitcroft			}
2439653d4876SAndy Whitcroft		}
2440653d4876SAndy Whitcroft
244100df344fSAndy Whitcroft# no C99 // comments
244200df344fSAndy Whitcroft		if ($line =~ m{//}) {
24433705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
24443705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
24453705ce5bSJoe Perches			    $fix) {
24463705ce5bSJoe Perches				my $line = $fixed[$linenr - 1];
24473705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
24483705ce5bSJoe Perches					my $comment = trim($1);
24493705ce5bSJoe Perches					$fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
24503705ce5bSJoe Perches				}
24513705ce5bSJoe Perches			}
245200df344fSAndy Whitcroft		}
245300df344fSAndy Whitcroft		# Remove C99 comments.
24540a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
24556c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
24560a920b5bSAndy Whitcroft
24572b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
24582b474a1aSAndy Whitcroft# the whole statement.
24592b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
24602b474a1aSAndy Whitcroft		if (defined $realline_next &&
24612b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
24622b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
24632b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
24642b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
24653cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
24663cbf62dfSAndy Whitcroft			# a prefix:
24673cbf62dfSAndy Whitcroft			#   XXX(foo);
24683cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
2469653d4876SAndy Whitcroft			my $name = $1;
247087a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
24713cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
24723cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
24733cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
24743cbf62dfSAndy Whitcroft
24753cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
24762b474a1aSAndy Whitcroft				\n.}\s*$|
247748012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
247848012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
247948012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
24802b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
24812b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
248248012058SAndy Whitcroft			    )/x) {
24832b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
24842b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
24852b474a1aSAndy Whitcroft			} else {
24862b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
24870a920b5bSAndy Whitcroft			}
24880a920b5bSAndy Whitcroft		}
24892b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
24902b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
24912b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
24922b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
24932b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
24942b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
24952b474a1aSAndy Whitcroft		}
24962b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
24972b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
2498000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
2499000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
25002b474a1aSAndy Whitcroft		}
25010a920b5bSAndy Whitcroft
25025150bda4SJoe Eloff# check for global initialisers.
2503d5e616fcSJoe Perches		if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
2504d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
2505000d1cc1SJoe Perches				  "do not initialise globals to 0 or NULL\n" .
2506d5e616fcSJoe Perches				      $herecurr) &&
2507d5e616fcSJoe Perches			    $fix) {
2508d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
2509d5e616fcSJoe Perches			}
2510f0a594c1SAndy Whitcroft		}
25110a920b5bSAndy Whitcroft# check for static initialisers.
2512d5e616fcSJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
2513d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
2514000d1cc1SJoe Perches				  "do not initialise statics to 0 or NULL\n" .
2515d5e616fcSJoe Perches				      $herecurr) &&
2516d5e616fcSJoe Perches			    $fix) {
2517d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
2518d5e616fcSJoe Perches			}
25190a920b5bSAndy Whitcroft		}
25200a920b5bSAndy Whitcroft
2521cb710ecaSJoe Perches# check for static const char * arrays.
2522cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
2523000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2524000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
2525cb710ecaSJoe Perches				$herecurr);
2526cb710ecaSJoe Perches               }
2527cb710ecaSJoe Perches
2528cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
2529cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
2530000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
2531000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
2532cb710ecaSJoe Perches				$herecurr);
2533cb710ecaSJoe Perches               }
2534cb710ecaSJoe Perches
253593ed0e2dSJoe Perches# check for declarations of struct pci_device_id
253693ed0e2dSJoe Perches		if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
2537000d1cc1SJoe Perches			WARN("DEFINE_PCI_DEVICE_TABLE",
2538000d1cc1SJoe Perches			     "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
253993ed0e2dSJoe Perches		}
254093ed0e2dSJoe Perches
2541653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
2542653d4876SAndy Whitcroft# make sense.
2543653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
25448054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
2545c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
25468ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
2547653d4876SAndy Whitcroft		    $line !~ /\b__bitwise(?:__|)\b/) {
2548000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
2549000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
25500a920b5bSAndy Whitcroft		}
25510a920b5bSAndy Whitcroft
25520a920b5bSAndy Whitcroft# * goes on variable not on type
255365863862SAndy Whitcroft		# (char*[ const])
2554bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
2555bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
25563705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
2557d8aaf121SAndy Whitcroft
255865863862SAndy Whitcroft			# Should start with a space.
255965863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
256065863862SAndy Whitcroft			# Should not end with a space.
256165863862SAndy Whitcroft			$to =~ s/\s+$//;
256265863862SAndy Whitcroft			# '*'s should not have spaces between.
2563f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
256465863862SAndy Whitcroft			}
2565d8aaf121SAndy Whitcroft
25663705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
256765863862SAndy Whitcroft			if ($from ne $to) {
25683705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
25693705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
25703705ce5bSJoe Perches				    $fix) {
25713705ce5bSJoe Perches					my $sub_from = $ident;
25723705ce5bSJoe Perches					my $sub_to = $ident;
25733705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
25743705ce5bSJoe Perches					$fixed[$linenr - 1] =~
25753705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
25763705ce5bSJoe Perches				}
257765863862SAndy Whitcroft			}
2578bfcb2cc7SAndy Whitcroft		}
2579bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
2580bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
25813705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
2582d8aaf121SAndy Whitcroft
258365863862SAndy Whitcroft			# Should start with a space.
258465863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
258565863862SAndy Whitcroft			# Should not end with a space.
258665863862SAndy Whitcroft			$to =~ s/\s+$//;
258765863862SAndy Whitcroft			# '*'s should not have spaces between.
2588f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
258965863862SAndy Whitcroft			}
259065863862SAndy Whitcroft			# Modifiers should have spaces.
259165863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
259265863862SAndy Whitcroft
25933705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
2594667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
25953705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
25963705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
25973705ce5bSJoe Perches				    $fix) {
25983705ce5bSJoe Perches
25993705ce5bSJoe Perches					my $sub_from = $match;
26003705ce5bSJoe Perches					my $sub_to = $match;
26013705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
26023705ce5bSJoe Perches					$fixed[$linenr - 1] =~
26033705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
26043705ce5bSJoe Perches				}
260565863862SAndy Whitcroft			}
26060a920b5bSAndy Whitcroft		}
26070a920b5bSAndy Whitcroft
26080a920b5bSAndy Whitcroft# # no BUG() or BUG_ON()
26090a920b5bSAndy Whitcroft# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {
26100a920b5bSAndy Whitcroft# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
26110a920b5bSAndy Whitcroft# 			print "$herecurr";
26120a920b5bSAndy Whitcroft# 			$clean = 0;
26130a920b5bSAndy Whitcroft# 		}
26140a920b5bSAndy Whitcroft
26158905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
2616000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
2617000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
26188905a67cSAndy Whitcroft		}
26198905a67cSAndy Whitcroft
262017441227SJoe Perches# check for uses of printk_ratelimit
262117441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
2622000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
2623000d1cc1SJoe Perches"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
262417441227SJoe Perches		}
262517441227SJoe Perches
262600df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
262700df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
262800df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
262925985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
263000df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
2631f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
263200df344fSAndy Whitcroft			my $ok = 0;
263300df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
263400df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
263525985edcSLucas De Marchi				# we have a preceding printk if it ends
263600df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
263700df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
263800df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
263900df344fSAndy Whitcroft						$ok = 1;
264000df344fSAndy Whitcroft					}
264100df344fSAndy Whitcroft					last;
264200df344fSAndy Whitcroft				}
264300df344fSAndy Whitcroft			}
264400df344fSAndy Whitcroft			if ($ok == 0) {
2645000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
2646000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
26470a920b5bSAndy Whitcroft			}
264800df344fSAndy Whitcroft		}
26490a920b5bSAndy Whitcroft
2650243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
2651243f3803SJoe Perches			my $orig = $1;
2652243f3803SJoe Perches			my $level = lc($orig);
2653243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
26548f26b837SJoe Perches			my $level2 = $level;
26558f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
2656243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
26578f26b837SJoe Perches			     "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
2658243f3803SJoe Perches		}
2659243f3803SJoe Perches
2660243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
2661d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
2662d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
2663d5e616fcSJoe Perches			    $fix) {
2664d5e616fcSJoe Perches				$fixed[$linenr - 1] =~
2665d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
2666d5e616fcSJoe Perches			}
2667243f3803SJoe Perches		}
2668243f3803SJoe Perches
2669dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
2670dc139313SJoe Perches			my $orig = $1;
2671dc139313SJoe Perches			my $level = lc($orig);
2672dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
2673dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
2674dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
2675dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
2676dc139313SJoe Perches		}
2677dc139313SJoe Perches
2678653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
2679653d4876SAndy Whitcroft# or if closed on same line
2680c45dcabdSAndy Whitcroft		if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
2681c45dcabdSAndy Whitcroft		    !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
2682000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2683000d1cc1SJoe Perches			      "open brace '{' following function declarations go on the next line\n" . $herecurr);
26840a920b5bSAndy Whitcroft		}
2685653d4876SAndy Whitcroft
26868905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
26878905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
26888905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2689000d1cc1SJoe Perches			ERROR("OPEN_BRACE",
2690000d1cc1SJoe Perches			      "open brace '{' following $1 go on the same line\n" . $hereprev);
26918905a67cSAndy Whitcroft		}
26928905a67cSAndy Whitcroft
26930c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
26943705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
26953705ce5bSJoe Perches			if (WARN("SPACING",
26963705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
26973705ce5bSJoe Perches			    $fix) {
26983705ce5bSJoe Perches				$fixed[$linenr - 1] =~
26993705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
27003705ce5bSJoe Perches			}
27010c73b4ebSAndy Whitcroft		}
27020c73b4ebSAndy Whitcroft
27038d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
27048d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
2705fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2706fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
27078d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
27088d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
27098d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
2710fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
2711daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
27123705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
27133705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
27143705ce5bSJoe Perches				    $fix) {
27153705ce5bSJoe Perches				    $fixed[$linenr - 1] =~
27163705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
27173705ce5bSJoe Perches				}
27188d31cfceSAndy Whitcroft			}
27198d31cfceSAndy Whitcroft		}
27208d31cfceSAndy Whitcroft
2721f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
27226c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
2723c2fdda0dSAndy Whitcroft			my $name = $1;
2724773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
2725773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
2726c2fdda0dSAndy Whitcroft
2727c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
2728773647a0SAndy Whitcroft			if ($name =~ /^(?:
2729773647a0SAndy Whitcroft				if|for|while|switch|return|case|
2730773647a0SAndy Whitcroft				volatile|__volatile__|
2731773647a0SAndy Whitcroft				__attribute__|format|__extension__|
2732773647a0SAndy Whitcroft				asm|__asm__)$/x)
2733773647a0SAndy Whitcroft			{
2734c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
2735c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
2736c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
2737c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
2738773647a0SAndy Whitcroft
2739773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
2740c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
2741c2fdda0dSAndy Whitcroft
2742c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
2743c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
2744773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
2745c2fdda0dSAndy Whitcroft
2746c2fdda0dSAndy Whitcroft			} else {
27473705ce5bSJoe Perches				if (WARN("SPACING",
27483705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
27493705ce5bSJoe Perches					     $fix) {
27503705ce5bSJoe Perches					$fixed[$linenr - 1] =~
27513705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
27523705ce5bSJoe Perches				}
2753f0a594c1SAndy Whitcroft			}
27546c72ffaaSAndy Whitcroft		}
27559a4cad4eSEric Nelson
2756653d4876SAndy Whitcroft# Check operator spacing.
27570a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
27583705ce5bSJoe Perches			my $fixed_line = "";
27593705ce5bSJoe Perches			my $line_fixed = 0;
27603705ce5bSJoe Perches
27619c0ca6f9SAndy Whitcroft			my $ops = qr{
27629c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
27639c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
27649c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
27651f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
27661f65f947SAndy Whitcroft				\?|:
27679c0ca6f9SAndy Whitcroft			}x;
2768cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
27693705ce5bSJoe Perches
27703705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
27713705ce5bSJoe Perches##			foreach my $el (@elements) {
27723705ce5bSJoe Perches##				print("el: <$el>\n");
27733705ce5bSJoe Perches##			}
27743705ce5bSJoe Perches
27753705ce5bSJoe Perches			my @fix_elements = ();
277600df344fSAndy Whitcroft			my $off = 0;
27776c72ffaaSAndy Whitcroft
27783705ce5bSJoe Perches			foreach my $el (@elements) {
27793705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
27803705ce5bSJoe Perches				$off += length($el);
27813705ce5bSJoe Perches			}
27823705ce5bSJoe Perches
27833705ce5bSJoe Perches			$off = 0;
27843705ce5bSJoe Perches
27856c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
27866c72ffaaSAndy Whitcroft
27870a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
27883705ce5bSJoe Perches
27893705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
27903705ce5bSJoe Perches
27913705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
27923705ce5bSJoe Perches
27934a0df2efSAndy Whitcroft				$off += length($elements[$n]);
27944a0df2efSAndy Whitcroft
279525985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
2796773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
2797773647a0SAndy Whitcroft				my $cc = '';
2798773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
2799773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
2800773647a0SAndy Whitcroft				}
2801773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
2802773647a0SAndy Whitcroft
28034a0df2efSAndy Whitcroft				my $a = '';
28044a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
28054a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
2806cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
28074a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
28084a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
2809773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
28104a0df2efSAndy Whitcroft
28110a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
28124a0df2efSAndy Whitcroft
28134a0df2efSAndy Whitcroft				my $c = '';
28140a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
28154a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
28164a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
2817cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
28184a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
28194a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
28208b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
28214a0df2efSAndy Whitcroft				} else {
28224a0df2efSAndy Whitcroft					$c = 'E';
28230a920b5bSAndy Whitcroft				}
28240a920b5bSAndy Whitcroft
28254a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
28264a0df2efSAndy Whitcroft
28274a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
28284a0df2efSAndy Whitcroft
28296c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
2830de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
28310a920b5bSAndy Whitcroft
283274048ed8SAndy Whitcroft				# Pull out the value of this operator.
28336c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
28340a920b5bSAndy Whitcroft
28351f65f947SAndy Whitcroft				# Get the full operator variant.
28361f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
28371f65f947SAndy Whitcroft
283813214adfSAndy Whitcroft				# Ignore operators passed as parameters.
283913214adfSAndy Whitcroft				if ($op_type ne 'V' &&
284013214adfSAndy Whitcroft				    $ca =~ /\s$/ && $cc =~ /^\s*,/) {
284113214adfSAndy Whitcroft
2842cf655043SAndy Whitcroft#				# Ignore comments
2843cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
284413214adfSAndy Whitcroft
2845d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
284613214adfSAndy Whitcroft				} elsif ($op eq ';') {
2847cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
2848cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
28493705ce5bSJoe Perches						if (ERROR("SPACING",
28503705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
28513705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
28523705ce5bSJoe Perches							$line_fixed = 1;
28533705ce5bSJoe Perches						}
2854d8aaf121SAndy Whitcroft					}
2855d8aaf121SAndy Whitcroft
2856d8aaf121SAndy Whitcroft				# // is a comment
2857d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
28580a920b5bSAndy Whitcroft
28591f65f947SAndy Whitcroft				# No spaces for:
28601f65f947SAndy Whitcroft				#   ->
28611f65f947SAndy Whitcroft				#   :   when part of a bitfield
28621f65f947SAndy Whitcroft				} elsif ($op eq '->' || $opv eq ':B') {
28634a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
28643705ce5bSJoe Perches						if (ERROR("SPACING",
28653705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
28663705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
28673705ce5bSJoe Perches							$line_fixed = 1;
28683705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
28693705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
28703705ce5bSJoe Perches							}
28713705ce5bSJoe Perches						}
28720a920b5bSAndy Whitcroft					}
28730a920b5bSAndy Whitcroft
28740a920b5bSAndy Whitcroft				# , must have a space on the right.
28750a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
2876cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
28773705ce5bSJoe Perches						if (ERROR("SPACING",
28783705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
28793705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
28803705ce5bSJoe Perches							$line_fixed = 1;
28813705ce5bSJoe Perches						}
28820a920b5bSAndy Whitcroft					}
28830a920b5bSAndy Whitcroft
28849c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
288574048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
28869c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
28879c0ca6f9SAndy Whitcroft
28889c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
28899c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
28909c0ca6f9SAndy Whitcroft				# unary operator, or a cast
28919c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
289274048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
28930d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
2894cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
28953705ce5bSJoe Perches						if (ERROR("SPACING",
28963705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
28973705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
28983705ce5bSJoe Perches							$line_fixed = 1;
28993705ce5bSJoe Perches						}
29000a920b5bSAndy Whitcroft					}
2901a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2902171ae1a4SAndy Whitcroft						# A unary '*' may be const
2903171ae1a4SAndy Whitcroft
2904171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
29053705ce5bSJoe Perches						if (ERROR("SPACING",
29063705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
29073705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
29083705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
29093705ce5bSJoe Perches							$line_fixed = 1;
29103705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
29113705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
29123705ce5bSJoe Perches							}
29133705ce5bSJoe Perches						}
29140a920b5bSAndy Whitcroft					}
29150a920b5bSAndy Whitcroft
29160a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
29170a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
2918773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
29193705ce5bSJoe Perches						if (ERROR("SPACING",
29203705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
29213705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
29223705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " ";
29233705ce5bSJoe Perches							$line_fixed = 1;
29243705ce5bSJoe Perches						}
29250a920b5bSAndy Whitcroft					}
2926773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
2927773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
29283705ce5bSJoe Perches						if (ERROR("SPACING",
29293705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
29303705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
29313705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
29323705ce5bSJoe Perches							$line_fixed = 1;
29333705ce5bSJoe Perches						}
2934653d4876SAndy Whitcroft					}
2935773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
29363705ce5bSJoe Perches						if (ERROR("SPACING",
29373705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
29383705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
29393705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
29403705ce5bSJoe Perches							$line_fixed = 1;
29413705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
29423705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
2943773647a0SAndy Whitcroft							}
29443705ce5bSJoe Perches						}
29453705ce5bSJoe Perches					}
29460a920b5bSAndy Whitcroft
29470a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
29489c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
29499c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
29509c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
2951c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
2952c2fdda0dSAndy Whitcroft					 $op eq '%')
29530a920b5bSAndy Whitcroft				{
2954773647a0SAndy Whitcroft					if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
29553705ce5bSJoe Perches						if (ERROR("SPACING",
29563705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
29573705ce5bSJoe Perches							$fixed_line =~ s/\s+$//;
29583705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
29593705ce5bSJoe Perches							$line_fixed = 1;
29603705ce5bSJoe Perches						}
29610a920b5bSAndy Whitcroft					}
29620a920b5bSAndy Whitcroft
29631f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
29641f65f947SAndy Whitcroft				# terminating a case value or a label.
29651f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
29661f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
29673705ce5bSJoe Perches						if (ERROR("SPACING",
29683705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
29693705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
29703705ce5bSJoe Perches							$line_fixed = 1;
29713705ce5bSJoe Perches						}
29721f65f947SAndy Whitcroft					}
29731f65f947SAndy Whitcroft
29740a920b5bSAndy Whitcroft				# All the others need spaces both sides.
2975cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
29761f65f947SAndy Whitcroft					my $ok = 0;
29771f65f947SAndy Whitcroft
297822f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
29791f65f947SAndy Whitcroft					if (($op eq '<' &&
29801f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
29811f65f947SAndy Whitcroft					    ($op eq '>' &&
29821f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
29831f65f947SAndy Whitcroft					{
29841f65f947SAndy Whitcroft					    	$ok = 1;
29851f65f947SAndy Whitcroft					}
29861f65f947SAndy Whitcroft
29871f65f947SAndy Whitcroft					# Ignore ?:
29881f65f947SAndy Whitcroft					if (($opv eq ':O' && $ca =~ /\?$/) ||
29891f65f947SAndy Whitcroft					    ($op eq '?' && $cc =~ /^:/)) {
29901f65f947SAndy Whitcroft					    	$ok = 1;
29911f65f947SAndy Whitcroft					}
29921f65f947SAndy Whitcroft
29931f65f947SAndy Whitcroft					if ($ok == 0) {
29943705ce5bSJoe Perches						if (ERROR("SPACING",
29953705ce5bSJoe Perches							  "spaces required around that '$op' $at\n" . $hereptr)) {
29963705ce5bSJoe Perches							$good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
29973705ce5bSJoe Perches							$good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " ";
29983705ce5bSJoe Perches							$line_fixed = 1;
29993705ce5bSJoe Perches						}
30000a920b5bSAndy Whitcroft					}
300122f2a2efSAndy Whitcroft				}
30024a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
30033705ce5bSJoe Perches
30043705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
30053705ce5bSJoe Perches
30063705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
30070a920b5bSAndy Whitcroft			}
30083705ce5bSJoe Perches
30093705ce5bSJoe Perches			if (($#elements % 2) == 0) {
30103705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
30113705ce5bSJoe Perches			}
30123705ce5bSJoe Perches
30133705ce5bSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
30143705ce5bSJoe Perches				$fixed[$linenr - 1] = $fixed_line;
30153705ce5bSJoe Perches			}
30163705ce5bSJoe Perches
30173705ce5bSJoe Perches
30180a920b5bSAndy Whitcroft		}
30190a920b5bSAndy Whitcroft
3020786b6326SJoe Perches# check for whitespace before a non-naked semicolon
3021786b6326SJoe Perches		if ($line =~ /^\+.*\S\s+;/) {
3022786b6326SJoe Perches			if (WARN("SPACING",
3023786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
3024786b6326SJoe Perches			    $fix) {
3025786b6326SJoe Perches				1 while $fixed[$linenr - 1] =~
3026786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
3027786b6326SJoe Perches			}
3028786b6326SJoe Perches		}
3029786b6326SJoe Perches
3030f0a594c1SAndy Whitcroft# check for multiple assignments
3031f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
3032000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
3033000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
3034f0a594c1SAndy Whitcroft		}
3035f0a594c1SAndy Whitcroft
303622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
303722f2a2efSAndy Whitcroft## # continuation.
303822f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
303922f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
304022f2a2efSAndy Whitcroft##
304122f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
304222f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
304322f2a2efSAndy Whitcroft## 			my $ln = $line;
304422f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
304522f2a2efSAndy Whitcroft## 			}
304622f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
3047000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
3048000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
304922f2a2efSAndy Whitcroft## 			}
305022f2a2efSAndy Whitcroft## 		}
3051f0a594c1SAndy Whitcroft
30520a920b5bSAndy Whitcroft#need space before brace following if, while, etc
305322f2a2efSAndy Whitcroft		if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
305422f2a2efSAndy Whitcroft		    $line =~ /do{/) {
30553705ce5bSJoe Perches			if (ERROR("SPACING",
30563705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
30573705ce5bSJoe Perches			    $fix) {
3058d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/;
30593705ce5bSJoe Perches			}
3060de7d4f0eSAndy Whitcroft		}
3061de7d4f0eSAndy Whitcroft
3062c4a62ef9SJoe Perches## # check for blank lines before declarations
3063c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
3064c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
3065c4a62ef9SJoe Perches##			WARN("SPACING",
3066c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
3067c4a62ef9SJoe Perches##		}
3068c4a62ef9SJoe Perches##
3069c4a62ef9SJoe Perches
3070de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
3071de7d4f0eSAndy Whitcroft# on the line
3072de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
3073d5e616fcSJoe Perches			if (ERROR("SPACING",
3074d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
3075d5e616fcSJoe Perches			    $fix) {
3076d5e616fcSJoe Perches				$fixed[$linenr - 1] =~
3077d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
3078d5e616fcSJoe Perches			}
30790a920b5bSAndy Whitcroft		}
30800a920b5bSAndy Whitcroft
308122f2a2efSAndy Whitcroft# check spacing on square brackets
308222f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
30833705ce5bSJoe Perches			if (ERROR("SPACING",
30843705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
30853705ce5bSJoe Perches			    $fix) {
30863705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30873705ce5bSJoe Perches				    s/\[\s+/\[/;
30883705ce5bSJoe Perches			}
308922f2a2efSAndy Whitcroft		}
309022f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
30913705ce5bSJoe Perches			if (ERROR("SPACING",
30923705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
30933705ce5bSJoe Perches			    $fix) {
30943705ce5bSJoe Perches				$fixed[$linenr - 1] =~
30953705ce5bSJoe Perches				    s/\s+\]/\]/;
30963705ce5bSJoe Perches			}
309722f2a2efSAndy Whitcroft		}
309822f2a2efSAndy Whitcroft
3099c45dcabdSAndy Whitcroft# check spacing on parentheses
31009c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
31019c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
31023705ce5bSJoe Perches			if (ERROR("SPACING",
31033705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
31043705ce5bSJoe Perches			    $fix) {
31053705ce5bSJoe Perches				$fixed[$linenr - 1] =~
31063705ce5bSJoe Perches				    s/\(\s+/\(/;
31073705ce5bSJoe Perches			}
310822f2a2efSAndy Whitcroft		}
310913214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
3110c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
3111c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
31123705ce5bSJoe Perches			if (ERROR("SPACING",
31133705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
31143705ce5bSJoe Perches			    $fix) {
31153705ce5bSJoe Perches				$fixed[$linenr - 1] =~
31163705ce5bSJoe Perches				    s/\s+\)/\)/;
31173705ce5bSJoe Perches			}
311822f2a2efSAndy Whitcroft		}
311922f2a2efSAndy Whitcroft
31200a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
31214a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
31220a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
31233705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
31243705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
31253705ce5bSJoe Perches			    $fix) {
31263705ce5bSJoe Perches				$fixed[$linenr - 1] =~
31273705ce5bSJoe Perches				    s/^(.)\s+/$1/;
31283705ce5bSJoe Perches			}
31290a920b5bSAndy Whitcroft		}
31300a920b5bSAndy Whitcroft
3131c45dcabdSAndy Whitcroft# Return is not a function.
3132c45dcabdSAndy Whitcroft		if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
3133c45dcabdSAndy Whitcroft			my $spacing = $1;
3134c45dcabdSAndy Whitcroft			my $value = $2;
3135c45dcabdSAndy Whitcroft
313686f9d059SAndy Whitcroft			# Flatten any parentheses
3137fb2d2c1bSAndy Whitcroft			$value =~ s/\(/ \(/g;
3138fb2d2c1bSAndy Whitcroft			$value =~ s/\)/\) /g;
3139e01886adSAndy Whitcroft			while ($value =~ s/\[[^\[\]]*\]/1/ ||
314063f17f89SAndy Whitcroft			       $value !~ /(?:$Ident|-?$Constant)\s*
314163f17f89SAndy Whitcroft					     $Compare\s*
314263f17f89SAndy Whitcroft					     (?:$Ident|-?$Constant)/x &&
314363f17f89SAndy Whitcroft			       $value =~ s/\([^\(\)]*\)/1/) {
3144c45dcabdSAndy Whitcroft			}
3145fb2d2c1bSAndy Whitcroft#print "value<$value>\n";
3146fb2d2c1bSAndy Whitcroft			if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
3147000d1cc1SJoe Perches				ERROR("RETURN_PARENTHESES",
3148000d1cc1SJoe Perches				      "return is not a function, parentheses are not required\n" . $herecurr);
3149c45dcabdSAndy Whitcroft
3150c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
3151000d1cc1SJoe Perches				ERROR("SPACING",
3152000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
3153c45dcabdSAndy Whitcroft			}
3154c45dcabdSAndy Whitcroft		}
315553a3c448SAndy Whitcroft# Return of what appears to be an errno should normally be -'ve
315653a3c448SAndy Whitcroft		if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
315753a3c448SAndy Whitcroft			my $name = $1;
315853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
3159000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
3160000d1cc1SJoe Perches				     "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
316153a3c448SAndy Whitcroft			}
316253a3c448SAndy Whitcroft		}
3163c45dcabdSAndy Whitcroft
31640a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
31654a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
31663705ce5bSJoe Perches			if (ERROR("SPACING",
31673705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
31683705ce5bSJoe Perches			    $fix) {
31693705ce5bSJoe Perches				$fixed[$linenr - 1] =~
31703705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
31713705ce5bSJoe Perches			}
31720a920b5bSAndy Whitcroft		}
31730a920b5bSAndy Whitcroft
3174f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
3175f5fe35ddSAndy Whitcroft# statements after the conditional.
3176170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
31773e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
31783e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
31793e469cdcSAndy Whitcroft					if (!defined $stat);
3180170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
3181170d3a22SAndy Whitcroft						$remain_next, $off_next);
3182170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
3183170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
3184170d3a22SAndy Whitcroft
3185170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
3186170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
3187170d3a22SAndy Whitcroft				# then count those as offsets.
3188170d3a22SAndy Whitcroft				my ($whitespace) =
3189170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
3190170d3a22SAndy Whitcroft				my $offset =
3191170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
3192170d3a22SAndy Whitcroft
3193170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
3194170d3a22SAndy Whitcroft								$offset} = 1;
3195170d3a22SAndy Whitcroft			}
3196170d3a22SAndy Whitcroft		}
3197170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
3198170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
3199171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
32008905a67cSAndy Whitcroft
3201b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
3202000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
3203000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
32048905a67cSAndy Whitcroft			}
32058905a67cSAndy Whitcroft
32068905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
32078905a67cSAndy Whitcroft			# conditional.
3208773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
32098905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
321013214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
321153210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
321253210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
3213773647a0SAndy Whitcroft			{
3214bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
3215bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
3216bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
321742bdf74cSHidetoshi Seto				my $stat_real = '';
3218bb44ad39SAndy Whitcroft
321942bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
322042bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
3221bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
3222bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
3223bb44ad39SAndy Whitcroft				}
3224bb44ad39SAndy Whitcroft
3225000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3226000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
32278905a67cSAndy Whitcroft			}
32288905a67cSAndy Whitcroft		}
32298905a67cSAndy Whitcroft
323013214adfSAndy Whitcroft# Check for bitwise tests written as boolean
323113214adfSAndy Whitcroft		if ($line =~ /
323213214adfSAndy Whitcroft			(?:
323313214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
323413214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
323513214adfSAndy Whitcroft				(?:\&\&|\|\|)
323613214adfSAndy Whitcroft			|
323713214adfSAndy Whitcroft				(?:\&\&|\|\|)
323813214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
323913214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
324013214adfSAndy Whitcroft			)/x)
324113214adfSAndy Whitcroft		{
3242000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
3243000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
324413214adfSAndy Whitcroft		}
324513214adfSAndy Whitcroft
32468905a67cSAndy Whitcroft# if and else should not have general statements after it
324713214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
324813214adfSAndy Whitcroft			my $s = $1;
324913214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
325013214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3251000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
3252000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
32530a920b5bSAndy Whitcroft			}
325413214adfSAndy Whitcroft		}
325539667782SAndy Whitcroft# if should not continue a brace
325639667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
3257000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3258000d1cc1SJoe Perches			      "trailing statements should be on next line\n" .
325939667782SAndy Whitcroft				$herecurr);
326039667782SAndy Whitcroft		}
3261a1080bf8SAndy Whitcroft# case and default should not have general statements after them
3262a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3263a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
32643fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3265a1080bf8SAndy Whitcroft			\s*return\s+
3266a1080bf8SAndy Whitcroft		    )/xg)
3267a1080bf8SAndy Whitcroft		{
3268000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
3269000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
3270a1080bf8SAndy Whitcroft		}
32710a920b5bSAndy Whitcroft
32720a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
32730a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
32740a920b5bSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
32750a920b5bSAndy Whitcroft						$previndent == $indent) {
3276000d1cc1SJoe Perches			ERROR("ELSE_AFTER_BRACE",
3277000d1cc1SJoe Perches			      "else should follow close brace '}'\n" . $hereprev);
32780a920b5bSAndy Whitcroft		}
32790a920b5bSAndy Whitcroft
3280c2fdda0dSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3281c2fdda0dSAndy Whitcroft						$previndent == $indent) {
3282c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3283c2fdda0dSAndy Whitcroft
3284c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
3285c2fdda0dSAndy Whitcroft			# conditional.
3286773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
3287c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
3288c2fdda0dSAndy Whitcroft
3289c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
3290000d1cc1SJoe Perches				ERROR("WHILE_AFTER_BRACE",
3291000d1cc1SJoe Perches				      "while should follow close brace '}'\n" . $hereprev);
3292c2fdda0dSAndy Whitcroft			}
3293c2fdda0dSAndy Whitcroft		}
3294c2fdda0dSAndy Whitcroft
329595e2c602SJoe Perches#Specific variable tests
3296323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
3297323c1260SJoe Perches			my $var = $1;
329895e2c602SJoe Perches
329995e2c602SJoe Perches#gcc binary extension
330095e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
3301d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
3302d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
3303d5e616fcSJoe Perches				    $fix) {
3304d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
3305d5e616fcSJoe Perches					$fixed[$linenr - 1] =~
3306d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
3307d5e616fcSJoe Perches				}
330895e2c602SJoe Perches			}
330995e2c602SJoe Perches
331095e2c602SJoe Perches#CamelCase
3311807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
3312be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
331322735ce8SJoe Perches#Ignore Page<foo> variants
3314807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
331522735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
33163445686aSJoe Perches			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
33177e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
33187e781f67SJoe Perches					my $word = $1;
33197e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
33203445686aSJoe Perches					seed_camelcase_includes() if ($check);
33217e781f67SJoe Perches					if (!defined $camelcase{$word}) {
33227e781f67SJoe Perches						$camelcase{$word} = 1;
3323be79794bSJoe Perches						CHK("CAMELCASE",
33247e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
33257e781f67SJoe Perches					}
3326323c1260SJoe Perches				}
3327323c1260SJoe Perches			}
33283445686aSJoe Perches		}
33290a920b5bSAndy Whitcroft
33300a920b5bSAndy Whitcroft#no spaces allowed after \ in define
3331d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
3332d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3333d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
3334d5e616fcSJoe Perches			    $fix) {
3335d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\s+$//;
3336d5e616fcSJoe Perches			}
33370a920b5bSAndy Whitcroft		}
33380a920b5bSAndy Whitcroft
3339653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
3340c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
3341e09dec48SAndy Whitcroft			my $file = "$1.h";
3342e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
3343e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
3344e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
33457840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
3346c45dcabdSAndy Whitcroft			{
3347e09dec48SAndy Whitcroft				if ($realfile =~ m{^arch/}) {
3348000d1cc1SJoe Perches					CHK("ARCH_INCLUDE_LINUX",
3349000d1cc1SJoe Perches					    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3350e09dec48SAndy Whitcroft				} else {
3351000d1cc1SJoe Perches					WARN("INCLUDE_LINUX",
3352000d1cc1SJoe Perches					     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3353e09dec48SAndy Whitcroft				}
33540a920b5bSAndy Whitcroft			}
33550a920b5bSAndy Whitcroft		}
33560a920b5bSAndy Whitcroft
3357653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
3358653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
3359cf655043SAndy Whitcroft# in a known good container
3360b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
3361b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3362d8aaf121SAndy Whitcroft			my $ln = $linenr;
3363d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
3364c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
3365c45dcabdSAndy Whitcroft			my $ctx = '';
3366c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
3367f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3368f74bd194SAndy Whitcroft			$ctx = $dstat;
3369c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3370a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3371c45dcabdSAndy Whitcroft
3372f74bd194SAndy Whitcroft			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3373292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
3374c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
3375c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
3376c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
3377c45dcabdSAndy Whitcroft
3378c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
3379bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3380bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
3381c81769fdSAndy Whitcroft			       $dstat =~ s/\[[^\[\]]*\]/1/)
3382bf30d6edSAndy Whitcroft			{
3383c45dcabdSAndy Whitcroft			}
3384c45dcabdSAndy Whitcroft
3385e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
3386e45bab8eSAndy Whitcroft			while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3387e45bab8eSAndy Whitcroft			       $dstat =~ s/$Ident\s*("X*")/$1/)
3388e45bab8eSAndy Whitcroft			{
3389e45bab8eSAndy Whitcroft			}
3390e45bab8eSAndy Whitcroft
3391c45dcabdSAndy Whitcroft			my $exceptions = qr{
3392c45dcabdSAndy Whitcroft				$Declare|
3393c45dcabdSAndy Whitcroft				module_param_named|
3394a0a0a7a9SKees Cook				MODULE_PARM_DESC|
3395c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
3396c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
3397383099fdSAndy Whitcroft				__typeof__\(|
339822fd2d3eSStefani Seibold				union|
339922fd2d3eSStefani Seibold				struct|
3400ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
3401ea71a0a0SAndy Whitcroft				^\"|\"$
3402c45dcabdSAndy Whitcroft			}x;
34035eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3404f74bd194SAndy Whitcroft			if ($dstat ne '' &&
3405f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
3406f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
34073cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3408b9df76acSAndy Whitcroft			    $dstat !~ /^'X'$/ &&					# character constants
3409f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
3410f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
3411e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
341272f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
3413f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
3414f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
3415f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
3416f74bd194SAndy Whitcroft			    $dstat !~ /^\({/)						# ({...
3417c45dcabdSAndy Whitcroft			{
3418f74bd194SAndy Whitcroft				$ctx =~ s/\n*$//;
3419f74bd194SAndy Whitcroft				my $herectx = $here . "\n";
3420f74bd194SAndy Whitcroft				my $cnt = statement_rawlines($ctx);
3421f74bd194SAndy Whitcroft
3422f74bd194SAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
3423f74bd194SAndy Whitcroft					$herectx .= raw_line($linenr, $n) . "\n";
3424c45dcabdSAndy Whitcroft				}
3425c45dcabdSAndy Whitcroft
3426f74bd194SAndy Whitcroft				if ($dstat =~ /;/) {
3427f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3428f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3429f74bd194SAndy Whitcroft				} else {
3430000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
3431f74bd194SAndy Whitcroft					      "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3432d8aaf121SAndy Whitcroft				}
34330a920b5bSAndy Whitcroft			}
34345023d347SJoe Perches
3435481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
34365023d347SJoe Perches
34375023d347SJoe Perches		} else {
34385023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
3439481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
3440481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
34415023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
34425023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
34435023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
34445023d347SJoe Perches			}
3445653d4876SAndy Whitcroft		}
34460a920b5bSAndy Whitcroft
3447b13edf7fSJoe Perches# do {} while (0) macro tests:
3448b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
3449b13edf7fSJoe Perches# macro should not end with a semicolon
3450b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3451b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
3452b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3453b13edf7fSJoe Perches			my $ln = $linenr;
3454b13edf7fSJoe Perches			my $cnt = $realcnt;
3455b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
3456b13edf7fSJoe Perches			my $ctx = '';
3457b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
3458b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
3459b13edf7fSJoe Perches			$ctx = $dstat;
3460b13edf7fSJoe Perches
3461b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
3462b13edf7fSJoe Perches
3463b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3464b13edf7fSJoe Perches				my $stmts = $2;
3465b13edf7fSJoe Perches				my $semis = $3;
3466b13edf7fSJoe Perches
3467b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
3468b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
3469b13edf7fSJoe Perches				my $herectx = $here . "\n";
3470b13edf7fSJoe Perches
3471b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
3472b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
3473b13edf7fSJoe Perches				}
3474b13edf7fSJoe Perches
3475ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
3476ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
3477b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3478b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3479b13edf7fSJoe Perches				}
3480b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
3481b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3482b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3483b13edf7fSJoe Perches				}
3484b13edf7fSJoe Perches			}
3485b13edf7fSJoe Perches		}
3486b13edf7fSJoe Perches
3487080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
3488080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
3489080ba929SMike Frysinger#	.
3490080ba929SMike Frysinger#	ALIGN(...)
3491080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
3492080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
3493000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
3494000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
3495080ba929SMike Frysinger		}
3496080ba929SMike Frysinger
3497f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
349813214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
349913214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
3500cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
350113214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3502cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3503cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
3504aad4f614SJoe Perches				my @allowed = ();
3505aad4f614SJoe Perches				my $allow = 0;
350613214adfSAndy Whitcroft				my $seen = 0;
3507773647a0SAndy Whitcroft				my $herectx = $here . "\n";
3508cf655043SAndy Whitcroft				my $ln = $linenr - 1;
350913214adfSAndy Whitcroft				for my $chunk (@chunks) {
351013214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
351113214adfSAndy Whitcroft
3512773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
3513773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3514773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
3515773647a0SAndy Whitcroft
3516aad4f614SJoe Perches					$allowed[$allow] = 0;
3517773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3518773647a0SAndy Whitcroft
3519773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
3520773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
3521773647a0SAndy Whitcroft
3522773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3523cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
3524cf655043SAndy Whitcroft
3525773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
352613214adfSAndy Whitcroft
352713214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
352813214adfSAndy Whitcroft
3529aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3530cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
3531cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
3532aad4f614SJoe Perches						$allowed[$allow] = 1;
353313214adfSAndy Whitcroft					}
353413214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
3535cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
3536aad4f614SJoe Perches						$allowed[$allow] = 1;
353713214adfSAndy Whitcroft					}
3538cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
3539cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
3540aad4f614SJoe Perches						$allowed[$allow] = 1;
354113214adfSAndy Whitcroft					}
3542aad4f614SJoe Perches					$allow++;
354313214adfSAndy Whitcroft				}
3544aad4f614SJoe Perches				if ($seen) {
3545aad4f614SJoe Perches					my $sum_allowed = 0;
3546aad4f614SJoe Perches					foreach (@allowed) {
3547aad4f614SJoe Perches						$sum_allowed += $_;
3548aad4f614SJoe Perches					}
3549aad4f614SJoe Perches					if ($sum_allowed == 0) {
3550000d1cc1SJoe Perches						WARN("BRACES",
3551000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
3552aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
3553aad4f614SJoe Perches						 $seen != $allow) {
3554aad4f614SJoe Perches						CHK("BRACES",
3555aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
3556aad4f614SJoe Perches					}
355713214adfSAndy Whitcroft				}
355813214adfSAndy Whitcroft			}
355913214adfSAndy Whitcroft		}
3560773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
356113214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
3562cf655043SAndy Whitcroft			my $allowed = 0;
3563f0a594c1SAndy Whitcroft
3564cf655043SAndy Whitcroft			# Check the pre-context.
3565cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3566cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
3567cf655043SAndy Whitcroft				$allowed = 1;
3568f0a594c1SAndy Whitcroft			}
3569773647a0SAndy Whitcroft
3570773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
3571773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
3572773647a0SAndy Whitcroft
3573cf655043SAndy Whitcroft			# Check the condition.
3574cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
3575773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3576cf655043SAndy Whitcroft			if (defined $cond) {
3577773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
3578cf655043SAndy Whitcroft			}
3579cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
3580cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
3581cf655043SAndy Whitcroft				$allowed = 1;
3582cf655043SAndy Whitcroft			}
3583cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
3584cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
3585cf655043SAndy Whitcroft				$allowed = 1;
3586cf655043SAndy Whitcroft			}
3587cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
3588cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
3589cf655043SAndy Whitcroft				$allowed = 1;
3590cf655043SAndy Whitcroft			}
3591cf655043SAndy Whitcroft			# Check the post-context.
3592cf655043SAndy Whitcroft			if (defined $chunks[1]) {
3593cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
3594cf655043SAndy Whitcroft				if (defined $cond) {
3595773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
3596cf655043SAndy Whitcroft				}
3597cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
3598cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
3599cf655043SAndy Whitcroft					$allowed = 1;
3600cf655043SAndy Whitcroft				}
3601cf655043SAndy Whitcroft			}
3602cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
360369932487SJustin P. Mattock				my $herectx = $here . "\n";
3604f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
3605cf655043SAndy Whitcroft
3606f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
360769932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
3608cf655043SAndy Whitcroft				}
3609cf655043SAndy Whitcroft
3610000d1cc1SJoe Perches				WARN("BRACES",
3611000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
3612f0a594c1SAndy Whitcroft			}
3613f0a594c1SAndy Whitcroft		}
3614f0a594c1SAndy Whitcroft
36150979ae66SJoe Perches# check for unnecessary blank lines around braces
361677b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
36170979ae66SJoe Perches			CHK("BRACES",
36180979ae66SJoe Perches			    "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
36190979ae66SJoe Perches		}
362077b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
36210979ae66SJoe Perches			CHK("BRACES",
36220979ae66SJoe Perches			    "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
36230979ae66SJoe Perches		}
36240979ae66SJoe Perches
36254a0df2efSAndy Whitcroft# no volatiles please
36266c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
36276c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
3628000d1cc1SJoe Perches			WARN("VOLATILE",
3629000d1cc1SJoe Perches			     "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
36304a0df2efSAndy Whitcroft		}
36314a0df2efSAndy Whitcroft
363200df344fSAndy Whitcroft# warn about #if 0
3633c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3634000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
3635000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
3636de7d4f0eSAndy Whitcroft				$herecurr);
36374a0df2efSAndy Whitcroft		}
36384a0df2efSAndy Whitcroft
363903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
364003df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
364103df4b51SAndy Whitcroft			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
364203df4b51SAndy Whitcroft			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
364303df4b51SAndy Whitcroft				WARN('NEEDLESS_IF',
364403df4b51SAndy Whitcroft				     "$1(NULL) is safe this check is probably not required\n" . $hereprev);
36454c432a8fSGreg Kroah-Hartman			}
36464c432a8fSGreg Kroah-Hartman		}
3647f0a594c1SAndy Whitcroft
36481a15a250SPatrick Pannuto# prefer usleep_range over udelay
364937581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
36501a15a250SPatrick Pannuto			# ignore udelay's < 10, however
365137581c28SBruce Allan			if (! ($1 < 10) ) {
3652000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
3653000d1cc1SJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
36541a15a250SPatrick Pannuto			}
36551a15a250SPatrick Pannuto		}
36561a15a250SPatrick Pannuto
365709ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
365809ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
365909ef8725SPatrick Pannuto			if ($1 < 20) {
3660000d1cc1SJoe Perches				WARN("MSLEEP",
3661000d1cc1SJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
366209ef8725SPatrick Pannuto			}
366309ef8725SPatrick Pannuto		}
366409ef8725SPatrick Pannuto
366536ec1939SJoe Perches# check for comparisons of jiffies
366636ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
366736ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
366836ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
366936ec1939SJoe Perches		}
367036ec1939SJoe Perches
36719d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
36729d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
36739d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
36749d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
36759d7a34a5SJoe Perches		}
36769d7a34a5SJoe Perches
367700df344fSAndy Whitcroft# warn about #ifdefs in C files
3678c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
367900df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
368000df344fSAndy Whitcroft#			print "$herecurr";
368100df344fSAndy Whitcroft#			$clean = 0;
368200df344fSAndy Whitcroft#		}
368300df344fSAndy Whitcroft
368422f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
3685c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
36863705ce5bSJoe Perches			if (ERROR("SPACING",
36873705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
36883705ce5bSJoe Perches			    $fix) {
36893705ce5bSJoe Perches				$fixed[$linenr - 1] =~
36903705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
36913705ce5bSJoe Perches			}
36923705ce5bSJoe Perches
369322f2a2efSAndy Whitcroft		}
369422f2a2efSAndy Whitcroft
36954a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
3696171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
3697171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
36984a0df2efSAndy Whitcroft			my $which = $1;
36994a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3700000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
3701000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
37024a0df2efSAndy Whitcroft			}
37034a0df2efSAndy Whitcroft		}
37044a0df2efSAndy Whitcroft# check for memory barriers without a comment.
37054a0df2efSAndy Whitcroft		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
37064a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
3707000d1cc1SJoe Perches				CHK("MEMORY_BARRIER",
3708000d1cc1SJoe Perches				    "memory barrier without comment\n" . $herecurr);
37094a0df2efSAndy Whitcroft			}
37104a0df2efSAndy Whitcroft		}
37114a0df2efSAndy Whitcroft# check of hardware specific defines
3712c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
3713000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
3714000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
37150a920b5bSAndy Whitcroft		}
3716653d4876SAndy Whitcroft
3717d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
3718d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3719000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
3720000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
3721d4977c78STobias Klauser		}
3722d4977c78STobias Klauser
3723de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
3724de7d4f0eSAndy Whitcroft# storage class and type.
37259c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
37269c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
3727000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
3728000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
3729de7d4f0eSAndy Whitcroft		}
3730de7d4f0eSAndy Whitcroft
37318905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
37328905a67cSAndy Whitcroft		if ($line =~ /\b(__inline__|__inline)\b/) {
3733d5e616fcSJoe Perches			if (WARN("INLINE",
3734d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
3735d5e616fcSJoe Perches			    $fix) {
3736d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
3737d5e616fcSJoe Perches
3738d5e616fcSJoe Perches			}
37398905a67cSAndy Whitcroft		}
37408905a67cSAndy Whitcroft
37413d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
37423d130fd0SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3743000d1cc1SJoe Perches			WARN("PREFER_PACKED",
3744000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
37453d130fd0SJoe Perches		}
37463d130fd0SJoe Perches
374739b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
374839b7e287SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3749000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
3750000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
375139b7e287SJoe Perches		}
375239b7e287SJoe Perches
37535f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
37545f14d3bdSJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
3755d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
3756d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
3757d5e616fcSJoe Perches			    $fix) {
3758d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
3759d5e616fcSJoe Perches
3760d5e616fcSJoe Perches			}
37615f14d3bdSJoe Perches		}
37625f14d3bdSJoe Perches
37636061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
37646061d949SJoe Perches		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
3765d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
3766d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
3767d5e616fcSJoe Perches			    $fix) {
3768d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
3769d5e616fcSJoe Perches			}
37706061d949SJoe Perches		}
37716061d949SJoe Perches
37728f53a9b8SJoe Perches# check for sizeof(&)
37738f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
3774000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
3775000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
37768f53a9b8SJoe Perches		}
37778f53a9b8SJoe Perches
377866c80b60SJoe Perches# check for sizeof without parenthesis
377966c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
3780d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
3781d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
3782d5e616fcSJoe Perches			    $fix) {
3783d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
3784d5e616fcSJoe Perches			}
378566c80b60SJoe Perches		}
378666c80b60SJoe Perches
3787428e2fdcSJoe Perches# check for line continuations in quoted strings with odd counts of "
3788428e2fdcSJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3789000d1cc1SJoe Perches			WARN("LINE_CONTINUATIONS",
3790000d1cc1SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
3791428e2fdcSJoe Perches		}
3792428e2fdcSJoe Perches
379388982feaSJoe Perches# check for struct spinlock declarations
379488982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
379588982feaSJoe Perches			WARN("USE_SPINLOCK_T",
379688982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
379788982feaSJoe Perches		}
379888982feaSJoe Perches
3799a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
3800a6962d72SJoe Perches		if ($line =~ /\bseq_printf\s*\(/) {
3801a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
3802a6962d72SJoe Perches			if ($fmt !~ /[^\\]\%/) {
3803d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
3804d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
3805d5e616fcSJoe Perches				    $fix) {
3806d5e616fcSJoe Perches					$fixed[$linenr - 1] =~ s/\bseq_printf\b/seq_puts/;
3807d5e616fcSJoe Perches				}
3808a6962d72SJoe Perches			}
3809a6962d72SJoe Perches		}
3810a6962d72SJoe Perches
3811554e165cSAndy Whitcroft# Check for misused memsets
3812d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3813d1fe9c09SJoe Perches		    defined $stat &&
3814d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3815554e165cSAndy Whitcroft
3816d7c76ba7SJoe Perches			my $ms_addr = $2;
3817d1fe9c09SJoe Perches			my $ms_val = $7;
3818d1fe9c09SJoe Perches			my $ms_size = $12;
3819d7c76ba7SJoe Perches
3820554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
3821554e165cSAndy Whitcroft				ERROR("MEMSET",
3822d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3823554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
3824554e165cSAndy Whitcroft				WARN("MEMSET",
3825d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3826d7c76ba7SJoe Perches			}
3827d7c76ba7SJoe Perches		}
3828d7c76ba7SJoe Perches
3829d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
3830d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3831d1fe9c09SJoe Perches		    defined $stat &&
3832d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3833d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
3834d7c76ba7SJoe Perches				my $call = $1;
3835d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
3836d7c76ba7SJoe Perches				my $arg1 = $3;
3837d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
3838d1fe9c09SJoe Perches				my $arg2 = $8;
3839d7c76ba7SJoe Perches				my $cast;
3840d7c76ba7SJoe Perches
3841d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3842d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
3843d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
3844d7c76ba7SJoe Perches					$cast = $cast1;
3845d7c76ba7SJoe Perches				} else {
3846d7c76ba7SJoe Perches					$cast = $cast2;
3847d7c76ba7SJoe Perches				}
3848d7c76ba7SJoe Perches				WARN("MINMAX",
3849d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3850554e165cSAndy Whitcroft			}
3851554e165cSAndy Whitcroft		}
3852554e165cSAndy Whitcroft
38534a273195SJoe Perches# check usleep_range arguments
38544a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
38554a273195SJoe Perches		    defined $stat &&
38564a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
38574a273195SJoe Perches			my $min = $1;
38584a273195SJoe Perches			my $max = $7;
38594a273195SJoe Perches			if ($min eq $max) {
38604a273195SJoe Perches				WARN("USLEEP_RANGE",
38614a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
38624a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
38634a273195SJoe Perches				 $min > $max) {
38644a273195SJoe Perches				WARN("USLEEP_RANGE",
38654a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
38664a273195SJoe Perches			}
38674a273195SJoe Perches		}
38684a273195SJoe Perches
3869de7d4f0eSAndy Whitcroft# check for new externs in .c files.
3870171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
3871c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
3872171ae1a4SAndy Whitcroft		{
3873c45dcabdSAndy Whitcroft			my $function_name = $1;
3874c45dcabdSAndy Whitcroft			my $paren_space = $2;
3875171ae1a4SAndy Whitcroft
3876171ae1a4SAndy Whitcroft			my $s = $stat;
3877171ae1a4SAndy Whitcroft			if (defined $cond) {
3878171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
3879171ae1a4SAndy Whitcroft			}
3880c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
3881c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
3882c45dcabdSAndy Whitcroft			{
3883000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
3884000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
3885de7d4f0eSAndy Whitcroft			}
3886de7d4f0eSAndy Whitcroft
3887171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
3888000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
3889000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
3890171ae1a4SAndy Whitcroft			}
38919c9ba34eSAndy Whitcroft
38929c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
38939c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
38949c9ba34eSAndy Whitcroft		{
3895000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
3896000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
3897171ae1a4SAndy Whitcroft		}
3898171ae1a4SAndy Whitcroft
3899de7d4f0eSAndy Whitcroft# checks for new __setup's
3900de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
3901de7d4f0eSAndy Whitcroft			my $name = $1;
3902de7d4f0eSAndy Whitcroft
3903de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
3904000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
3905000d1cc1SJoe Perches				    "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
3906de7d4f0eSAndy Whitcroft			}
3907653d4876SAndy Whitcroft		}
39089c0ca6f9SAndy Whitcroft
39099c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
3910caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
3911000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
3912000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
39139c0ca6f9SAndy Whitcroft		}
391413214adfSAndy Whitcroft
3915a640d25cSJoe Perches# alloc style
3916a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
3917a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
3918a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
3919a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
3920a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
3921a640d25cSJoe Perches		}
3922a640d25cSJoe Perches
3923972fdea2SJoe Perches# check for krealloc arg reuse
3924972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3925972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
3926972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
3927972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
3928972fdea2SJoe Perches		}
3929972fdea2SJoe Perches
39305ce59ae0SJoe Perches# check for alloc argument mismatch
39315ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
39325ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
39335ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
39345ce59ae0SJoe Perches		}
39355ce59ae0SJoe Perches
3936caf2a54fSJoe Perches# check for multiple semicolons
3937caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
3938d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
3939d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
3940d5e616fcSJoe Perches			    $fix) {
3941d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
3942d5e616fcSJoe Perches			}
3943d1e2ad07SJoe Perches		}
3944d1e2ad07SJoe Perches
3945d1e2ad07SJoe Perches# check for switch/default statements without a break;
3946d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
3947d1e2ad07SJoe Perches		    defined $stat &&
3948d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
3949d1e2ad07SJoe Perches			my $ctx = '';
3950d1e2ad07SJoe Perches			my $herectx = $here . "\n";
3951d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
3952d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
3953d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
3954d1e2ad07SJoe Perches			}
3955d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
3956d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
3957caf2a54fSJoe Perches		}
3958caf2a54fSJoe Perches
395913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
3960d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
3961d5e616fcSJoe Perches			if (WARN("USE_FUNC",
3962d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
3963d5e616fcSJoe Perches			    $fix) {
3964d5e616fcSJoe Perches				$fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g;
3965d5e616fcSJoe Perches			}
396613214adfSAndy Whitcroft		}
3967773647a0SAndy Whitcroft
39682c92488aSJoe Perches# check for use of yield()
39692c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
39702c92488aSJoe Perches			WARN("YIELD",
39712c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
39722c92488aSJoe Perches		}
39732c92488aSJoe Perches
3974179f8f40SJoe Perches# check for comparisons against true and false
3975179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
3976179f8f40SJoe Perches			my $lead = $1;
3977179f8f40SJoe Perches			my $arg = $2;
3978179f8f40SJoe Perches			my $test = $3;
3979179f8f40SJoe Perches			my $otype = $4;
3980179f8f40SJoe Perches			my $trail = $5;
3981179f8f40SJoe Perches			my $op = "!";
3982179f8f40SJoe Perches
3983179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
3984179f8f40SJoe Perches
3985179f8f40SJoe Perches			my $type = lc($otype);
3986179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
3987179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
3988179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
3989179f8f40SJoe Perches					$op = "";
3990179f8f40SJoe Perches				}
3991179f8f40SJoe Perches
3992179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
3993179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
3994179f8f40SJoe Perches
3995179f8f40SJoe Perches## maybe suggesting a correct construct would better
3996179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
3997179f8f40SJoe Perches
3998179f8f40SJoe Perches			}
3999179f8f40SJoe Perches		}
4000179f8f40SJoe Perches
40014882720bSThomas Gleixner# check for semaphores initialized locked
40024882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
4003000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
4004000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
4005773647a0SAndy Whitcroft		}
40066712d858SJoe Perches
400767d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
400867d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
4009000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
401067d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
4011773647a0SAndy Whitcroft		}
40126712d858SJoe Perches
4013f3db6639SMichael Ellerman# check for __initcall(), use device_initcall() explicitly please
4014f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
4015000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
4016000d1cc1SJoe Perches			     "please use device_initcall() instead of __initcall()\n" . $herecurr);
4017f3db6639SMichael Ellerman		}
40186712d858SJoe Perches
401979404849SEmese Revfy# check for various ops structs, ensure they are const.
402079404849SEmese Revfy		my $struct_ops = qr{acpi_dock_ops|
402179404849SEmese Revfy				address_space_operations|
402279404849SEmese Revfy				backlight_ops|
402379404849SEmese Revfy				block_device_operations|
402479404849SEmese Revfy				dentry_operations|
402579404849SEmese Revfy				dev_pm_ops|
402679404849SEmese Revfy				dma_map_ops|
402779404849SEmese Revfy				extent_io_ops|
402879404849SEmese Revfy				file_lock_operations|
402979404849SEmese Revfy				file_operations|
403079404849SEmese Revfy				hv_ops|
403179404849SEmese Revfy				ide_dma_ops|
403279404849SEmese Revfy				intel_dvo_dev_ops|
403379404849SEmese Revfy				item_operations|
403479404849SEmese Revfy				iwl_ops|
403579404849SEmese Revfy				kgdb_arch|
403679404849SEmese Revfy				kgdb_io|
403779404849SEmese Revfy				kset_uevent_ops|
403879404849SEmese Revfy				lock_manager_operations|
403979404849SEmese Revfy				microcode_ops|
404079404849SEmese Revfy				mtrr_ops|
404179404849SEmese Revfy				neigh_ops|
404279404849SEmese Revfy				nlmsvc_binding|
404379404849SEmese Revfy				pci_raw_ops|
404479404849SEmese Revfy				pipe_buf_operations|
404579404849SEmese Revfy				platform_hibernation_ops|
404679404849SEmese Revfy				platform_suspend_ops|
404779404849SEmese Revfy				proto_ops|
404879404849SEmese Revfy				rpc_pipe_ops|
404979404849SEmese Revfy				seq_operations|
405079404849SEmese Revfy				snd_ac97_build_ops|
405179404849SEmese Revfy				soc_pcmcia_socket_ops|
405279404849SEmese Revfy				stacktrace_ops|
405379404849SEmese Revfy				sysfs_ops|
405479404849SEmese Revfy				tty_operations|
405579404849SEmese Revfy				usb_mon_operations|
405679404849SEmese Revfy				wd_ops}x;
40576903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
405879404849SEmese Revfy		    $line =~ /\bstruct\s+($struct_ops)\b/) {
4059000d1cc1SJoe Perches			WARN("CONST_STRUCT",
4060000d1cc1SJoe Perches			     "struct $1 should normally be const\n" .
40616903ffb2SAndy Whitcroft				$herecurr);
40622b6db5cbSAndy Whitcroft		}
4063773647a0SAndy Whitcroft
4064773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
4065773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
4066773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
4067c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
4068c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
4069171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
4070171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
4071171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
4072773647a0SAndy Whitcroft		{
4073000d1cc1SJoe Perches			WARN("NR_CPUS",
4074000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
4075773647a0SAndy Whitcroft		}
40769c9ba34eSAndy Whitcroft
40779c9ba34eSAndy Whitcroft# check for %L{u,d,i} in strings
40789c9ba34eSAndy Whitcroft		my $string;
40799c9ba34eSAndy Whitcroft		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
40809c9ba34eSAndy Whitcroft			$string = substr($rawline, $-[1], $+[1] - $-[1]);
40812a1bc5d5SAndy Whitcroft			$string =~ s/%%/__/g;
40829c9ba34eSAndy Whitcroft			if ($string =~ /(?<!%)%L[udi]/) {
4083000d1cc1SJoe Perches				WARN("PRINTF_L",
4084000d1cc1SJoe Perches				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
40859c9ba34eSAndy Whitcroft				last;
40869c9ba34eSAndy Whitcroft			}
40879c9ba34eSAndy Whitcroft		}
4088691d77b6SAndy Whitcroft
4089691d77b6SAndy Whitcroft# whine mightly about in_atomic
4090691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
4091691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
4092000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
4093000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
4094f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
4095000d1cc1SJoe Perches				WARN("IN_ATOMIC",
4096000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
4097691d77b6SAndy Whitcroft			}
4098691d77b6SAndy Whitcroft		}
40991704f47bSPeter Zijlstra
41001704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
41011704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
41021704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
41031704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
41041704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
41051704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
4106000d1cc1SJoe Perches				ERROR("LOCKDEP",
4107000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
41081704f47bSPeter Zijlstra			}
41091704f47bSPeter Zijlstra		}
411088f8831cSDave Jones
411188f8831cSDave Jones		if ($line =~ /debugfs_create_file.*S_IWUGO/ ||
411288f8831cSDave Jones		    $line =~ /DEVICE_ATTR.*S_IWUGO/ ) {
4113000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
4114000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
411588f8831cSDave Jones		}
411613214adfSAndy Whitcroft	}
411713214adfSAndy Whitcroft
411813214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
411913214adfSAndy Whitcroft	# so just keep quiet.
412013214adfSAndy Whitcroft	if ($#rawlines == -1) {
412113214adfSAndy Whitcroft		exit(0);
41220a920b5bSAndy Whitcroft	}
41230a920b5bSAndy Whitcroft
41248905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
41258905a67cSAndy Whitcroft	# things that appear to be patches.
41268905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
41278905a67cSAndy Whitcroft		exit(0);
41288905a67cSAndy Whitcroft	}
41298905a67cSAndy Whitcroft
41308905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
41318905a67cSAndy Whitcroft	# just keep quiet.
41328905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
41338905a67cSAndy Whitcroft		exit(0);
41348905a67cSAndy Whitcroft	}
41358905a67cSAndy Whitcroft
41368905a67cSAndy Whitcroft	if (!$is_patch) {
4137000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
4138000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
41390a920b5bSAndy Whitcroft	}
41400a920b5bSAndy Whitcroft	if ($is_patch && $chk_signoff && $signoff == 0) {
4141000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
4142000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
41430a920b5bSAndy Whitcroft	}
41440a920b5bSAndy Whitcroft
4145f0a594c1SAndy Whitcroft	print report_dump();
414613214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
414713214adfSAndy Whitcroft		print "$filename " if ($summary_file);
41486c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
41496c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
41506c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
41518905a67cSAndy Whitcroft		print "\n" if ($quiet == 0);
41526c72ffaaSAndy Whitcroft	}
41538905a67cSAndy Whitcroft
4154d2c0a235SAndy Whitcroft	if ($quiet == 0) {
4155d1fe9c09SJoe Perches
4156d1fe9c09SJoe Perches		if ($^V lt 5.10.0) {
4157d1fe9c09SJoe Perches			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
4158d1fe9c09SJoe Perches			print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
4159d1fe9c09SJoe Perches		}
4160d1fe9c09SJoe Perches
4161d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
4162d2c0a235SAndy Whitcroft		# then suggest that.
4163d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
4164d2c0a235SAndy Whitcroft			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
4165d2c0a235SAndy Whitcroft			print "      scripts/cleanfile\n\n";
4166b0781216SMike Frysinger			$rpt_cleaners = 0;
4167d2c0a235SAndy Whitcroft		}
4168d2c0a235SAndy Whitcroft	}
4169d2c0a235SAndy Whitcroft
417011232688SArtem Bityutskiy	if ($quiet == 0 && keys %ignore_type) {
4171000d1cc1SJoe Perches	    print "NOTE: Ignored message types:";
4172000d1cc1SJoe Perches	    foreach my $ignore (sort keys %ignore_type) {
4173000d1cc1SJoe Perches		print " $ignore";
4174000d1cc1SJoe Perches	    }
417511232688SArtem Bityutskiy	    print "\n\n";
4176000d1cc1SJoe Perches	}
4177000d1cc1SJoe Perches
41783705ce5bSJoe Perches	if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
41793705ce5bSJoe Perches		my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes";
41803705ce5bSJoe Perches		my $linecount = 0;
41813705ce5bSJoe Perches		my $f;
41823705ce5bSJoe Perches
41833705ce5bSJoe Perches		open($f, '>', $newfile)
41843705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
41853705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
41863705ce5bSJoe Perches			$linecount++;
41873705ce5bSJoe Perches			if ($file) {
41883705ce5bSJoe Perches				if ($linecount > 3) {
41893705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
41903705ce5bSJoe Perches					print $f $fixed_line. "\n";
41913705ce5bSJoe Perches				}
41923705ce5bSJoe Perches			} else {
41933705ce5bSJoe Perches				print $f $fixed_line . "\n";
41943705ce5bSJoe Perches			}
41953705ce5bSJoe Perches		}
41963705ce5bSJoe Perches		close($f);
41973705ce5bSJoe Perches
41983705ce5bSJoe Perches		if (!$quiet) {
41993705ce5bSJoe Perches			print << "EOM";
42003705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
42013705ce5bSJoe Perches
42023705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
42033705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
42043705ce5bSJoe Perches
42053705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
42063705ce5bSJoe PerchesNo warranties, expressed or implied...
42073705ce5bSJoe Perches
42083705ce5bSJoe PerchesEOM
42093705ce5bSJoe Perches		}
42103705ce5bSJoe Perches	}
42113705ce5bSJoe Perches
42120a920b5bSAndy Whitcroft	if ($clean == 1 && $quiet == 0) {
4213c2fdda0dSAndy Whitcroft		print "$vname has no obvious style problems and is ready for submission.\n"
42140a920b5bSAndy Whitcroft	}
42150a920b5bSAndy Whitcroft	if ($clean == 0 && $quiet == 0) {
4216000d1cc1SJoe Perches		print << "EOM";
4217000d1cc1SJoe Perches$vname has style problems, please review.
4218000d1cc1SJoe Perches
4219000d1cc1SJoe PerchesIf any of these errors are false positives, please report
4220000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS.
4221000d1cc1SJoe PerchesEOM
42220a920b5bSAndy Whitcroft	}
422313214adfSAndy Whitcroft
42240a920b5bSAndy Whitcroft	return $clean;
42250a920b5bSAndy Whitcroft}
4226