xref: /linux-6.15/scripts/checkpatch.pl (revision 628f91a2)
1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl
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;
9cb77f0d6SKamil Rytarowskiuse warnings;
10c707a81dSJoe Perchesuse POSIX;
1136061e38SJoe Perchesuse File::Basename;
1236061e38SJoe Perchesuse Cwd 'abs_path';
1357230297SJoe Perchesuse Term::ANSIColor qw(:constants);
140a920b5bSAndy Whitcroft
150a920b5bSAndy Whitcroftmy $P = $0;
1636061e38SJoe Perchesmy $D = dirname(abs_path($P));
170a920b5bSAndy Whitcroft
18000d1cc1SJoe Perchesmy $V = '0.32';
190a920b5bSAndy Whitcroft
200a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
210a920b5bSAndy Whitcroft
220a920b5bSAndy Whitcroftmy $quiet = 0;
230a920b5bSAndy Whitcroftmy $tree = 1;
240a920b5bSAndy Whitcroftmy $chk_signoff = 1;
250a920b5bSAndy Whitcroftmy $chk_patch = 1;
26773647a0SAndy Whitcroftmy $tst_only;
276c72ffaaSAndy Whitcroftmy $emacs = 0;
288905a67cSAndy Whitcroftmy $terse = 0;
2934d8815fSJoe Perchesmy $showfile = 0;
306c72ffaaSAndy Whitcroftmy $file = 0;
314a593c34SDu, Changbinmy $git = 0;
320dea9f1eSJoe Perchesmy %git_commits = ();
336c72ffaaSAndy Whitcroftmy $check = 0;
342ac73b4fSJoe Perchesmy $check_orig = 0;
358905a67cSAndy Whitcroftmy $summary = 1;
368905a67cSAndy Whitcroftmy $mailback = 0;
3713214adfSAndy Whitcroftmy $summary_file = 0;
38000d1cc1SJoe Perchesmy $show_types = 0;
393beb42ecSJoe Perchesmy $list_types = 0;
403705ce5bSJoe Perchesmy $fix = 0;
419624b8d6SJoe Perchesmy $fix_inplace = 0;
426c72ffaaSAndy Whitcroftmy $root;
43c2fdda0dSAndy Whitcroftmy %debug;
443445686aSJoe Perchesmy %camelcase = ();
4591bfe484SJoe Perchesmy %use_type = ();
4691bfe484SJoe Perchesmy @use = ();
4791bfe484SJoe Perchesmy %ignore_type = ();
48000d1cc1SJoe Perchesmy @ignore = ();
4977f5b10aSHannes Edermy $help = 0;
50000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
516cd7f386SJoe Perchesmy $max_line_length = 80;
52d62a201fSDave Hansenmy $ignore_perl_version = 0;
53d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5456193274SVadim Bendeburymy $min_conf_desc_length = 4;
5566b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
56ebfd7d62SJoe Perchesmy $codespell = 0;
57f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
58bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
5975ad8c57SJerome Forissiermy $typedefsfile = "";
6057230297SJoe Perchesmy $color = 1;
61dadf680dSJoe Perchesmy $allow_c99_comments = 1;
6277f5b10aSHannes Eder
6377f5b10aSHannes Edersub help {
6477f5b10aSHannes Eder	my ($exitcode) = @_;
6577f5b10aSHannes Eder
6677f5b10aSHannes Eder	print << "EOM";
6777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
6877f5b10aSHannes EderVersion: $V
6977f5b10aSHannes Eder
7077f5b10aSHannes EderOptions:
7177f5b10aSHannes Eder  -q, --quiet                quiet
7277f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7377f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
7477f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
7577f5b10aSHannes Eder  --emacs                    emacs compile window format
7677f5b10aSHannes Eder  --terse                    one line per report
7734d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
784a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
794a593c34SDu, Changbin                             single git commit with:
804a593c34SDu, Changbin                               <rev>
814a593c34SDu, Changbin                               <rev>^
824a593c34SDu, Changbin                               <rev>~n
834a593c34SDu, Changbin                             multiple git commits with:
844a593c34SDu, Changbin                               <rev1>..<rev2>
854a593c34SDu, Changbin                               <rev1>...<rev2>
864a593c34SDu, Changbin                               <rev>-<count>
874a593c34SDu, Changbin                             git merges are ignored
8877f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
8977f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
903beb42ecSJoe Perches  --list-types               list the possible message types
9191bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
92000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
933beb42ecSJoe Perches  --show-types               show the specific message type in the output
946cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
9556193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
9677f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
9777f5b10aSHannes Eder  --no-summary               suppress the per-file summary
9877f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
9977f5b10aSHannes Eder  --summary-file             include the filename in summary
10077f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
10177f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
10277f5b10aSHannes Eder                             is all off)
10377f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
10477f5b10aSHannes Eder                             literally
1053705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1063705ce5bSJoe Perches                             If correctable single-line errors exist, create
1073705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1083705ce5bSJoe Perches                             with potential errors corrected to the preferred
1093705ce5bSJoe Perches                             checkpatch style
1109624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1119624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1129624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
113d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
114d62a201fSDave Hansen                             runtime errors.
115ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
116f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
117ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
11875ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
11957230297SJoe Perches  --color                    Use colors when output is STDOUT (default: on)
12077f5b10aSHannes Eder  -h, --help, --version      display this help and exit
12177f5b10aSHannes Eder
12277f5b10aSHannes EderWhen FILE is - read standard input.
12377f5b10aSHannes EderEOM
12477f5b10aSHannes Eder
12577f5b10aSHannes Eder	exit($exitcode);
12677f5b10aSHannes Eder}
12777f5b10aSHannes Eder
1283beb42ecSJoe Perchessub uniq {
1293beb42ecSJoe Perches	my %seen;
1303beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1313beb42ecSJoe Perches}
1323beb42ecSJoe Perches
1333beb42ecSJoe Perchessub list_types {
1343beb42ecSJoe Perches	my ($exitcode) = @_;
1353beb42ecSJoe Perches
1363beb42ecSJoe Perches	my $count = 0;
1373beb42ecSJoe Perches
1383beb42ecSJoe Perches	local $/ = undef;
1393beb42ecSJoe Perches
1403beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1413beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1423beb42ecSJoe Perches
1433beb42ecSJoe Perches	my $text = <$script>;
1443beb42ecSJoe Perches	close($script);
1453beb42ecSJoe Perches
1463beb42ecSJoe Perches	my @types = ();
1473beb42ecSJoe Perches	for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) {
1483beb42ecSJoe Perches		push (@types, $_);
1493beb42ecSJoe Perches	}
1503beb42ecSJoe Perches	@types = sort(uniq(@types));
1513beb42ecSJoe Perches	print("#\tMessage type\n\n");
1523beb42ecSJoe Perches	foreach my $type (@types) {
1533beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1543beb42ecSJoe Perches	}
1553beb42ecSJoe Perches
1563beb42ecSJoe Perches	exit($exitcode);
1573beb42ecSJoe Perches}
1583beb42ecSJoe Perches
159000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
160000d1cc1SJoe Perchesif (-f $conf) {
161000d1cc1SJoe Perches	my @conf_args;
162000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
163000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
164000d1cc1SJoe Perches
165000d1cc1SJoe Perches	while (<$conffile>) {
166000d1cc1SJoe Perches		my $line = $_;
167000d1cc1SJoe Perches
168000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
169000d1cc1SJoe Perches		$line =~ s/^\s*//g;
170000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
171000d1cc1SJoe Perches
172000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
173000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
174000d1cc1SJoe Perches
175000d1cc1SJoe Perches		my @words = split(" ", $line);
176000d1cc1SJoe Perches		foreach my $word (@words) {
177000d1cc1SJoe Perches			last if ($word =~ m/^#/);
178000d1cc1SJoe Perches			push (@conf_args, $word);
179000d1cc1SJoe Perches		}
180000d1cc1SJoe Perches	}
181000d1cc1SJoe Perches	close($conffile);
182000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
183000d1cc1SJoe Perches}
184000d1cc1SJoe Perches
1850a920b5bSAndy WhitcroftGetOptions(
1866c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1870a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1880a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1890a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1906c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1918905a67cSAndy Whitcroft	'terse!'	=> \$terse,
19234d8815fSJoe Perches	'showfile!'	=> \$showfile,
19377f5b10aSHannes Eder	'f|file!'	=> \$file,
1944a593c34SDu, Changbin	'g|git!'	=> \$git,
1956c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1966c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
197000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
19891bfe484SJoe Perches	'types=s'	=> \@use,
199000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2003beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2016cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
20256193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
2036c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2048905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2058905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
20613214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2073705ce5bSJoe Perches	'fix!'		=> \$fix,
2089624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
209d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
210c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
211773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
212ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
213ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
21475ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
21557230297SJoe Perches	'color!'	=> \$color,
21677f5b10aSHannes Eder	'h|help'	=> \$help,
21777f5b10aSHannes Eder	'version'	=> \$help
21877f5b10aSHannes Eder) or help(1);
21977f5b10aSHannes Eder
22077f5b10aSHannes Ederhelp(0) if ($help);
2210a920b5bSAndy Whitcroft
2223beb42ecSJoe Percheslist_types(0) if ($list_types);
2233beb42ecSJoe Perches
2249624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2252ac73b4fSJoe Perches$check_orig = $check;
2269624b8d6SJoe Perches
2270a920b5bSAndy Whitcroftmy $exit = 0;
2280a920b5bSAndy Whitcroft
229d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
230d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
231d62a201fSDave Hansen	if (!$ignore_perl_version) {
232d62a201fSDave Hansen		exit(1);
233d62a201fSDave Hansen	}
234d62a201fSDave Hansen}
235d62a201fSDave Hansen
23645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2370a920b5bSAndy Whitcroftif ($#ARGV < 0) {
23845107ff6SAllen Hubbe	push(@ARGV, '-');
2390a920b5bSAndy Whitcroft}
2400a920b5bSAndy Whitcroft
24191bfe484SJoe Perchessub hash_save_array_words {
24291bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
24391bfe484SJoe Perches
24491bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
24591bfe484SJoe Perches	foreach my $word (@array) {
246000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
247000d1cc1SJoe Perches		$word =~ s/^\s*//g;
248000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
249000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
250000d1cc1SJoe Perches
251000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
252000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
253000d1cc1SJoe Perches
25491bfe484SJoe Perches		$hashRef->{$word}++;
255000d1cc1SJoe Perches	}
25691bfe484SJoe Perches}
25791bfe484SJoe Perches
25891bfe484SJoe Perchessub hash_show_words {
25991bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
26091bfe484SJoe Perches
2613c816e49SJoe Perches	if (keys %$hashRef) {
262d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
26358cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
26491bfe484SJoe Perches			print " $word";
26591bfe484SJoe Perches		}
266d8469f16SJoe Perches		print "\n";
26791bfe484SJoe Perches	}
26891bfe484SJoe Perches}
26991bfe484SJoe Perches
27091bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
27191bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
272000d1cc1SJoe Perches
273c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
274c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
2757429c690SAndy Whitcroftmy $dbg_type = 0;
276a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
277c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
27821caa13cSAndy Whitcroft	## no critic
27921caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
28021caa13cSAndy Whitcroft	die "$@" if ($@);
281c2fdda0dSAndy Whitcroft}
282c2fdda0dSAndy Whitcroft
283d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
284d2c0a235SAndy Whitcroft
2858905a67cSAndy Whitcroftif ($terse) {
2868905a67cSAndy Whitcroft	$emacs = 1;
2878905a67cSAndy Whitcroft	$quiet++;
2888905a67cSAndy Whitcroft}
2898905a67cSAndy Whitcroft
2906c72ffaaSAndy Whitcroftif ($tree) {
2916c72ffaaSAndy Whitcroft	if (defined $root) {
2926c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
2936c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
2946c72ffaaSAndy Whitcroft		}
2956c72ffaaSAndy Whitcroft	} else {
2966c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
2976c72ffaaSAndy Whitcroft			$root = '.';
2986c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
2996c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3006c72ffaaSAndy Whitcroft			$root = $1;
3016c72ffaaSAndy Whitcroft		}
3026c72ffaaSAndy Whitcroft	}
3036c72ffaaSAndy Whitcroft
3046c72ffaaSAndy Whitcroft	if (!defined $root) {
3050a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3060a920b5bSAndy Whitcroft		exit(2);
3070a920b5bSAndy Whitcroft	}
3086c72ffaaSAndy Whitcroft}
3096c72ffaaSAndy Whitcroft
3106c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3116c72ffaaSAndy Whitcroft
3122ceb532bSAndy Whitcroftour $Ident	= qr{
3132ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3142ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3152ceb532bSAndy Whitcroft		}x;
3166c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3176c72ffaaSAndy Whitcroftour $Sparse	= qr{
3186c72ffaaSAndy Whitcroft			__user|
3196c72ffaaSAndy Whitcroft			__kernel|
3206c72ffaaSAndy Whitcroft			__force|
3216c72ffaaSAndy Whitcroft			__iomem|
3226c72ffaaSAndy Whitcroft			__must_check|
3236c72ffaaSAndy Whitcroft			__init_refok|
324417495edSAndy Whitcroft			__kprobes|
325165e72a6SSven Eckelmann			__ref|
326ad315455SBoqun Feng			__rcu|
327ad315455SBoqun Feng			__private
3286c72ffaaSAndy Whitcroft		}x;
329e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
330e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
331e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
332e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
333e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3348716de38SJoe Perches
33552131292SWolfram Sang# Notes to $Attribute:
33652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3376c72ffaaSAndy Whitcroftour $Attribute	= qr{
3386c72ffaaSAndy Whitcroft			const|
33903f1df7dSJoe Perches			__percpu|
34003f1df7dSJoe Perches			__nocast|
34103f1df7dSJoe Perches			__safe|
34246d832f5SMichael S. Tsirkin			__bitwise|
34303f1df7dSJoe Perches			__packed__|
34403f1df7dSJoe Perches			__packed2__|
34503f1df7dSJoe Perches			__naked|
34603f1df7dSJoe Perches			__maybe_unused|
34703f1df7dSJoe Perches			__always_unused|
34803f1df7dSJoe Perches			__noreturn|
34903f1df7dSJoe Perches			__used|
35003f1df7dSJoe Perches			__cold|
351e23ef1f3SJoe Perches			__pure|
35203f1df7dSJoe Perches			__noclone|
35303f1df7dSJoe Perches			__deprecated|
3546c72ffaaSAndy Whitcroft			__read_mostly|
3556c72ffaaSAndy Whitcroft			__kprobes|
3568716de38SJoe Perches			$InitAttribute|
35724e1d81aSAndy Whitcroft			____cacheline_aligned|
35824e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3595fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3605fe3af11SAndy Whitcroft			__weak
3616c72ffaaSAndy Whitcroft		  }x;
362c45dcabdSAndy Whitcroftour $Modifier;
36391cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
3646c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
3656c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
3666c72ffaaSAndy Whitcroft
36795e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
36895e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
36995e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
37095e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
3712435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
372c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
373326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
374326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
375326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
37674349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
3772435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
378326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
379447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
38023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
3816c72ffaaSAndy Whitcroftour $Operators	= qr{
3826c72ffaaSAndy Whitcroft			<=|>=|==|!=|
3836c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
38423f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
3856c72ffaaSAndy Whitcroft		  }x;
3866c72ffaaSAndy Whitcroft
38791cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
38891cb5195SJoe Perches
389ab7e23f3SJoe Perchesour $BasicType;
3908905a67cSAndy Whitcroftour $NonptrType;
3911813087dSJoe Perchesour $NonptrTypeMisordered;
3928716de38SJoe Perchesour $NonptrTypeWithAttr;
3938905a67cSAndy Whitcroftour $Type;
3941813087dSJoe Perchesour $TypeMisordered;
3958905a67cSAndy Whitcroftour $Declare;
3961813087dSJoe Perchesour $DeclareMisordered;
3978905a67cSAndy Whitcroft
39815662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
39915662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
400171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
401171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
402171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
403171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
404171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
405171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
406171ae1a4SAndy Whitcroft}x;
407171ae1a4SAndy Whitcroft
40815662b3eSJoe Perchesour $UTF8	= qr{
40915662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
41015662b3eSJoe Perches	| $NON_ASCII_UTF8
41115662b3eSJoe Perches}x;
41215662b3eSJoe Perches
413e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
414021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
415021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
416021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
417021158b4SJoe Perches)};
418e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
419fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4208ed22cadSAndy Whitcroft	atomic_t
4218ed22cadSAndy Whitcroft)};
422e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
423e6176fa4SJoe Perches	$typeC99Typedefs\b|
424e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
425e6176fa4SJoe Perches	$typeKernelTypedefs\b
426e6176fa4SJoe Perches)};
4278ed22cadSAndy Whitcroft
4286d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4296d32f7a3SJoe Perches
430691e669bSJoe Perchesour $logFunctions = qr{(?x:
431758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4327d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
4336e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
434b0531722SJoe Perches	panic|
43506668727SJoe Perches	MODULE_[A-Z_]+|
43606668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
437691e669bSJoe Perches)};
438691e669bSJoe Perches
43920112475SJoe Perchesour $signature_tags = qr{(?xi:
44020112475SJoe Perches	Signed-off-by:|
44120112475SJoe Perches	Acked-by:|
44220112475SJoe Perches	Tested-by:|
44320112475SJoe Perches	Reviewed-by:|
44420112475SJoe Perches	Reported-by:|
4458543ae12SMugunthan V N	Suggested-by:|
44620112475SJoe Perches	To:|
44720112475SJoe Perches	Cc:
44820112475SJoe Perches)};
44920112475SJoe Perches
4501813087dSJoe Perchesour @typeListMisordered = (
4511813087dSJoe Perches	qr{char\s+(?:un)?signed},
4521813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
4531813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
4541813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
4551813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
4561813087dSJoe Perches	qr{short\s+(?:un)?signed},
4571813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
4581813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
4591813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
4601813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
4611813087dSJoe Perches	qr{int\s+(?:un)?signed},
4621813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
4631813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
4641813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
4651813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
4661813087dSJoe Perches	qr{long\s+(?:un)?signed},
4671813087dSJoe Perches);
4681813087dSJoe Perches
4698905a67cSAndy Whitcroftour @typeList = (
4708905a67cSAndy Whitcroft	qr{void},
4710c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
4720c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
4730c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
4740c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
4750c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
4760c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
4770c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
4780c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
4790c773d9dSJoe Perches	qr{(?:un)?signed},
4808905a67cSAndy Whitcroft	qr{float},
4818905a67cSAndy Whitcroft	qr{double},
4828905a67cSAndy Whitcroft	qr{bool},
4838905a67cSAndy Whitcroft	qr{struct\s+$Ident},
4848905a67cSAndy Whitcroft	qr{union\s+$Ident},
4858905a67cSAndy Whitcroft	qr{enum\s+$Ident},
4868905a67cSAndy Whitcroft	qr{${Ident}_t},
4878905a67cSAndy Whitcroft	qr{${Ident}_handler},
4888905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
4891813087dSJoe Perches	@typeListMisordered,
4908905a67cSAndy Whitcroft);
491938224b5SJoe Perches
492938224b5SJoe Perchesour $C90_int_types = qr{(?x:
493938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
494938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
495938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
496938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
497938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
498938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
499938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
500938224b5SJoe Perches
501938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
502938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
503938224b5SJoe Perches	long\s+(?:un)?signed|
504938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
505938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
506938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
507938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
508938224b5SJoe Perches
509938224b5SJoe Perches	int\s+(?:un)?signed|
510938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
511938224b5SJoe Perches)};
512938224b5SJoe Perches
513485ff23eSAlex Dowadour @typeListFile = ();
5148716de38SJoe Perchesour @typeListWithAttr = (
5158716de38SJoe Perches	@typeList,
5168716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5178716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5188716de38SJoe Perches);
5198716de38SJoe Perches
520c45dcabdSAndy Whitcroftour @modifierList = (
521c45dcabdSAndy Whitcroft	qr{fastcall},
522c45dcabdSAndy Whitcroft);
523485ff23eSAlex Dowadour @modifierListFile = ();
5248905a67cSAndy Whitcroft
5252435880fSJoe Perchesour @mode_permission_funcs = (
5262435880fSJoe Perches	["module_param", 3],
5272435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5282435880fSJoe Perches	["module_param_array_named", 5],
5292435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5302435880fSJoe Perches	["proc_create(?:_data|)", 2],
531459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
532459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
533459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
534459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
535459cf0aeSJoe Perches	["__ATTR", 2],
5362435880fSJoe Perches);
5372435880fSJoe Perches
538515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
539515a235eSJoe Perchesour $mode_perms_search = "";
540515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
541515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
542515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
543515a235eSJoe Perches}
544515a235eSJoe Perches
545b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
546b392c64fSJoe Perches	S_IWUGO		|
547b392c64fSJoe Perches	S_IWOTH		|
548b392c64fSJoe Perches	S_IRWXUGO	|
549b392c64fSJoe Perches	S_IALLUGO	|
550b392c64fSJoe Perches	0[0-7][0-7][2367]
551b392c64fSJoe Perches}x;
552b392c64fSJoe Perches
553f90774e1SJoe Perchesour %mode_permission_string_types = (
554f90774e1SJoe Perches	"S_IRWXU" => 0700,
555f90774e1SJoe Perches	"S_IRUSR" => 0400,
556f90774e1SJoe Perches	"S_IWUSR" => 0200,
557f90774e1SJoe Perches	"S_IXUSR" => 0100,
558f90774e1SJoe Perches	"S_IRWXG" => 0070,
559f90774e1SJoe Perches	"S_IRGRP" => 0040,
560f90774e1SJoe Perches	"S_IWGRP" => 0020,
561f90774e1SJoe Perches	"S_IXGRP" => 0010,
562f90774e1SJoe Perches	"S_IRWXO" => 0007,
563f90774e1SJoe Perches	"S_IROTH" => 0004,
564f90774e1SJoe Perches	"S_IWOTH" => 0002,
565f90774e1SJoe Perches	"S_IXOTH" => 0001,
566f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
567f90774e1SJoe Perches	"S_IRUGO" => 0444,
568f90774e1SJoe Perches	"S_IWUGO" => 0222,
569f90774e1SJoe Perches	"S_IXUGO" => 0111,
570f90774e1SJoe Perches);
571f90774e1SJoe Perches
572f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
573f90774e1SJoe Perchesour $mode_perms_string_search = "";
574f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
575f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
576f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
577f90774e1SJoe Perches}
578f90774e1SJoe Perches
5797840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
5807840a94cSWolfram Sang	irq|
581cdcee686SSergey Ryazanov	memory|
582cdcee686SSergey Ryazanov	time|
583cdcee686SSergey Ryazanov	reboot
5847840a94cSWolfram Sang)};
5857840a94cSWolfram Sang# memory.h: ARM has a custom one
5867840a94cSWolfram Sang
58766b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
58866b47b4aSKees Cookmy $misspellings;
58966b47b4aSKees Cookmy %spelling_fix;
59036061e38SJoe Perches
59136061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
59266b47b4aSKees Cook	while (<$spelling>) {
59366b47b4aSKees Cook		my $line = $_;
59466b47b4aSKees Cook
59566b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
59666b47b4aSKees Cook		$line =~ s/^\s*//g;
59766b47b4aSKees Cook
59866b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
59966b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
60066b47b4aSKees Cook
60166b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
60266b47b4aSKees Cook
60366b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
60466b47b4aSKees Cook	}
60566b47b4aSKees Cook	close($spelling);
60636061e38SJoe Perches} else {
60736061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
60836061e38SJoe Perches}
60966b47b4aSKees Cook
610ebfd7d62SJoe Perchesif ($codespell) {
611ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
612ebfd7d62SJoe Perches		while (<$spelling>) {
613ebfd7d62SJoe Perches			my $line = $_;
614ebfd7d62SJoe Perches
615ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
616ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
617ebfd7d62SJoe Perches
618ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
619ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
620ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
621ebfd7d62SJoe Perches
622ebfd7d62SJoe Perches			$line =~ s/,.*$//;
623ebfd7d62SJoe Perches
624ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
625ebfd7d62SJoe Perches
626ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
627ebfd7d62SJoe Perches		}
628ebfd7d62SJoe Perches		close($spelling);
629ebfd7d62SJoe Perches	} else {
630ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
631ebfd7d62SJoe Perches	}
632ebfd7d62SJoe Perches}
633ebfd7d62SJoe Perches
634ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
635ebfd7d62SJoe Perches
63675ad8c57SJerome Forissiersub read_words {
63775ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
63875ad8c57SJerome Forissier
63975ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
64075ad8c57SJerome Forissier		while (<$words>) {
641bf1fa1daSJoe Perches			my $line = $_;
642bf1fa1daSJoe Perches
643bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
644bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
645bf1fa1daSJoe Perches
646bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
647bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
648bf1fa1daSJoe Perches			if ($line =~ /\s/) {
64975ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
650bf1fa1daSJoe Perches				next;
651bf1fa1daSJoe Perches			}
652bf1fa1daSJoe Perches
65375ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
65475ad8c57SJerome Forissier			$$wordsRef .= $line;
655bf1fa1daSJoe Perches		}
65675ad8c57SJerome Forissier		close($file);
65775ad8c57SJerome Forissier		return 1;
658bf1fa1daSJoe Perches	}
659bf1fa1daSJoe Perches
66075ad8c57SJerome Forissier	return 0;
66175ad8c57SJerome Forissier}
66275ad8c57SJerome Forissier
66375ad8c57SJerome Forissiermy $const_structs = "";
66475ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
66575ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
66675ad8c57SJerome Forissier
66775ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
66875ad8c57SJerome Forissierif (length($typedefsfile)) {
66975ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
67075ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
67175ad8c57SJerome Forissier}
67275ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
67375ad8c57SJerome Forissier
6748905a67cSAndy Whitcroftsub build_types {
675485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
676485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
6771813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
6788716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
679c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
680ab7e23f3SJoe Perches	$BasicType	= qr{
681ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
682ab7e23f3SJoe Perches				(?:${all}\b)
683ab7e23f3SJoe Perches		}x;
6848905a67cSAndy Whitcroft	$NonptrType	= qr{
685d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
686cf655043SAndy Whitcroft			(?:
6876b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
6888ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
689c45dcabdSAndy Whitcroft				(?:${all}\b)
690cf655043SAndy Whitcroft			)
691c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
6928905a67cSAndy Whitcroft		  }x;
6931813087dSJoe Perches	$NonptrTypeMisordered	= qr{
6941813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
6951813087dSJoe Perches			(?:
6961813087dSJoe Perches				(?:${Misordered}\b)
6971813087dSJoe Perches			)
6981813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
6991813087dSJoe Perches		  }x;
7008716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
7018716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
7028716de38SJoe Perches			(?:
7038716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
7048716de38SJoe Perches				(?:$typeTypedefs\b)|
7058716de38SJoe Perches				(?:${allWithAttr}\b)
7068716de38SJoe Perches			)
7078716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
7088716de38SJoe Perches		  }x;
7098905a67cSAndy Whitcroft	$Type	= qr{
710c45dcabdSAndy Whitcroft			$NonptrType
7111574a29fSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
712c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
7138905a67cSAndy Whitcroft		  }x;
7141813087dSJoe Perches	$TypeMisordered	= qr{
7151813087dSJoe Perches			$NonptrTypeMisordered
7161813087dSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
7171813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
7181813087dSJoe Perches		  }x;
71991cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
7201813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
7218905a67cSAndy Whitcroft}
7228905a67cSAndy Whitcroftbuild_types();
7236c72ffaaSAndy Whitcroft
7247d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
725d1fe9c09SJoe Perches
726d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
727d1fe9c09SJoe Perches# requires at least perl version v5.10.0
728d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
729d1fe9c09SJoe Perches
730d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
7312435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
732c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
7337d2367afSJoe Perches
734f8422308SJoe Perchesour $declaration_macros = qr{(?x:
7353e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
736f8422308SJoe Perches	(?:$Storage\s+)?LIST_HEAD\s*\(|
737f8422308SJoe Perches	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
738f8422308SJoe Perches)};
739f8422308SJoe Perches
7407d2367afSJoe Perchessub deparenthesize {
7417d2367afSJoe Perches	my ($string) = @_;
7427d2367afSJoe Perches	return "" if (!defined($string));
7435b9553abSJoe Perches
7445b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
7455b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
7465b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
7475b9553abSJoe Perches	}
7485b9553abSJoe Perches
7497d2367afSJoe Perches	$string =~ s@\s+@ @g;
7505b9553abSJoe Perches
7517d2367afSJoe Perches	return $string;
7527d2367afSJoe Perches}
7537d2367afSJoe Perches
7543445686aSJoe Perchessub seed_camelcase_file {
7553445686aSJoe Perches	my ($file) = @_;
7563445686aSJoe Perches
7573445686aSJoe Perches	return if (!(-f $file));
7583445686aSJoe Perches
7593445686aSJoe Perches	local $/;
7603445686aSJoe Perches
7613445686aSJoe Perches	open(my $include_file, '<', "$file")
7623445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
7633445686aSJoe Perches	my $text = <$include_file>;
7643445686aSJoe Perches	close($include_file);
7653445686aSJoe Perches
7663445686aSJoe Perches	my @lines = split('\n', $text);
7673445686aSJoe Perches
7683445686aSJoe Perches	foreach my $line (@lines) {
7693445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
7703445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
7713445686aSJoe Perches			$camelcase{$1} = 1;
77211ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
77311ea516aSJoe Perches			$camelcase{$1} = 1;
77411ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
7753445686aSJoe Perches			$camelcase{$1} = 1;
7763445686aSJoe Perches		}
7773445686aSJoe Perches	}
7783445686aSJoe Perches}
7793445686aSJoe Perches
78085b0ee18SJoe Perchessub is_maintained_obsolete {
78185b0ee18SJoe Perches	my ($filename) = @_;
78285b0ee18SJoe Perches
783f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
78485b0ee18SJoe Perches
7850616efa4SJoe Perches	my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
78685b0ee18SJoe Perches
78785b0ee18SJoe Perches	return $status =~ /obsolete/i;
78885b0ee18SJoe Perches}
78985b0ee18SJoe Perches
7903445686aSJoe Perchesmy $camelcase_seeded = 0;
7913445686aSJoe Perchessub seed_camelcase_includes {
7923445686aSJoe Perches	return if ($camelcase_seeded);
7933445686aSJoe Perches
7943445686aSJoe Perches	my $files;
795c707a81dSJoe Perches	my $camelcase_cache = "";
796c707a81dSJoe Perches	my @include_files = ();
797c707a81dSJoe Perches
798c707a81dSJoe Perches	$camelcase_seeded = 1;
799351b2a1fSJoe Perches
8003645e328SRichard Genoud	if (-e ".git") {
801351b2a1fSJoe Perches		my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
802351b2a1fSJoe Perches		chomp $git_last_include_commit;
803c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
804c707a81dSJoe Perches	} else {
805c707a81dSJoe Perches		my $last_mod_date = 0;
806c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
807c707a81dSJoe Perches		@include_files = split('\n', $files);
808c707a81dSJoe Perches		foreach my $file (@include_files) {
809c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
810c707a81dSJoe Perches						   localtime((stat $file)[9]));
811c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
812c707a81dSJoe Perches		}
813c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
814c707a81dSJoe Perches	}
815c707a81dSJoe Perches
816c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
817c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
818c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
819351b2a1fSJoe Perches		while (<$camelcase_file>) {
820351b2a1fSJoe Perches			chomp;
821351b2a1fSJoe Perches			$camelcase{$_} = 1;
822351b2a1fSJoe Perches		}
823351b2a1fSJoe Perches		close($camelcase_file);
824351b2a1fSJoe Perches
825351b2a1fSJoe Perches		return;
826351b2a1fSJoe Perches	}
827c707a81dSJoe Perches
8283645e328SRichard Genoud	if (-e ".git") {
829c707a81dSJoe Perches		$files = `git ls-files "include/*.h"`;
830c707a81dSJoe Perches		@include_files = split('\n', $files);
8313445686aSJoe Perches	}
832c707a81dSJoe Perches
8333445686aSJoe Perches	foreach my $file (@include_files) {
8343445686aSJoe Perches		seed_camelcase_file($file);
8353445686aSJoe Perches	}
836351b2a1fSJoe Perches
837c707a81dSJoe Perches	if ($camelcase_cache ne "") {
838351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
839c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
840c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
841351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
842351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
843351b2a1fSJoe Perches		}
844351b2a1fSJoe Perches		close($camelcase_file);
845351b2a1fSJoe Perches	}
8463445686aSJoe Perches}
8473445686aSJoe Perches
848d311cd44SJoe Perchessub git_commit_info {
849d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
850d311cd44SJoe Perches
851d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
852d311cd44SJoe Perches
853d311cd44SJoe Perches	my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
854d311cd44SJoe Perches	$output =~ s/^\s*//gm;
855d311cd44SJoe Perches	my @lines = split("\n", $output);
856d311cd44SJoe Perches
8570d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
8580d7835fcSJoe Perches
859d311cd44SJoe Perches	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
860d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
861d311cd44SJoe Perches# all matching commit ids, but it's very slow...
862d311cd44SJoe Perches#
863d311cd44SJoe Perches#		echo "checking commits $1..."
864d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
865d311cd44SJoe Perches#		while read line ; do
866d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
867d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
868d311cd44SJoe Perches#		done
869d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
870d311cd44SJoe Perches	} else {
871d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
872d311cd44SJoe Perches		$desc = substr($lines[0], 41);
873d311cd44SJoe Perches	}
874d311cd44SJoe Perches
875d311cd44SJoe Perches	return ($id, $desc);
876d311cd44SJoe Perches}
877d311cd44SJoe Perches
8786c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
8790a920b5bSAndy Whitcroft
88000df344fSAndy Whitcroftmy @rawlines = ();
881c2fdda0dSAndy Whitcroftmy @lines = ();
8823705ce5bSJoe Perchesmy @fixed = ();
883d752fcc8SJoe Perchesmy @fixed_inserted = ();
884d752fcc8SJoe Perchesmy @fixed_deleted = ();
885194f66fcSJoe Perchesmy $fixlinenr = -1;
886194f66fcSJoe Perches
8874a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
8884a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
8894a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
8904a593c34SDu, Changbin
8914a593c34SDu, Changbinif ($git) {
8924a593c34SDu, Changbin	my @commits = ();
8930dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
8944a593c34SDu, Changbin		my $git_range;
89528898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
89628898fd1SJoe Perches			$git_range = "-$2 $1";
8974a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
8984a593c34SDu, Changbin			$git_range = "$commit_expr";
8994a593c34SDu, Changbin		} else {
9000dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
9010dea9f1eSJoe Perches		}
9020dea9f1eSJoe Perches		my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
9030dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
90428898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
90528898fd1SJoe Perches			next if (!defined($1) || !defined($2));
9060dea9f1eSJoe Perches			my $sha1 = $1;
9070dea9f1eSJoe Perches			my $subject = $2;
9080dea9f1eSJoe Perches			unshift(@commits, $sha1);
9090dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
9104a593c34SDu, Changbin		}
9114a593c34SDu, Changbin	}
9124a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
9134a593c34SDu, Changbin	@ARGV = @commits;
9144a593c34SDu, Changbin}
9154a593c34SDu, Changbin
916c2fdda0dSAndy Whitcroftmy $vname;
9176c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
91821caa13cSAndy Whitcroft	my $FILE;
9194a593c34SDu, Changbin	if ($git) {
9204a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
9214a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
9224a593c34SDu, Changbin	} elsif ($file) {
92321caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
9246c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
92521caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
92621caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
9276c72ffaaSAndy Whitcroft	} else {
92821caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
9296c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
9306c72ffaaSAndy Whitcroft	}
931c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
932c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
9334a593c34SDu, Changbin	} elsif ($git) {
9340dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
935c2fdda0dSAndy Whitcroft	} else {
936c2fdda0dSAndy Whitcroft		$vname = $filename;
937c2fdda0dSAndy Whitcroft	}
93821caa13cSAndy Whitcroft	while (<$FILE>) {
9390a920b5bSAndy Whitcroft		chomp;
94000df344fSAndy Whitcroft		push(@rawlines, $_);
9416c72ffaaSAndy Whitcroft	}
94221caa13cSAndy Whitcroft	close($FILE);
943d8469f16SJoe Perches
944d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
945d8469f16SJoe Perches		print '-' x length($vname) . "\n";
946d8469f16SJoe Perches		print "$vname\n";
947d8469f16SJoe Perches		print '-' x length($vname) . "\n";
948d8469f16SJoe Perches	}
949d8469f16SJoe Perches
950c2fdda0dSAndy Whitcroft	if (!process($filename)) {
9510a920b5bSAndy Whitcroft		$exit = 1;
9520a920b5bSAndy Whitcroft	}
95300df344fSAndy Whitcroft	@rawlines = ();
95413214adfSAndy Whitcroft	@lines = ();
9553705ce5bSJoe Perches	@fixed = ();
956d752fcc8SJoe Perches	@fixed_inserted = ();
957d752fcc8SJoe Perches	@fixed_deleted = ();
958194f66fcSJoe Perches	$fixlinenr = -1;
959485ff23eSAlex Dowad	@modifierListFile = ();
960485ff23eSAlex Dowad	@typeListFile = ();
961485ff23eSAlex Dowad	build_types();
9620a920b5bSAndy Whitcroft}
9630a920b5bSAndy Whitcroft
964d8469f16SJoe Perchesif (!$quiet) {
9653c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
9663c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
9673c816e49SJoe Perches
968d8469f16SJoe Perches	if ($^V lt 5.10.0) {
969d8469f16SJoe Perches		print << "EOM"
970d8469f16SJoe Perches
971d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
972d8469f16SJoe Perches      An upgrade to at least perl v5.10.0 is suggested.
973d8469f16SJoe PerchesEOM
974d8469f16SJoe Perches	}
975d8469f16SJoe Perches	if ($exit) {
976d8469f16SJoe Perches		print << "EOM"
977d8469f16SJoe Perches
978d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
979d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
980d8469f16SJoe PerchesEOM
981d8469f16SJoe Perches	}
982d8469f16SJoe Perches}
983d8469f16SJoe Perches
9840a920b5bSAndy Whitcroftexit($exit);
9850a920b5bSAndy Whitcroft
9860a920b5bSAndy Whitcroftsub top_of_kernel_tree {
9876c72ffaaSAndy Whitcroft	my ($root) = @_;
9886c72ffaaSAndy Whitcroft
9896c72ffaaSAndy Whitcroft	my @tree_check = (
9906c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
9916c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
9926c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
9936c72ffaaSAndy Whitcroft	);
9946c72ffaaSAndy Whitcroft
9956c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
9966c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
9970a920b5bSAndy Whitcroft			return 0;
9980a920b5bSAndy Whitcroft		}
9996c72ffaaSAndy Whitcroft	}
10006c72ffaaSAndy Whitcroft	return 1;
10016c72ffaaSAndy Whitcroft}
10020a920b5bSAndy Whitcroft
100320112475SJoe Perchessub parse_email {
100420112475SJoe Perches	my ($formatted_email) = @_;
100520112475SJoe Perches
100620112475SJoe Perches	my $name = "";
100720112475SJoe Perches	my $address = "";
100820112475SJoe Perches	my $comment = "";
100920112475SJoe Perches
101020112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
101120112475SJoe Perches		$name = $1;
101220112475SJoe Perches		$address = $2;
101320112475SJoe Perches		$comment = $3 if defined $3;
101420112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
101520112475SJoe Perches		$address = $1;
101620112475SJoe Perches		$comment = $2 if defined $2;
101720112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
101820112475SJoe Perches		$address = $1;
101920112475SJoe Perches		$comment = $2 if defined $2;
102020112475SJoe Perches		$formatted_email =~ s/$address.*$//;
102120112475SJoe Perches		$name = $formatted_email;
10223705ce5bSJoe Perches		$name = trim($name);
102320112475SJoe Perches		$name =~ s/^\"|\"$//g;
102420112475SJoe Perches		# If there's a name left after stripping spaces and
102520112475SJoe Perches		# leading quotes, and the address doesn't have both
102620112475SJoe Perches		# leading and trailing angle brackets, the address
102720112475SJoe Perches		# is invalid. ie:
102820112475SJoe Perches		#   "joe smith [email protected]" bad
102920112475SJoe Perches		#   "joe smith <[email protected]" bad
103020112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
103120112475SJoe Perches			$name = "";
103220112475SJoe Perches			$address = "";
103320112475SJoe Perches			$comment = "";
103420112475SJoe Perches		}
103520112475SJoe Perches	}
103620112475SJoe Perches
10373705ce5bSJoe Perches	$name = trim($name);
103820112475SJoe Perches	$name =~ s/^\"|\"$//g;
10393705ce5bSJoe Perches	$address = trim($address);
104020112475SJoe Perches	$address =~ s/^\<|\>$//g;
104120112475SJoe Perches
104220112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
104320112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
104420112475SJoe Perches		$name = "\"$name\"";
104520112475SJoe Perches	}
104620112475SJoe Perches
104720112475SJoe Perches	return ($name, $address, $comment);
104820112475SJoe Perches}
104920112475SJoe Perches
105020112475SJoe Perchessub format_email {
105120112475SJoe Perches	my ($name, $address) = @_;
105220112475SJoe Perches
105320112475SJoe Perches	my $formatted_email;
105420112475SJoe Perches
10553705ce5bSJoe Perches	$name = trim($name);
105620112475SJoe Perches	$name =~ s/^\"|\"$//g;
10573705ce5bSJoe Perches	$address = trim($address);
105820112475SJoe Perches
105920112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
106020112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
106120112475SJoe Perches		$name = "\"$name\"";
106220112475SJoe Perches	}
106320112475SJoe Perches
106420112475SJoe Perches	if ("$name" eq "") {
106520112475SJoe Perches		$formatted_email = "$address";
106620112475SJoe Perches	} else {
106720112475SJoe Perches		$formatted_email = "$name <$address>";
106820112475SJoe Perches	}
106920112475SJoe Perches
107020112475SJoe Perches	return $formatted_email;
107120112475SJoe Perches}
107220112475SJoe Perches
1073d311cd44SJoe Perchessub which {
1074d311cd44SJoe Perches	my ($bin) = @_;
1075d311cd44SJoe Perches
1076d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1077d311cd44SJoe Perches		if (-e "$path/$bin") {
1078d311cd44SJoe Perches			return "$path/$bin";
1079d311cd44SJoe Perches		}
1080d311cd44SJoe Perches	}
1081d311cd44SJoe Perches
1082d311cd44SJoe Perches	return "";
1083d311cd44SJoe Perches}
1084d311cd44SJoe Perches
1085000d1cc1SJoe Perchessub which_conf {
1086000d1cc1SJoe Perches	my ($conf) = @_;
1087000d1cc1SJoe Perches
1088000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1089000d1cc1SJoe Perches		if (-e "$path/$conf") {
1090000d1cc1SJoe Perches			return "$path/$conf";
1091000d1cc1SJoe Perches		}
1092000d1cc1SJoe Perches	}
1093000d1cc1SJoe Perches
1094000d1cc1SJoe Perches	return "";
1095000d1cc1SJoe Perches}
1096000d1cc1SJoe Perches
10970a920b5bSAndy Whitcroftsub expand_tabs {
10980a920b5bSAndy Whitcroft	my ($str) = @_;
10990a920b5bSAndy Whitcroft
11000a920b5bSAndy Whitcroft	my $res = '';
11010a920b5bSAndy Whitcroft	my $n = 0;
11020a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
11030a920b5bSAndy Whitcroft		if ($c eq "\t") {
11040a920b5bSAndy Whitcroft			$res .= ' ';
11050a920b5bSAndy Whitcroft			$n++;
11060a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
11070a920b5bSAndy Whitcroft				$res .= ' ';
11080a920b5bSAndy Whitcroft			}
11090a920b5bSAndy Whitcroft			next;
11100a920b5bSAndy Whitcroft		}
11110a920b5bSAndy Whitcroft		$res .= $c;
11120a920b5bSAndy Whitcroft		$n++;
11130a920b5bSAndy Whitcroft	}
11140a920b5bSAndy Whitcroft
11150a920b5bSAndy Whitcroft	return $res;
11160a920b5bSAndy Whitcroft}
11176c72ffaaSAndy Whitcroftsub copy_spacing {
1118773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
11196c72ffaaSAndy Whitcroft	return $res;
11206c72ffaaSAndy Whitcroft}
11210a920b5bSAndy Whitcroft
11224a0df2efSAndy Whitcroftsub line_stats {
11234a0df2efSAndy Whitcroft	my ($line) = @_;
11244a0df2efSAndy Whitcroft
11254a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
11264a0df2efSAndy Whitcroft	$line =~ s/^.//;
11274a0df2efSAndy Whitcroft	$line = expand_tabs($line);
11284a0df2efSAndy Whitcroft
11294a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
11304a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
11314a0df2efSAndy Whitcroft
11324a0df2efSAndy Whitcroft	return (length($line), length($white));
11334a0df2efSAndy Whitcroft}
11344a0df2efSAndy Whitcroft
1135773647a0SAndy Whitcroftmy $sanitise_quote = '';
1136773647a0SAndy Whitcroft
1137773647a0SAndy Whitcroftsub sanitise_line_reset {
1138773647a0SAndy Whitcroft	my ($in_comment) = @_;
1139773647a0SAndy Whitcroft
1140773647a0SAndy Whitcroft	if ($in_comment) {
1141773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1142773647a0SAndy Whitcroft	} else {
1143773647a0SAndy Whitcroft		$sanitise_quote = '';
1144773647a0SAndy Whitcroft	}
1145773647a0SAndy Whitcroft}
114600df344fSAndy Whitcroftsub sanitise_line {
114700df344fSAndy Whitcroft	my ($line) = @_;
114800df344fSAndy Whitcroft
114900df344fSAndy Whitcroft	my $res = '';
115000df344fSAndy Whitcroft	my $l = '';
115100df344fSAndy Whitcroft
1152c2fdda0dSAndy Whitcroft	my $qlen = 0;
1153773647a0SAndy Whitcroft	my $off = 0;
1154773647a0SAndy Whitcroft	my $c;
115500df344fSAndy Whitcroft
1156773647a0SAndy Whitcroft	# Always copy over the diff marker.
1157773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1158773647a0SAndy Whitcroft
1159773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1160773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1161773647a0SAndy Whitcroft
1162773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
1163773647a0SAndy Whitcroft		# and end, all to $;.
1164773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1165773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1166773647a0SAndy Whitcroft
1167773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1168773647a0SAndy Whitcroft			$off++;
116900df344fSAndy Whitcroft			next;
1170773647a0SAndy Whitcroft		}
117181bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1172773647a0SAndy Whitcroft			$sanitise_quote = '';
1173773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1174773647a0SAndy Whitcroft			$off++;
1175773647a0SAndy Whitcroft			next;
1176773647a0SAndy Whitcroft		}
1177113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1178113f04a8SDaniel Walker			$sanitise_quote = '//';
1179113f04a8SDaniel Walker
1180113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1181113f04a8SDaniel Walker			$off++;
1182113f04a8SDaniel Walker			next;
1183113f04a8SDaniel Walker		}
1184773647a0SAndy Whitcroft
1185773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1186773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1187773647a0SAndy Whitcroft		    $c eq "\\") {
1188773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1189773647a0SAndy Whitcroft			$off++;
1190773647a0SAndy Whitcroft			next;
1191773647a0SAndy Whitcroft		}
1192773647a0SAndy Whitcroft		# Regular quotes.
1193773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1194773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1195773647a0SAndy Whitcroft				$sanitise_quote = $c;
1196773647a0SAndy Whitcroft
1197773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1198773647a0SAndy Whitcroft				next;
1199773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1200773647a0SAndy Whitcroft				$sanitise_quote = '';
120100df344fSAndy Whitcroft			}
120200df344fSAndy Whitcroft		}
1203773647a0SAndy Whitcroft
1204fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1205773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1206773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1207113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1208113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1209773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1210773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
121100df344fSAndy Whitcroft		} else {
1212773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
121300df344fSAndy Whitcroft		}
1214c2fdda0dSAndy Whitcroft	}
1215c2fdda0dSAndy Whitcroft
1216113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1217113f04a8SDaniel Walker		$sanitise_quote = '';
1218113f04a8SDaniel Walker	}
1219113f04a8SDaniel Walker
1220c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1221c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1222c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1223c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1224c2fdda0dSAndy Whitcroft
1225c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1226c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1227c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1228c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1229c2fdda0dSAndy Whitcroft	}
1230c2fdda0dSAndy Whitcroft
1231dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1232dadf680dSJoe Perches		my $match = $1;
1233dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1234dadf680dSJoe Perches	}
1235dadf680dSJoe Perches
123600df344fSAndy Whitcroft	return $res;
123700df344fSAndy Whitcroft}
123800df344fSAndy Whitcroft
1239a6962d72SJoe Perchessub get_quoted_string {
1240a6962d72SJoe Perches	my ($line, $rawline) = @_;
1241a6962d72SJoe Perches
124233acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1243a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1244a6962d72SJoe Perches}
1245a6962d72SJoe Perches
12468905a67cSAndy Whitcroftsub ctx_statement_block {
12478905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
12488905a67cSAndy Whitcroft	my $line = $linenr - 1;
12498905a67cSAndy Whitcroft	my $blk = '';
12508905a67cSAndy Whitcroft	my $soff = $off;
12518905a67cSAndy Whitcroft	my $coff = $off - 1;
1252773647a0SAndy Whitcroft	my $coff_set = 0;
12538905a67cSAndy Whitcroft
125413214adfSAndy Whitcroft	my $loff = 0;
125513214adfSAndy Whitcroft
12568905a67cSAndy Whitcroft	my $type = '';
12578905a67cSAndy Whitcroft	my $level = 0;
1258a2750645SAndy Whitcroft	my @stack = ();
1259cf655043SAndy Whitcroft	my $p;
12608905a67cSAndy Whitcroft	my $c;
12618905a67cSAndy Whitcroft	my $len = 0;
126213214adfSAndy Whitcroft
126313214adfSAndy Whitcroft	my $remainder;
12648905a67cSAndy Whitcroft	while (1) {
1265a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1266a2750645SAndy Whitcroft
1267773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
12688905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
12698905a67cSAndy Whitcroft		# context.
12708905a67cSAndy Whitcroft		if ($off >= $len) {
12718905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1272dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1273c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
12748905a67cSAndy Whitcroft				$remain--;
127513214adfSAndy Whitcroft				$loff = $len;
1276c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
12778905a67cSAndy Whitcroft				$len = length($blk);
12788905a67cSAndy Whitcroft				$line++;
12798905a67cSAndy Whitcroft				last;
12808905a67cSAndy Whitcroft			}
12818905a67cSAndy Whitcroft			# Bail if there is no further context.
12828905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
128313214adfSAndy Whitcroft			if ($off >= $len) {
12848905a67cSAndy Whitcroft				last;
12858905a67cSAndy Whitcroft			}
1286f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1287f74bd194SAndy Whitcroft				$level++;
1288f74bd194SAndy Whitcroft				$type = '#';
1289f74bd194SAndy Whitcroft			}
12908905a67cSAndy Whitcroft		}
1291cf655043SAndy Whitcroft		$p = $c;
12928905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
129313214adfSAndy Whitcroft		$remainder = substr($blk, $off);
12948905a67cSAndy Whitcroft
1295773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
12964635f4fbSAndy Whitcroft
12974635f4fbSAndy Whitcroft		# Handle nested #if/#else.
12984635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
12994635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
13004635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
13014635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
13024635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
13034635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
13044635f4fbSAndy Whitcroft		}
13054635f4fbSAndy Whitcroft
13068905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
13078905a67cSAndy Whitcroft		# outermost level.
13088905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
13098905a67cSAndy Whitcroft			last;
13108905a67cSAndy Whitcroft		}
13118905a67cSAndy Whitcroft
131213214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1313773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1314773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1315773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1316773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1317773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1318773647a0SAndy Whitcroft			$coff_set = 1;
1319773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1320773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
132113214adfSAndy Whitcroft		}
132213214adfSAndy Whitcroft
13238905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
13248905a67cSAndy Whitcroft			$level++;
13258905a67cSAndy Whitcroft			$type = '(';
13268905a67cSAndy Whitcroft		}
13278905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
13288905a67cSAndy Whitcroft			$level--;
13298905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
13308905a67cSAndy Whitcroft
13318905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
13328905a67cSAndy Whitcroft				$coff = $off;
1333773647a0SAndy Whitcroft				$coff_set = 1;
1334773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
13358905a67cSAndy Whitcroft			}
13368905a67cSAndy Whitcroft		}
13378905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
13388905a67cSAndy Whitcroft			$level++;
13398905a67cSAndy Whitcroft			$type = '{';
13408905a67cSAndy Whitcroft		}
13418905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
13428905a67cSAndy Whitcroft			$level--;
13438905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
13448905a67cSAndy Whitcroft
13458905a67cSAndy Whitcroft			if ($level == 0) {
1346b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1347b998e001SPatrick Pannuto					$off++;
1348b998e001SPatrick Pannuto				}
13498905a67cSAndy Whitcroft				last;
13508905a67cSAndy Whitcroft			}
13518905a67cSAndy Whitcroft		}
1352f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1353f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1354f74bd194SAndy Whitcroft			$level--;
1355f74bd194SAndy Whitcroft			$type = '';
1356f74bd194SAndy Whitcroft			$off++;
1357f74bd194SAndy Whitcroft			last;
1358f74bd194SAndy Whitcroft		}
13598905a67cSAndy Whitcroft		$off++;
13608905a67cSAndy Whitcroft	}
1361a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
136213214adfSAndy Whitcroft	if ($off == $len) {
1363a3bb97a7SAndy Whitcroft		$loff = $len + 1;
136413214adfSAndy Whitcroft		$line++;
136513214adfSAndy Whitcroft		$remain--;
136613214adfSAndy Whitcroft	}
13678905a67cSAndy Whitcroft
13688905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
13698905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
13708905a67cSAndy Whitcroft
13718905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
13728905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
13738905a67cSAndy Whitcroft
1374773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
137513214adfSAndy Whitcroft
137613214adfSAndy Whitcroft	return ($statement, $condition,
137713214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
137813214adfSAndy Whitcroft}
137913214adfSAndy Whitcroft
1380cf655043SAndy Whitcroftsub statement_lines {
1381cf655043SAndy Whitcroft	my ($stmt) = @_;
1382cf655043SAndy Whitcroft
1383cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1384cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1385cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1386cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1387cf655043SAndy Whitcroft
1388cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1389cf655043SAndy Whitcroft
1390cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1391cf655043SAndy Whitcroft}
1392cf655043SAndy Whitcroft
1393cf655043SAndy Whitcroftsub statement_rawlines {
1394cf655043SAndy Whitcroft	my ($stmt) = @_;
1395cf655043SAndy Whitcroft
1396cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1397cf655043SAndy Whitcroft
1398cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1399cf655043SAndy Whitcroft}
1400cf655043SAndy Whitcroft
1401cf655043SAndy Whitcroftsub statement_block_size {
1402cf655043SAndy Whitcroft	my ($stmt) = @_;
1403cf655043SAndy Whitcroft
1404cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1405cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1406cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1407cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1408cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1409cf655043SAndy Whitcroft
1410cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1411cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1412cf655043SAndy Whitcroft
1413cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1414cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1415cf655043SAndy Whitcroft
1416cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1417cf655043SAndy Whitcroft		return $stmt_lines;
1418cf655043SAndy Whitcroft	} else {
1419cf655043SAndy Whitcroft		return $stmt_statements;
1420cf655043SAndy Whitcroft	}
1421cf655043SAndy Whitcroft}
1422cf655043SAndy Whitcroft
142313214adfSAndy Whitcroftsub ctx_statement_full {
142413214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
142513214adfSAndy Whitcroft	my ($statement, $condition, $level);
142613214adfSAndy Whitcroft
142713214adfSAndy Whitcroft	my (@chunks);
142813214adfSAndy Whitcroft
1429cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
143013214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
143113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1432773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
143313214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1434cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1435cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1436cf655043SAndy Whitcroft	}
1437cf655043SAndy Whitcroft
1438cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1439cf655043SAndy Whitcroft	# could continue the statement.
1440cf655043SAndy Whitcroft	for (;;) {
144113214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
144213214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1443cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1444773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1445cf655043SAndy Whitcroft		#print "C: push\n";
1446cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
144713214adfSAndy Whitcroft	}
144813214adfSAndy Whitcroft
144913214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
14508905a67cSAndy Whitcroft}
14518905a67cSAndy Whitcroft
14524a0df2efSAndy Whitcroftsub ctx_block_get {
1453f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
14544a0df2efSAndy Whitcroft	my $line;
14554a0df2efSAndy Whitcroft	my $start = $linenr - 1;
14564a0df2efSAndy Whitcroft	my $blk = '';
14574a0df2efSAndy Whitcroft	my @o;
14584a0df2efSAndy Whitcroft	my @c;
14594a0df2efSAndy Whitcroft	my @res = ();
14604a0df2efSAndy Whitcroft
1461f0a594c1SAndy Whitcroft	my $level = 0;
14624635f4fbSAndy Whitcroft	my @stack = ($level);
146300df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
146400df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
146500df344fSAndy Whitcroft		$remain--;
146600df344fSAndy Whitcroft
146700df344fSAndy Whitcroft		$blk .= $rawlines[$line];
14684635f4fbSAndy Whitcroft
14694635f4fbSAndy Whitcroft		# Handle nested #if/#else.
147001464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
14714635f4fbSAndy Whitcroft			push(@stack, $level);
147201464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
14734635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
147401464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
14754635f4fbSAndy Whitcroft			$level = pop(@stack);
14764635f4fbSAndy Whitcroft		}
14774635f4fbSAndy Whitcroft
147801464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1479f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1480f0a594c1SAndy Whitcroft			if ($off > 0) {
1481f0a594c1SAndy Whitcroft				$off--;
1482f0a594c1SAndy Whitcroft				next;
1483f0a594c1SAndy Whitcroft			}
14844a0df2efSAndy Whitcroft
1485f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1486f0a594c1SAndy Whitcroft				$level--;
1487f0a594c1SAndy Whitcroft				last if ($level == 0);
1488f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1489f0a594c1SAndy Whitcroft				$level++;
1490f0a594c1SAndy Whitcroft			}
1491f0a594c1SAndy Whitcroft		}
14924a0df2efSAndy Whitcroft
1493f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
149400df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
14954a0df2efSAndy Whitcroft		}
14964a0df2efSAndy Whitcroft
1497f0a594c1SAndy Whitcroft		last if ($level == 0);
14984a0df2efSAndy Whitcroft	}
14994a0df2efSAndy Whitcroft
1500f0a594c1SAndy Whitcroft	return ($level, @res);
15014a0df2efSAndy Whitcroft}
15024a0df2efSAndy Whitcroftsub ctx_block_outer {
15034a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15044a0df2efSAndy Whitcroft
1505f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1506f0a594c1SAndy Whitcroft	return @r;
15074a0df2efSAndy Whitcroft}
15084a0df2efSAndy Whitcroftsub ctx_block {
15094a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15104a0df2efSAndy Whitcroft
1511f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1512f0a594c1SAndy Whitcroft	return @r;
1513653d4876SAndy Whitcroft}
1514653d4876SAndy Whitcroftsub ctx_statement {
1515f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1516f0a594c1SAndy Whitcroft
1517f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1518f0a594c1SAndy Whitcroft	return @r;
1519f0a594c1SAndy Whitcroft}
1520f0a594c1SAndy Whitcroftsub ctx_block_level {
1521653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1522653d4876SAndy Whitcroft
1523f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
15244a0df2efSAndy Whitcroft}
15259c0ca6f9SAndy Whitcroftsub ctx_statement_level {
15269c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
15279c0ca6f9SAndy Whitcroft
15289c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
15299c0ca6f9SAndy Whitcroft}
15304a0df2efSAndy Whitcroft
15314a0df2efSAndy Whitcroftsub ctx_locate_comment {
15324a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15334a0df2efSAndy Whitcroft
15344a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1535beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
15364a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
15374a0df2efSAndy Whitcroft
15384a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
15394a0df2efSAndy Whitcroft	# comment.
15404a0df2efSAndy Whitcroft	my $in_comment = 0;
15414a0df2efSAndy Whitcroft	$current_comment = '';
15424a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
154300df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
154400df344fSAndy Whitcroft		#warn "           $line\n";
15454a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
15464a0df2efSAndy Whitcroft			$in_comment = 1;
15474a0df2efSAndy Whitcroft		}
15484a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
15494a0df2efSAndy Whitcroft			$in_comment = 1;
15504a0df2efSAndy Whitcroft		}
15514a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
15524a0df2efSAndy Whitcroft			$current_comment = '';
15534a0df2efSAndy Whitcroft		}
15544a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
15554a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
15564a0df2efSAndy Whitcroft			$in_comment = 0;
15574a0df2efSAndy Whitcroft		}
15584a0df2efSAndy Whitcroft	}
15594a0df2efSAndy Whitcroft
15604a0df2efSAndy Whitcroft	chomp($current_comment);
15614a0df2efSAndy Whitcroft	return($current_comment);
15624a0df2efSAndy Whitcroft}
15634a0df2efSAndy Whitcroftsub ctx_has_comment {
15644a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15654a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
15664a0df2efSAndy Whitcroft
156700df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
15684a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
15694a0df2efSAndy Whitcroft
15704a0df2efSAndy Whitcroft	return ($cmt ne '');
15714a0df2efSAndy Whitcroft}
15724a0df2efSAndy Whitcroft
15734d001e4dSAndy Whitcroftsub raw_line {
15744d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
15754d001e4dSAndy Whitcroft
15764d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
15774d001e4dSAndy Whitcroft	$cnt++;
15784d001e4dSAndy Whitcroft
15794d001e4dSAndy Whitcroft	my $line;
15804d001e4dSAndy Whitcroft	while ($cnt) {
15814d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
15824d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
15834d001e4dSAndy Whitcroft		$cnt--;
15844d001e4dSAndy Whitcroft	}
15854d001e4dSAndy Whitcroft
15864d001e4dSAndy Whitcroft	return $line;
15874d001e4dSAndy Whitcroft}
15884d001e4dSAndy Whitcroft
15890a920b5bSAndy Whitcroftsub cat_vet {
15900a920b5bSAndy Whitcroft	my ($vet) = @_;
15919c0ca6f9SAndy Whitcroft	my ($res, $coded);
15920a920b5bSAndy Whitcroft
15939c0ca6f9SAndy Whitcroft	$res = '';
15946c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
15956c72ffaaSAndy Whitcroft		$res .= $1;
15966c72ffaaSAndy Whitcroft		if ($2 ne '') {
15979c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
15986c72ffaaSAndy Whitcroft			$res .= $coded;
15996c72ffaaSAndy Whitcroft		}
16009c0ca6f9SAndy Whitcroft	}
16019c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
16020a920b5bSAndy Whitcroft
16039c0ca6f9SAndy Whitcroft	return $res;
16040a920b5bSAndy Whitcroft}
16050a920b5bSAndy Whitcroft
1606c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1607cf655043SAndy Whitcroftmy $av_pending;
1608c2fdda0dSAndy Whitcroftmy @av_paren_type;
16091f65f947SAndy Whitcroftmy $av_pend_colon;
1610c2fdda0dSAndy Whitcroft
1611c2fdda0dSAndy Whitcroftsub annotate_reset {
1612c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1613cf655043SAndy Whitcroft	$av_pending = '_';
1614cf655043SAndy Whitcroft	@av_paren_type = ('E');
16151f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1616c2fdda0dSAndy Whitcroft}
1617c2fdda0dSAndy Whitcroft
16186c72ffaaSAndy Whitcroftsub annotate_values {
16196c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
16206c72ffaaSAndy Whitcroft
16216c72ffaaSAndy Whitcroft	my $res;
16221f65f947SAndy Whitcroft	my $var = '_' x length($stream);
16236c72ffaaSAndy Whitcroft	my $cur = $stream;
16246c72ffaaSAndy Whitcroft
1625c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
16266c72ffaaSAndy Whitcroft
16276c72ffaaSAndy Whitcroft	while (length($cur)) {
1628773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1629cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1630171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
16316c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1632c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1633c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1634cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1635c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
16366c72ffaaSAndy Whitcroft			}
16376c72ffaaSAndy Whitcroft
1638c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
16399446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
16409446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1641addcdceaSAndy Whitcroft			$type = 'c';
16429446ef56SAndy Whitcroft
1643e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1644c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
16456c72ffaaSAndy Whitcroft			$type = 'T';
16466c72ffaaSAndy Whitcroft
1647389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1648389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1649389a2fe5SAndy Whitcroft			$type = 'T';
1650389a2fe5SAndy Whitcroft
1651c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1652171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1653c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1654171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1655171ae1a4SAndy Whitcroft			if ($2 ne '') {
1656cf655043SAndy Whitcroft				$av_pending = 'N';
1657171ae1a4SAndy Whitcroft			}
1658171ae1a4SAndy Whitcroft			$type = 'E';
1659171ae1a4SAndy Whitcroft
1660c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1661171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1662171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1663171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
16646c72ffaaSAndy Whitcroft
1665c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1666cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1667c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1668cf655043SAndy Whitcroft
1669cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1670cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1671171ae1a4SAndy Whitcroft			$type = 'E';
1672cf655043SAndy Whitcroft
1673c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1674cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1675cf655043SAndy Whitcroft			$av_preprocessor = 1;
1676cf655043SAndy Whitcroft
1677cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1678cf655043SAndy Whitcroft
1679171ae1a4SAndy Whitcroft			$type = 'E';
1680cf655043SAndy Whitcroft
1681c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1682cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1683cf655043SAndy Whitcroft
1684cf655043SAndy Whitcroft			$av_preprocessor = 1;
1685cf655043SAndy Whitcroft
1686cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1687cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1688cf655043SAndy Whitcroft			pop(@av_paren_type);
1689cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1690171ae1a4SAndy Whitcroft			$type = 'E';
16916c72ffaaSAndy Whitcroft
16926c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1693c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
16946c72ffaaSAndy Whitcroft
1695171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1696171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1697171ae1a4SAndy Whitcroft			$av_pending = $type;
1698171ae1a4SAndy Whitcroft			$type = 'N';
1699171ae1a4SAndy Whitcroft
17006c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1701c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
17026c72ffaaSAndy Whitcroft			if (defined $2) {
1703cf655043SAndy Whitcroft				$av_pending = 'V';
17046c72ffaaSAndy Whitcroft			}
17056c72ffaaSAndy Whitcroft			$type = 'N';
17066c72ffaaSAndy Whitcroft
170714b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1708c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
170914b111c1SAndy Whitcroft			$av_pending = 'E';
17106c72ffaaSAndy Whitcroft			$type = 'N';
17116c72ffaaSAndy Whitcroft
17121f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
17131f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
17141f65f947SAndy Whitcroft			$av_pend_colon = 'C';
17151f65f947SAndy Whitcroft			$type = 'N';
17161f65f947SAndy Whitcroft
171714b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1718c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
17196c72ffaaSAndy Whitcroft			$type = 'N';
17206c72ffaaSAndy Whitcroft
17216c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1722c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1723cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1724cf655043SAndy Whitcroft			$av_pending = '_';
17256c72ffaaSAndy Whitcroft			$type = 'N';
17266c72ffaaSAndy Whitcroft
17276c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1728cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1729cf655043SAndy Whitcroft			if ($new_type ne '_') {
1730cf655043SAndy Whitcroft				$type = $new_type;
1731c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1732c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
17336c72ffaaSAndy Whitcroft			} else {
1734c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
17356c72ffaaSAndy Whitcroft			}
17366c72ffaaSAndy Whitcroft
1737c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1738c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1739c8cb2ca3SAndy Whitcroft			$type = 'V';
1740cf655043SAndy Whitcroft			$av_pending = 'V';
17416c72ffaaSAndy Whitcroft
17428e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
17438e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
17441f65f947SAndy Whitcroft				$av_pend_colon = 'B';
17458e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
17468e761b04SAndy Whitcroft				$av_pend_colon = 'L';
17471f65f947SAndy Whitcroft			}
17481f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
17491f65f947SAndy Whitcroft			$type = 'V';
17501f65f947SAndy Whitcroft
17516c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1752c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
17536c72ffaaSAndy Whitcroft			$type = 'V';
17546c72ffaaSAndy Whitcroft
17556c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1756c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
17576c72ffaaSAndy Whitcroft			$type = 'N';
17586c72ffaaSAndy Whitcroft
1759cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1760c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
176113214adfSAndy Whitcroft			$type = 'E';
17621f65f947SAndy Whitcroft			$av_pend_colon = 'O';
176313214adfSAndy Whitcroft
17648e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
17658e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
17668e761b04SAndy Whitcroft			$type = 'C';
17678e761b04SAndy Whitcroft
17681f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
17691f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
17701f65f947SAndy Whitcroft			$type = 'N';
17711f65f947SAndy Whitcroft
17721f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
17731f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
17741f65f947SAndy Whitcroft
17751f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
17761f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
17771f65f947SAndy Whitcroft				$type = 'E';
17781f65f947SAndy Whitcroft			} else {
17791f65f947SAndy Whitcroft				$type = 'N';
17801f65f947SAndy Whitcroft			}
17811f65f947SAndy Whitcroft			$av_pend_colon = 'O';
17821f65f947SAndy Whitcroft
17838e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
178413214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
17856c72ffaaSAndy Whitcroft			$type = 'N';
17866c72ffaaSAndy Whitcroft
17870d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
178874048ed8SAndy Whitcroft			my $variant;
178974048ed8SAndy Whitcroft
179074048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
179174048ed8SAndy Whitcroft			if ($type eq 'V') {
179274048ed8SAndy Whitcroft				$variant = 'B';
179374048ed8SAndy Whitcroft			} else {
179474048ed8SAndy Whitcroft				$variant = 'U';
179574048ed8SAndy Whitcroft			}
179674048ed8SAndy Whitcroft
179774048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
179874048ed8SAndy Whitcroft			$type = 'N';
179974048ed8SAndy Whitcroft
18006c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1801c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
18026c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
18036c72ffaaSAndy Whitcroft				$type = 'N';
18046c72ffaaSAndy Whitcroft			}
18056c72ffaaSAndy Whitcroft
18066c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1807c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
18086c72ffaaSAndy Whitcroft		}
18096c72ffaaSAndy Whitcroft		if (defined $1) {
18106c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
18116c72ffaaSAndy Whitcroft			$res .= $type x length($1);
18126c72ffaaSAndy Whitcroft		}
18136c72ffaaSAndy Whitcroft	}
18146c72ffaaSAndy Whitcroft
18151f65f947SAndy Whitcroft	return ($res, $var);
18166c72ffaaSAndy Whitcroft}
18176c72ffaaSAndy Whitcroft
18188905a67cSAndy Whitcroftsub possible {
181913214adfSAndy Whitcroft	my ($possible, $line) = @_;
18209a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
18210776e594SAndy Whitcroft		^(?:
18220776e594SAndy Whitcroft			$Modifier|
18230776e594SAndy Whitcroft			$Storage|
18240776e594SAndy Whitcroft			$Type|
18259a974fdbSAndy Whitcroft			DEFINE_\S+
18269a974fdbSAndy Whitcroft		)$|
18279a974fdbSAndy Whitcroft		^(?:
18280776e594SAndy Whitcroft			goto|
18290776e594SAndy Whitcroft			return|
18300776e594SAndy Whitcroft			case|
18310776e594SAndy Whitcroft			else|
18320776e594SAndy Whitcroft			asm|__asm__|
183389a88353SAndy Whitcroft			do|
183489a88353SAndy Whitcroft			\#|
183589a88353SAndy Whitcroft			\#\#|
18369a974fdbSAndy Whitcroft		)(?:\s|$)|
18370776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
18389a974fdbSAndy Whitcroft	    )}x;
18399a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
18409a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1841c45dcabdSAndy Whitcroft		# Check for modifiers.
1842c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1843c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1844c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1845c45dcabdSAndy Whitcroft
1846c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1847c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1848d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
18499a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1850d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1851485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
1852d2506586SAndy Whitcroft				}
18539a974fdbSAndy Whitcroft			}
1854c45dcabdSAndy Whitcroft
1855c45dcabdSAndy Whitcroft		} else {
185613214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1857485ff23eSAlex Dowad			push(@typeListFile, $possible);
1858c45dcabdSAndy Whitcroft		}
18598905a67cSAndy Whitcroft		build_types();
18600776e594SAndy Whitcroft	} else {
18610776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
18628905a67cSAndy Whitcroft	}
18638905a67cSAndy Whitcroft}
18648905a67cSAndy Whitcroft
18656c72ffaaSAndy Whitcroftmy $prefix = '';
18666c72ffaaSAndy Whitcroft
1867000d1cc1SJoe Perchessub show_type {
1868cbec18afSJoe Perches	my ($type) = @_;
186991bfe484SJoe Perches
1870522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
1871522b837cSAlexey Dobriyan
1872cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
1873cbec18afSJoe Perches
1874cbec18afSJoe Perches	return !defined $ignore_type{$type};
1875000d1cc1SJoe Perches}
1876000d1cc1SJoe Perches
1877f0a594c1SAndy Whitcroftsub report {
1878cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
1879cbec18afSJoe Perches
1880cbec18afSJoe Perches	if (!show_type($type) ||
1881cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1882773647a0SAndy Whitcroft		return 0;
1883773647a0SAndy Whitcroft	}
188457230297SJoe Perches	my $output = '';
188557230297SJoe Perches	if (-t STDOUT && $color) {
188657230297SJoe Perches		if ($level eq 'ERROR') {
188757230297SJoe Perches			$output .= RED;
188857230297SJoe Perches		} elsif ($level eq 'WARNING') {
188957230297SJoe Perches			$output .= YELLOW;
1890000d1cc1SJoe Perches		} else {
189157230297SJoe Perches			$output .= GREEN;
1892000d1cc1SJoe Perches		}
189357230297SJoe Perches	}
189457230297SJoe Perches	$output .= $prefix . $level . ':';
189557230297SJoe Perches	if ($show_types) {
189657230297SJoe Perches		$output .= BLUE if (-t STDOUT && $color);
189757230297SJoe Perches		$output .= "$type:";
189857230297SJoe Perches	}
189957230297SJoe Perches	$output .= RESET if (-t STDOUT && $color);
190057230297SJoe Perches	$output .= ' ' . $msg . "\n";
190134d8815fSJoe Perches
190234d8815fSJoe Perches	if ($showfile) {
190334d8815fSJoe Perches		my @lines = split("\n", $output, -1);
190434d8815fSJoe Perches		splice(@lines, 1, 1);
190534d8815fSJoe Perches		$output = join("\n", @lines);
190634d8815fSJoe Perches	}
190757230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
19088905a67cSAndy Whitcroft
190957230297SJoe Perches	push(our @report, $output);
1910773647a0SAndy Whitcroft
1911773647a0SAndy Whitcroft	return 1;
1912f0a594c1SAndy Whitcroft}
1913cbec18afSJoe Perches
1914f0a594c1SAndy Whitcroftsub report_dump {
191513214adfSAndy Whitcroft	our @report;
1916f0a594c1SAndy Whitcroft}
1917000d1cc1SJoe Perches
1918d752fcc8SJoe Perchessub fixup_current_range {
1919d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
1920d752fcc8SJoe Perches
1921d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1922d752fcc8SJoe Perches		my $o = $1;
1923d752fcc8SJoe Perches		my $l = $2;
1924d752fcc8SJoe Perches		my $no = $o + $offset;
1925d752fcc8SJoe Perches		my $nl = $l + $length;
1926d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1927d752fcc8SJoe Perches	}
1928d752fcc8SJoe Perches}
1929d752fcc8SJoe Perches
1930d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
1931d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
1932d752fcc8SJoe Perches
1933d752fcc8SJoe Perches	my $range_last_linenr = 0;
1934d752fcc8SJoe Perches	my $delta_offset = 0;
1935d752fcc8SJoe Perches
1936d752fcc8SJoe Perches	my $old_linenr = 0;
1937d752fcc8SJoe Perches	my $new_linenr = 0;
1938d752fcc8SJoe Perches
1939d752fcc8SJoe Perches	my $next_insert = 0;
1940d752fcc8SJoe Perches	my $next_delete = 0;
1941d752fcc8SJoe Perches
1942d752fcc8SJoe Perches	my @lines = ();
1943d752fcc8SJoe Perches
1944d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
1945d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
1946d752fcc8SJoe Perches
1947d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
1948d752fcc8SJoe Perches		my $save_line = 1;
1949d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
1950323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
1951d752fcc8SJoe Perches			$delta_offset = 0;
1952d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
1953d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
1954d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
1955d752fcc8SJoe Perches		}
1956d752fcc8SJoe Perches
1957d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1958d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
1959d752fcc8SJoe Perches			$save_line = 0;
1960d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1961d752fcc8SJoe Perches		}
1962d752fcc8SJoe Perches
1963d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1964d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
1965d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
1966d752fcc8SJoe Perches			$new_linenr++;
1967d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1968d752fcc8SJoe Perches		}
1969d752fcc8SJoe Perches
1970d752fcc8SJoe Perches		if ($save_line) {
1971d752fcc8SJoe Perches			push(@lines, $line);
1972d752fcc8SJoe Perches			$new_linenr++;
1973d752fcc8SJoe Perches		}
1974d752fcc8SJoe Perches
1975d752fcc8SJoe Perches		$old_linenr++;
1976d752fcc8SJoe Perches	}
1977d752fcc8SJoe Perches
1978d752fcc8SJoe Perches	return @lines;
1979d752fcc8SJoe Perches}
1980d752fcc8SJoe Perches
1981f2d7e4d4SJoe Perchessub fix_insert_line {
1982f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1983f2d7e4d4SJoe Perches
1984f2d7e4d4SJoe Perches	my $inserted = {
1985f2d7e4d4SJoe Perches		LINENR => $linenr,
1986f2d7e4d4SJoe Perches		LINE => $line,
1987f2d7e4d4SJoe Perches	};
1988f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
1989f2d7e4d4SJoe Perches}
1990f2d7e4d4SJoe Perches
1991f2d7e4d4SJoe Perchessub fix_delete_line {
1992f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1993f2d7e4d4SJoe Perches
1994f2d7e4d4SJoe Perches	my $deleted = {
1995f2d7e4d4SJoe Perches		LINENR => $linenr,
1996f2d7e4d4SJoe Perches		LINE => $line,
1997f2d7e4d4SJoe Perches	};
1998f2d7e4d4SJoe Perches
1999f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2000f2d7e4d4SJoe Perches}
2001f2d7e4d4SJoe Perches
2002de7d4f0eSAndy Whitcroftsub ERROR {
2003cbec18afSJoe Perches	my ($type, $msg) = @_;
2004cbec18afSJoe Perches
2005cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2006de7d4f0eSAndy Whitcroft		our $clean = 0;
20076c72ffaaSAndy Whitcroft		our $cnt_error++;
20083705ce5bSJoe Perches		return 1;
2009de7d4f0eSAndy Whitcroft	}
20103705ce5bSJoe Perches	return 0;
2011773647a0SAndy Whitcroft}
2012de7d4f0eSAndy Whitcroftsub WARN {
2013cbec18afSJoe Perches	my ($type, $msg) = @_;
2014cbec18afSJoe Perches
2015cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2016de7d4f0eSAndy Whitcroft		our $clean = 0;
20176c72ffaaSAndy Whitcroft		our $cnt_warn++;
20183705ce5bSJoe Perches		return 1;
2019de7d4f0eSAndy Whitcroft	}
20203705ce5bSJoe Perches	return 0;
2021773647a0SAndy Whitcroft}
2022de7d4f0eSAndy Whitcroftsub CHK {
2023cbec18afSJoe Perches	my ($type, $msg) = @_;
2024cbec18afSJoe Perches
2025cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2026de7d4f0eSAndy Whitcroft		our $clean = 0;
20276c72ffaaSAndy Whitcroft		our $cnt_chk++;
20283705ce5bSJoe Perches		return 1;
20296c72ffaaSAndy Whitcroft	}
20303705ce5bSJoe Perches	return 0;
2031de7d4f0eSAndy Whitcroft}
2032de7d4f0eSAndy Whitcroft
20336ecd9674SAndy Whitcroftsub check_absolute_file {
20346ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
20356ecd9674SAndy Whitcroft	my $file = $absolute;
20366ecd9674SAndy Whitcroft
20376ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
20386ecd9674SAndy Whitcroft
20396ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
20406ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
20416ecd9674SAndy Whitcroft		if (-f "$root/$file") {
20426ecd9674SAndy Whitcroft			##print "file<$file>\n";
20436ecd9674SAndy Whitcroft			last;
20446ecd9674SAndy Whitcroft		}
20456ecd9674SAndy Whitcroft	}
20466ecd9674SAndy Whitcroft	if (! -f _)  {
20476ecd9674SAndy Whitcroft		return 0;
20486ecd9674SAndy Whitcroft	}
20496ecd9674SAndy Whitcroft
20506ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
20516ecd9674SAndy Whitcroft	my $prefix = $absolute;
20526ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
20536ecd9674SAndy Whitcroft
20546ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
20556ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2056000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2057000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
20586ecd9674SAndy Whitcroft	}
20596ecd9674SAndy Whitcroft}
20606ecd9674SAndy Whitcroft
20613705ce5bSJoe Perchessub trim {
20623705ce5bSJoe Perches	my ($string) = @_;
20633705ce5bSJoe Perches
2064b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2065b34c648bSJoe Perches
2066b34c648bSJoe Perches	return $string;
2067b34c648bSJoe Perches}
2068b34c648bSJoe Perches
2069b34c648bSJoe Perchessub ltrim {
2070b34c648bSJoe Perches	my ($string) = @_;
2071b34c648bSJoe Perches
2072b34c648bSJoe Perches	$string =~ s/^\s+//;
2073b34c648bSJoe Perches
2074b34c648bSJoe Perches	return $string;
2075b34c648bSJoe Perches}
2076b34c648bSJoe Perches
2077b34c648bSJoe Perchessub rtrim {
2078b34c648bSJoe Perches	my ($string) = @_;
2079b34c648bSJoe Perches
2080b34c648bSJoe Perches	$string =~ s/\s+$//;
20813705ce5bSJoe Perches
20823705ce5bSJoe Perches	return $string;
20833705ce5bSJoe Perches}
20843705ce5bSJoe Perches
208552ea8506SJoe Perchessub string_find_replace {
208652ea8506SJoe Perches	my ($string, $find, $replace) = @_;
208752ea8506SJoe Perches
208852ea8506SJoe Perches	$string =~ s/$find/$replace/g;
208952ea8506SJoe Perches
209052ea8506SJoe Perches	return $string;
209152ea8506SJoe Perches}
209252ea8506SJoe Perches
20933705ce5bSJoe Perchessub tabify {
20943705ce5bSJoe Perches	my ($leading) = @_;
20953705ce5bSJoe Perches
20963705ce5bSJoe Perches	my $source_indent = 8;
20973705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
20983705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
20993705ce5bSJoe Perches
21003705ce5bSJoe Perches	#convert leading spaces to tabs
21013705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
21023705ce5bSJoe Perches	#Remove spaces before a tab
21033705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
21043705ce5bSJoe Perches
21053705ce5bSJoe Perches	return "$leading";
21063705ce5bSJoe Perches}
21073705ce5bSJoe Perches
2108d1fe9c09SJoe Perchessub pos_last_openparen {
2109d1fe9c09SJoe Perches	my ($line) = @_;
2110d1fe9c09SJoe Perches
2111d1fe9c09SJoe Perches	my $pos = 0;
2112d1fe9c09SJoe Perches
2113d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2114d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2115d1fe9c09SJoe Perches
2116d1fe9c09SJoe Perches	my $last_openparen = 0;
2117d1fe9c09SJoe Perches
2118d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2119d1fe9c09SJoe Perches		return -1;
2120d1fe9c09SJoe Perches	}
2121d1fe9c09SJoe Perches
2122d1fe9c09SJoe Perches	my $len = length($line);
2123d1fe9c09SJoe Perches
2124d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2125d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2126d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2127d1fe9c09SJoe Perches			$pos += length($1) - 1;
2128d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2129d1fe9c09SJoe Perches			$last_openparen = $pos;
2130d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2131d1fe9c09SJoe Perches			last;
2132d1fe9c09SJoe Perches		}
2133d1fe9c09SJoe Perches	}
2134d1fe9c09SJoe Perches
213591cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2136d1fe9c09SJoe Perches}
2137d1fe9c09SJoe Perches
21380a920b5bSAndy Whitcroftsub process {
21390a920b5bSAndy Whitcroft	my $filename = shift;
21400a920b5bSAndy Whitcroft
21410a920b5bSAndy Whitcroft	my $linenr=0;
21420a920b5bSAndy Whitcroft	my $prevline="";
2143c2fdda0dSAndy Whitcroft	my $prevrawline="";
21440a920b5bSAndy Whitcroft	my $stashline="";
2145c2fdda0dSAndy Whitcroft	my $stashrawline="";
21460a920b5bSAndy Whitcroft
21474a0df2efSAndy Whitcroft	my $length;
21480a920b5bSAndy Whitcroft	my $indent;
21490a920b5bSAndy Whitcroft	my $previndent=0;
21500a920b5bSAndy Whitcroft	my $stashindent=0;
21510a920b5bSAndy Whitcroft
2152de7d4f0eSAndy Whitcroft	our $clean = 1;
21530a920b5bSAndy Whitcroft	my $signoff = 0;
21540a920b5bSAndy Whitcroft	my $is_patch = 0;
215529ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
215615662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
2157ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2158bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
21592a076f40SJoe Perches	my $commit_log_long_line = 0;
2160e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
216113f1937eSJoe Perches	my $reported_maintainer_file = 0;
2162fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2163fa64205dSPasi Savanainen
2164365dd4eaSJoe Perches	my $last_blank_line = 0;
21655e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2166365dd4eaSJoe Perches
216713214adfSAndy Whitcroft	our @report = ();
21686c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
21696c72ffaaSAndy Whitcroft	our $cnt_error = 0;
21706c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
21716c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
21726c72ffaaSAndy Whitcroft
21730a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
21740a920b5bSAndy Whitcroft	my $realfile = '';
21750a920b5bSAndy Whitcroft	my $realline = 0;
21760a920b5bSAndy Whitcroft	my $realcnt = 0;
21770a920b5bSAndy Whitcroft	my $here = '';
217877cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
21790a920b5bSAndy Whitcroft	my $in_comment = 0;
2180c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
21810a920b5bSAndy Whitcroft	my $first_line = 0;
21821e855726SWolfram Sang	my $p1_prefix = '';
21830a920b5bSAndy Whitcroft
218413214adfSAndy Whitcroft	my $prev_values = 'E';
218513214adfSAndy Whitcroft
218613214adfSAndy Whitcroft	# suppression flags
2187773647a0SAndy Whitcroft	my %suppress_ifbraces;
2188170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
21892b474a1aSAndy Whitcroft	my %suppress_export;
21903e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2191653d4876SAndy Whitcroft
21927e51f197SJoe Perches	my %signatures = ();
2193323c1260SJoe Perches
2194c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2195de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2196c2fdda0dSAndy Whitcroft	#
2197de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2198de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2199773647a0SAndy Whitcroft
2200d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2201d8b07710SJoe Perches
2202773647a0SAndy Whitcroft	sanitise_line_reset();
2203c2fdda0dSAndy Whitcroft	my $line;
2204c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2205773647a0SAndy Whitcroft		$linenr++;
2206773647a0SAndy Whitcroft		$line = $rawline;
2207c2fdda0dSAndy Whitcroft
22083705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
22093705ce5bSJoe Perches
2210773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2211de7d4f0eSAndy Whitcroft			$setup_docs = 0;
22128c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2213de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2214de7d4f0eSAndy Whitcroft			}
2215773647a0SAndy Whitcroft			#next;
2216de7d4f0eSAndy Whitcroft		}
221774fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2218773647a0SAndy Whitcroft			$realline=$1-1;
2219773647a0SAndy Whitcroft			if (defined $2) {
2220773647a0SAndy Whitcroft				$realcnt=$3+1;
2221773647a0SAndy Whitcroft			} else {
2222773647a0SAndy Whitcroft				$realcnt=1+1;
2223773647a0SAndy Whitcroft			}
2224c45dcabdSAndy Whitcroft			$in_comment = 0;
2225773647a0SAndy Whitcroft
2226773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2227773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2228773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2229773647a0SAndy Whitcroft			# at context start.
2230773647a0SAndy Whitcroft			my $edge;
223101fa9147SAndy Whitcroft			my $cnt = $realcnt;
223201fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
223301fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
223401fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
223501fa9147SAndy Whitcroft				$cnt--;
223601fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2237721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2238fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2239fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2240fae17daeSAndy Whitcroft					($edge) = $1;
2241fae17daeSAndy Whitcroft					last;
2242fae17daeSAndy Whitcroft				}
2243773647a0SAndy Whitcroft			}
2244773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2245773647a0SAndy Whitcroft				$in_comment = 1;
2246773647a0SAndy Whitcroft			}
2247773647a0SAndy Whitcroft
2248773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2249773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2250773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2251773647a0SAndy Whitcroft			if (!defined $edge &&
225283242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2253773647a0SAndy Whitcroft			{
2254773647a0SAndy Whitcroft				$in_comment = 1;
2255773647a0SAndy Whitcroft			}
2256773647a0SAndy Whitcroft
2257773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2258773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2259773647a0SAndy Whitcroft
2260171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2261773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2262171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2263773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2264773647a0SAndy Whitcroft		}
2265773647a0SAndy Whitcroft		push(@lines, $line);
2266773647a0SAndy Whitcroft
2267773647a0SAndy Whitcroft		if ($realcnt > 1) {
2268773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2269773647a0SAndy Whitcroft		} else {
2270773647a0SAndy Whitcroft			$realcnt = 0;
2271773647a0SAndy Whitcroft		}
2272773647a0SAndy Whitcroft
2273773647a0SAndy Whitcroft		#print "==>$rawline\n";
2274773647a0SAndy Whitcroft		#print "-->$line\n";
2275de7d4f0eSAndy Whitcroft
2276de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2277de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2278de7d4f0eSAndy Whitcroft		}
2279de7d4f0eSAndy Whitcroft	}
2280de7d4f0eSAndy Whitcroft
22816c72ffaaSAndy Whitcroft	$prefix = '';
22826c72ffaaSAndy Whitcroft
2283773647a0SAndy Whitcroft	$realcnt = 0;
2284773647a0SAndy Whitcroft	$linenr = 0;
2285194f66fcSJoe Perches	$fixlinenr = -1;
22860a920b5bSAndy Whitcroft	foreach my $line (@lines) {
22870a920b5bSAndy Whitcroft		$linenr++;
2288194f66fcSJoe Perches		$fixlinenr++;
22891b5539b1SJoe Perches		my $sline = $line;	#copy of $line
22901b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
22910a920b5bSAndy Whitcroft
2292c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
22936c72ffaaSAndy Whitcroft
22940a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2295e518e9a5SJoe Perches		if (!$in_commit_log &&
229674fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
229774fd4f34SJoe Perches			my $context = $4;
22980a920b5bSAndy Whitcroft			$is_patch = 1;
22994a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
23000a920b5bSAndy Whitcroft			$realline=$1-1;
23010a920b5bSAndy Whitcroft			if (defined $2) {
23020a920b5bSAndy Whitcroft				$realcnt=$3+1;
23030a920b5bSAndy Whitcroft			} else {
23040a920b5bSAndy Whitcroft				$realcnt=1+1;
23050a920b5bSAndy Whitcroft			}
2306c2fdda0dSAndy Whitcroft			annotate_reset();
230713214adfSAndy Whitcroft			$prev_values = 'E';
230813214adfSAndy Whitcroft
2309773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2310170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
23112b474a1aSAndy Whitcroft			%suppress_export = ();
23123e469cdcSAndy Whitcroft			$suppress_statement = 0;
231374fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
231474fd4f34SJoe Perches				$context_function = $1;
231574fd4f34SJoe Perches			} else {
231674fd4f34SJoe Perches				undef $context_function;
231774fd4f34SJoe Perches			}
23180a920b5bSAndy Whitcroft			next;
23190a920b5bSAndy Whitcroft
23204a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
23214a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
23224a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2323773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
23240a920b5bSAndy Whitcroft			$realline++;
2325d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
23260a920b5bSAndy Whitcroft
23274a0df2efSAndy Whitcroft			# Measure the line length and indent.
2328c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
23290a920b5bSAndy Whitcroft
23300a920b5bSAndy Whitcroft			# Track the previous line.
23310a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
23320a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2333c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2334c2fdda0dSAndy Whitcroft
2335773647a0SAndy Whitcroft			#warn "line<$line>\n";
23366c72ffaaSAndy Whitcroft
2337d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2338d8aaf121SAndy Whitcroft			$realcnt--;
23390a920b5bSAndy Whitcroft		}
23400a920b5bSAndy Whitcroft
2341cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2342cc77cdcaSAndy Whitcroft
23436c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
23446c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2345773647a0SAndy Whitcroft
23462ac73b4fSJoe Perches		my $found_file = 0;
2347773647a0SAndy Whitcroft		# extract the filename as it passes
23483bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
23493bf9a009SRabin Vincent			$realfile = $1;
23502b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2351270c49a0SJoe Perches			$in_commit_log = 0;
23522ac73b4fSJoe Perches			$found_file = 1;
23533bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2354773647a0SAndy Whitcroft			$realfile = $1;
23552b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2356270c49a0SJoe Perches			$in_commit_log = 0;
23571e855726SWolfram Sang
23581e855726SWolfram Sang			$p1_prefix = $1;
2359e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2360e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2361000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2362000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
23631e855726SWolfram Sang			}
2364773647a0SAndy Whitcroft
2365c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2366000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2367000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2368773647a0SAndy Whitcroft			}
23692ac73b4fSJoe Perches			$found_file = 1;
23702ac73b4fSJoe Perches		}
23712ac73b4fSJoe Perches
237234d8815fSJoe Perches#make up the handle for any error we report on this line
237334d8815fSJoe Perches		if ($showfile) {
237434d8815fSJoe Perches			$prefix = "$realfile:$realline: "
237534d8815fSJoe Perches		} elsif ($emacs) {
23767d3a9f67SJoe Perches			if ($file) {
23777d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
23787d3a9f67SJoe Perches			} else {
237934d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
238034d8815fSJoe Perches			}
23817d3a9f67SJoe Perches		}
238234d8815fSJoe Perches
23832ac73b4fSJoe Perches		if ($found_file) {
238485b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
238585b0ee18SJoe Perches				WARN("OBSOLETE",
238685b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
238785b0ee18SJoe Perches			}
23887bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
23892ac73b4fSJoe Perches				$check = 1;
23902ac73b4fSJoe Perches			} else {
23912ac73b4fSJoe Perches				$check = $check_orig;
23922ac73b4fSJoe Perches			}
2393773647a0SAndy Whitcroft			next;
2394773647a0SAndy Whitcroft		}
2395773647a0SAndy Whitcroft
2396389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
23970a920b5bSAndy Whitcroft
2398c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2399c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2400c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
24010a920b5bSAndy Whitcroft
24026c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
24036c72ffaaSAndy Whitcroft
2404e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2405e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2406e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2407e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2408e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2409e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2410e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2411e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2412e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2413e518e9a5SJoe Perches		}
2414e518e9a5SJoe Perches
24153bf9a009SRabin Vincent# Check for incorrect file permissions
24163bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
24173bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
241804db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
241904db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2420000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2421000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
24223bf9a009SRabin Vincent			}
24233bf9a009SRabin Vincent		}
24243bf9a009SRabin Vincent
242520112475SJoe Perches# Check the patch for a signoff:
2426d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
24274a0df2efSAndy Whitcroft			$signoff++;
242815662b3eSJoe Perches			$in_commit_log = 0;
24290a920b5bSAndy Whitcroft		}
243020112475SJoe Perches
2431e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2432e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2433e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2434e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2435e0d975b1SJoe Perches		}
2436e0d975b1SJoe Perches
243720112475SJoe Perches# Check signature styles
2438270c49a0SJoe Perches		if (!$in_header_lines &&
2439ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
244020112475SJoe Perches			my $space_before = $1;
244120112475SJoe Perches			my $sign_off = $2;
244220112475SJoe Perches			my $space_after = $3;
244320112475SJoe Perches			my $email = $4;
244420112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
244520112475SJoe Perches
2446ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2447ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2448ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2449ce0338dfSJoe Perches			}
245020112475SJoe Perches			if (defined $space_before && $space_before ne "") {
24513705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24523705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
24533705ce5bSJoe Perches				    $fix) {
2454194f66fcSJoe Perches					$fixed[$fixlinenr] =
24553705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24563705ce5bSJoe Perches				}
245720112475SJoe Perches			}
245820112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
24593705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24603705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
24613705ce5bSJoe Perches				    $fix) {
2462194f66fcSJoe Perches					$fixed[$fixlinenr] =
24633705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24643705ce5bSJoe Perches				}
24653705ce5bSJoe Perches
246620112475SJoe Perches			}
246720112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
24683705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24693705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
24703705ce5bSJoe Perches				    $fix) {
2471194f66fcSJoe Perches					$fixed[$fixlinenr] =
24723705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24733705ce5bSJoe Perches				}
247420112475SJoe Perches			}
247520112475SJoe Perches
247620112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
247720112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
247820112475SJoe Perches			if ($suggested_email eq "") {
2479000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2480000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
248120112475SJoe Perches			} else {
248220112475SJoe Perches				my $dequoted = $suggested_email;
248320112475SJoe Perches				$dequoted =~ s/^"//;
248420112475SJoe Perches				$dequoted =~ s/" </ </;
248520112475SJoe Perches				# Don't force email to have quotes
248620112475SJoe Perches				# Allow just an angle bracketed address
248720112475SJoe Perches				if ("$dequoted$comment" ne $email &&
248820112475SJoe Perches				    "<$email_address>$comment" ne $email &&
248920112475SJoe Perches				    "$suggested_email$comment" ne $email) {
2490000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2491000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
249220112475SJoe Perches				}
24930a920b5bSAndy Whitcroft			}
24947e51f197SJoe Perches
24957e51f197SJoe Perches# Check for duplicate signatures
24967e51f197SJoe Perches			my $sig_nospace = $line;
24977e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
24987e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
24997e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
25007e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
25017e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
25027e51f197SJoe Perches			} else {
25037e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
25047e51f197SJoe Perches			}
25050a920b5bSAndy Whitcroft		}
25060a920b5bSAndy Whitcroft
2507a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2508a2fe16b9SJoe Perches		if ($in_header_lines &&
2509a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2510a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2511a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2512a2fe16b9SJoe Perches		}
2513a2fe16b9SJoe Perches
25149b3189ebSJoe Perches# Check for old stable address
25159b3189ebSJoe Perches		if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
25169b3189ebSJoe Perches			ERROR("STABLE_ADDRESS",
25179b3189ebSJoe Perches			      "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
25189b3189ebSJoe Perches		}
25199b3189ebSJoe Perches
25207ebd05efSChristopher Covington# Check for unwanted Gerrit info
25217ebd05efSChristopher Covington		if ($in_commit_log && $line =~ /^\s*change-id:/i) {
25227ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
25237ebd05efSChristopher Covington			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
25247ebd05efSChristopher Covington		}
25257ebd05efSChristopher Covington
2526369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2527369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2528369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2529369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2530369c8dd3SJoe Perches					# timestamp
2531369c8dd3SJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2532369c8dd3SJoe Perches					# stack dump address
2533369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2534369c8dd3SJoe Perches		}
2535369c8dd3SJoe Perches
25362a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
25372a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2538bf4daf12SJoe Perches		    length($line) > 75 &&
2539bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2540bf4daf12SJoe Perches					# file delta changes
2541bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2542bf4daf12SJoe Perches					# filename then :
2543bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2544bf4daf12SJoe Perches					# A Fixes: or Link: line
2545bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
25462a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
25472a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
25482a076f40SJoe Perches			$commit_log_long_line = 1;
25492a076f40SJoe Perches		}
25502a076f40SJoe Perches
2551bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2552bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2553bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2554bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2555bf4daf12SJoe Perches		}
2556bf4daf12SJoe Perches
25570d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2558369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2559aab38f51SJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2560e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2561fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2562aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2563369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2564bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2565fe043ea1SJoe Perches			my $init_char = "c";
2566fe043ea1SJoe Perches			my $orig_commit = "";
25670d7835fcSJoe Perches			my $short = 1;
25680d7835fcSJoe Perches			my $long = 0;
25690d7835fcSJoe Perches			my $case = 1;
25700d7835fcSJoe Perches			my $space = 1;
25710d7835fcSJoe Perches			my $hasdesc = 0;
257219c146a6SJoe Perches			my $hasparens = 0;
25730d7835fcSJoe Perches			my $id = '0123456789ab';
25740d7835fcSJoe Perches			my $orig_desc = "commit description";
25750d7835fcSJoe Perches			my $description = "";
25760d7835fcSJoe Perches
2577fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2578fe043ea1SJoe Perches				$init_char = $1;
2579fe043ea1SJoe Perches				$orig_commit = lc($2);
2580fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2581fe043ea1SJoe Perches				$orig_commit = lc($1);
2582fe043ea1SJoe Perches			}
2583fe043ea1SJoe Perches
25840d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
25850d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
25860d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
25870d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
25880d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
25890d7835fcSJoe Perches				$orig_desc = $1;
259019c146a6SJoe Perches				$hasparens = 1;
25910d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
25920d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
25930d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
25940d7835fcSJoe Perches				$orig_desc = $1;
259519c146a6SJoe Perches				$hasparens = 1;
2596b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2597b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2598b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2599b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2600b671fde0SJoe Perches				$orig_desc = $1;
2601b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2602b671fde0SJoe Perches				$orig_desc .= " " . $1;
260319c146a6SJoe Perches				$hasparens = 1;
26040d7835fcSJoe Perches			}
26050d7835fcSJoe Perches
26060d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
26070d7835fcSJoe Perches							      $id, $orig_desc);
26080d7835fcSJoe Perches
260919c146a6SJoe Perches			if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) {
2610d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
26110d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
26120d7835fcSJoe Perches			}
2613d311cd44SJoe Perches		}
2614d311cd44SJoe Perches
261513f1937eSJoe Perches# Check for added, moved or deleted files
261613f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
261713f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
261813f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
261913f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
262013f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2621a82603a8SAndrew Jeffery			$is_patch = 1;
262213f1937eSJoe Perches			$reported_maintainer_file = 1;
262313f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
262413f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
262513f1937eSJoe Perches		}
262613f1937eSJoe Perches
262700df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
26288905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2629000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2630000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
26316c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2632de7d4f0eSAndy Whitcroft		}
2633de7d4f0eSAndy Whitcroft
2634de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2635de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2636171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2637171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2638171ae1a4SAndy Whitcroft
2639171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2640171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2641171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2642171ae1a4SAndy Whitcroft
264334d99219SJoe Perches			CHK("INVALID_UTF8",
2644000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
264500df344fSAndy Whitcroft		}
26460a920b5bSAndy Whitcroft
264715662b3eSJoe Perches# Check if it's the start of a commit log
264815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
264915662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2650eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2651eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
265215662b3eSJoe Perches			$in_header_lines = 0;
265315662b3eSJoe Perches			$in_commit_log = 1;
2654ed43c4e5SAllen Hubbe			$has_commit_log = 1;
265515662b3eSJoe Perches		}
265615662b3eSJoe Perches
2657fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2658fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2659fa64205dSPasi Savanainen		if ($in_header_lines &&
2660fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2661fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2662fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2663fa64205dSPasi Savanainen		}
2664fa64205dSPasi Savanainen
2665fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
266615662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2667fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
266815662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
266915662b3eSJoe Perches		}
267015662b3eSJoe Perches
2671d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2672d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2673d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2674d6430f71SJoe Perches				my $file = $1;
2675d6430f71SJoe Perches
2676d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2677d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2678d6430f71SJoe Perches					#
2679d6430f71SJoe Perches				} else {
2680d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2681d6430f71SJoe Perches				}
2682d6430f71SJoe Perches			}
2683d6430f71SJoe Perches		}
2684d6430f71SJoe Perches
268566b47b4aSKees Cook# Check for various typo / spelling mistakes
268666d7a382SJoe Perches		if (defined($misspellings) &&
268766d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2688ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
268966b47b4aSKees Cook				my $typo = $1;
269066b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
269166b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
269266b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
269366b47b4aSKees Cook				my $msg_type = \&WARN;
269466b47b4aSKees Cook				$msg_type = \&CHK if ($file);
269566b47b4aSKees Cook				if (&{$msg_type}("TYPO_SPELLING",
269666b47b4aSKees Cook						 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
269766b47b4aSKees Cook				    $fix) {
269866b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
269966b47b4aSKees Cook				}
270066b47b4aSKees Cook			}
270166b47b4aSKees Cook		}
270266b47b4aSKees Cook
270330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
270430670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
270500df344fSAndy Whitcroft
27060a920b5bSAndy Whitcroft#trailing whitespace
27079c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2708c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2709d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2710d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2711d5e616fcSJoe Perches			    $fix) {
2712194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2713d5e616fcSJoe Perches			}
2714c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2715c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27163705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
27173705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
27183705ce5bSJoe Perches			    $fix) {
2719194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
27203705ce5bSJoe Perches			}
27213705ce5bSJoe Perches
2722d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
27230a920b5bSAndy Whitcroft		}
27245368df20SAndy Whitcroft
27254783f894SJosh Triplett# Check for FSF mailing addresses.
2726109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
27271bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
27283e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
27293e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
27304783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27314783f894SJosh Triplett			my $msg_type = \&ERROR;
27324783f894SJosh Triplett			$msg_type = \&CHK if ($file);
27334783f894SJosh Triplett			&{$msg_type}("FSF_MAILING_ADDRESS",
27344783f894SJosh Triplett				     "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
27354783f894SJosh Triplett		}
27364783f894SJosh Triplett
27373354957aSAndi Kleen# check for Kconfig help text having a real description
27389fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
27399fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
27403354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
27418d73e0e7SJoe Perches		    $line =~ /^\+\s*config\s+/) {
27423354957aSAndi Kleen			my $length = 0;
27439fe287d7SAndy Whitcroft			my $cnt = $realcnt;
27449fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
27459fe287d7SAndy Whitcroft			my $f;
2746a1385803SAndy Whitcroft			my $is_start = 0;
27479fe287d7SAndy Whitcroft			my $is_end = 0;
2748a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
27499fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
27509fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
27519fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
27529fe287d7SAndy Whitcroft
27539fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
27548d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
2755a1385803SAndy Whitcroft
27568d73e0e7SJoe Perches				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2757a1385803SAndy Whitcroft					$is_start = 1;
27588d73e0e7SJoe Perches				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2759a1385803SAndy Whitcroft					$length = -1;
2760a1385803SAndy Whitcroft				}
2761a1385803SAndy Whitcroft
27629fe287d7SAndy Whitcroft				$f =~ s/^.//;
27633354957aSAndi Kleen				$f =~ s/#.*//;
27643354957aSAndi Kleen				$f =~ s/^\s+//;
27653354957aSAndi Kleen				next if ($f =~ /^$/);
27669fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
27679fe287d7SAndy Whitcroft					$is_end = 1;
27689fe287d7SAndy Whitcroft					last;
27699fe287d7SAndy Whitcroft				}
27703354957aSAndi Kleen				$length++;
27713354957aSAndi Kleen			}
277256193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
2773000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
277456193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
277556193274SVadim Bendebury			}
2776a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
27773354957aSAndi Kleen		}
27783354957aSAndi Kleen
2779*628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form
2780*628f91a2SJoe Perches		if ($realfile =~ /^MAINTAINERS$/ &&
2781*628f91a2SJoe Perches		    $rawline =~ /^\+[A-Z]:/ &&
2782*628f91a2SJoe Perches		    $rawline !~ /^\+[A-Z]:\t\S/) {
2783*628f91a2SJoe Perches			if (WARN("MAINTAINERS_STYLE",
2784*628f91a2SJoe Perches				 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2785*628f91a2SJoe Perches			    $fix) {
2786*628f91a2SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2787*628f91a2SJoe Perches			}
2788*628f91a2SJoe Perches		}
2789*628f91a2SJoe Perches
2790327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
2791327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
2792327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
2793327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
2794327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2795327953e9SChristoph Jaeger		}
2796327953e9SChristoph Jaeger
2797c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2798c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2799c68e5878SArnaud Lacombe			my $flag = $1;
2800c68e5878SArnaud Lacombe			my $replacement = {
2801c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
2802c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
2803c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
2804c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
2805c68e5878SArnaud Lacombe			};
2806c68e5878SArnaud Lacombe
2807c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
2808c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2809c68e5878SArnaud Lacombe		}
2810c68e5878SArnaud Lacombe
2811bff5da43SRob Herring# check for DT compatible documentation
28127dd05b38SFlorian Vaussard		if (defined $root &&
28137dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
28147dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
28157dd05b38SFlorian Vaussard
2816bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2817bff5da43SRob Herring
2818cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
2819cc93319bSFlorian Vaussard			my $vp_file = $dt_path . "vendor-prefixes.txt";
2820cc93319bSFlorian Vaussard
2821bff5da43SRob Herring			foreach my $compat (@compats) {
2822bff5da43SRob Herring				my $compat2 = $compat;
2823185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2824185d566bSRob Herring				my $compat3 = $compat;
2825185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2826185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2827bff5da43SRob Herring				if ( $? >> 8 ) {
2828bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2829bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2830bff5da43SRob Herring				}
2831bff5da43SRob Herring
28324fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
28334fbf32a6SFlorian Vaussard				my $vendor = $1;
2834cc93319bSFlorian Vaussard				`grep -Eq "^$vendor\\b" $vp_file`;
2835bff5da43SRob Herring				if ( $? >> 8 ) {
2836bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2837cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2838bff5da43SRob Herring				}
2839bff5da43SRob Herring			}
2840bff5da43SRob Herring		}
2841bff5da43SRob Herring
28425368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
2843d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
28445368df20SAndy Whitcroft
284547e0c88bSJoe Perches# line length limit (with some exclusions)
284647e0c88bSJoe Perches#
284747e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
284847e0c88bSJoe Perches#	logging functions like pr_info that end in a string
284947e0c88bSJoe Perches#	lines with a single string
285047e0c88bSJoe Perches#	#defines that are a single string
285147e0c88bSJoe Perches#
285247e0c88bSJoe Perches# There are 3 different line length message types:
285347e0c88bSJoe Perches# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_linelength
285447e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
285547e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
285647e0c88bSJoe Perches#
285747e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
285847e0c88bSJoe Perches#
285947e0c88bSJoe Perches
2860b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
286147e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
286247e0c88bSJoe Perches
286347e0c88bSJoe Perches			# Check the allowed long line types first
286447e0c88bSJoe Perches
286547e0c88bSJoe Perches			# logging functions that end in a string that starts
286647e0c88bSJoe Perches			# before $max_line_length
286747e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
286847e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
286947e0c88bSJoe Perches				$msg_type = "";
287047e0c88bSJoe Perches
287147e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
287247e0c88bSJoe Perches			# #defines with only strings
287347e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
287447e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
287547e0c88bSJoe Perches				$msg_type = "";
287647e0c88bSJoe Perches
2877d560a5f8SJoe Perches			# EFI_GUID is another special case
2878d560a5f8SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
2879d560a5f8SJoe Perches				$msg_type = "";
2880d560a5f8SJoe Perches
288147e0c88bSJoe Perches			# Otherwise set the alternate message types
288247e0c88bSJoe Perches
288347e0c88bSJoe Perches			# a comment starts before $max_line_length
288447e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
288547e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
288647e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
288747e0c88bSJoe Perches
288847e0c88bSJoe Perches			# a quoted string starts before $max_line_length
288947e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
289047e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
289147e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
289247e0c88bSJoe Perches			}
289347e0c88bSJoe Perches
289447e0c88bSJoe Perches			if ($msg_type ne "" &&
289547e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
289647e0c88bSJoe Perches				WARN($msg_type,
28976cd7f386SJoe Perches				     "line over $max_line_length characters\n" . $herecurr);
28980a920b5bSAndy Whitcroft			}
289947e0c88bSJoe Perches		}
29000a920b5bSAndy Whitcroft
29018905a67cSAndy Whitcroft# check for adding lines without a newline.
29028905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2903000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
2904000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
29058905a67cSAndy Whitcroft		}
29068905a67cSAndy Whitcroft
290742e41c54SMike Frysinger# Blackfin: use hi/lo macros
290842e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
290942e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
291042e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2911000d1cc1SJoe Perches				ERROR("LO_MACRO",
2912000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
291342e41c54SMike Frysinger			}
291442e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
291542e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2916000d1cc1SJoe Perches				ERROR("HI_MACRO",
2917000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
291842e41c54SMike Frysinger			}
291942e41c54SMike Frysinger		}
292042e41c54SMike Frysinger
2921b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
2922de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
29230a920b5bSAndy Whitcroft
29240a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
29250a920b5bSAndy Whitcroft# more than 8 must use tabs.
2926c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
2927c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
2928c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2929d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29303705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
29313705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
29323705ce5bSJoe Perches			    $fix) {
2933194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
29343705ce5bSJoe Perches			}
29350a920b5bSAndy Whitcroft		}
29360a920b5bSAndy Whitcroft
293708e44365SAlberto Panizzo# check for space before tabs.
293808e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
293908e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29403705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
29413705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
29423705ce5bSJoe Perches			    $fix) {
2943194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2944d2207ccbSJoe Perches					   s/(^\+.*) {8,8}\t/$1\t\t/) {}
2945194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2946c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
29473705ce5bSJoe Perches			}
294808e44365SAlberto Panizzo		}
294908e44365SAlberto Panizzo
2950d1fe9c09SJoe Perches# check for && or || at the start of a line
2951d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2952d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
2953d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
2954d1fe9c09SJoe Perches		}
2955d1fe9c09SJoe Perches
2956a91e8994SJoe Perches# check indentation starts on a tab stop
2957a91e8994SJoe Perches		if ($^V && $^V ge 5.10.0 &&
2958a91e8994SJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
2959a91e8994SJoe Perches			my $indent = length($1);
2960a91e8994SJoe Perches			if ($indent % 8) {
2961a91e8994SJoe Perches				if (WARN("TABSTOP",
2962a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
2963a91e8994SJoe Perches				    $fix) {
2964a91e8994SJoe Perches					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
2965a91e8994SJoe Perches				}
2966a91e8994SJoe Perches			}
2967a91e8994SJoe Perches		}
2968a91e8994SJoe Perches
2969d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
2970d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
297191cb5195SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
2972d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
2973d1fe9c09SJoe Perches			my $oldindent = $1;
2974d1fe9c09SJoe Perches			my $rest = $2;
2975d1fe9c09SJoe Perches
2976d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
2977d1fe9c09SJoe Perches			if ($pos >= 0) {
2978b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
2979b34a26f3SJoe Perches				my $newindent = $2;
2980d1fe9c09SJoe Perches
2981d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
2982d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
2983d1fe9c09SJoe Perches					" "  x ($pos % 8);
2984d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
2985d1fe9c09SJoe Perches
2986d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
2987d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
29883705ce5bSJoe Perches
29893705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
29903705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
29913705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
2992194f66fcSJoe Perches						$fixed[$fixlinenr] =~
29933705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
29943705ce5bSJoe Perches					}
2995d1fe9c09SJoe Perches				}
2996d1fe9c09SJoe Perches			}
2997d1fe9c09SJoe Perches		}
2998d1fe9c09SJoe Perches
29996ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
30006ab3a970SJoe Perches# avoid checking a few false positives:
30016ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
30026ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
30036ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
30046ab3a970SJoe Perches#   multiline macros that define functions
30056ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
30066ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
30076ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
30083705ce5bSJoe Perches			if (CHK("SPACING",
3009f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
30103705ce5bSJoe Perches			    $fix) {
3011194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3012f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
30133705ce5bSJoe Perches			}
3014aad4f614SJoe Perches		}
3015aad4f614SJoe Perches
301686406b1cSJoe Perches# Block comment styles
301786406b1cSJoe Perches# Networking with an initial /*
301805880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3019fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
302085ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
302185ad978cSJoe Perches		    $realline > 2) {
302205880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
302305880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
302405880600SJoe Perches		}
302505880600SJoe Perches
302686406b1cSJoe Perches# Block comments use * on subsequent lines
302786406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
302886406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3029a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
303061135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3031a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
303286406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
303386406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3034a605e32eSJoe Perches		}
3035a605e32eSJoe Perches
303686406b1cSJoe Perches# Block comments use */ on trailing lines
303786406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3038c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3039c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3040c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
304186406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
304286406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
304305880600SJoe Perches		}
304405880600SJoe Perches
304508eb9b80SJoe Perches# Block comment * alignment
304608eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3047af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3048af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3049af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
305008eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3051af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3052af207524SJoe Perches			my $oldindent;
305308eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3054af207524SJoe Perches			if (defined($1)) {
3055af207524SJoe Perches				$oldindent = expand_tabs($1);
3056af207524SJoe Perches			} else {
3057af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3058af207524SJoe Perches				$oldindent = expand_tabs($1);
3059af207524SJoe Perches			}
306008eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
306108eb9b80SJoe Perches			my $newindent = $1;
306208eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3063af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
306408eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
306508eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
306608eb9b80SJoe Perches			}
306708eb9b80SJoe Perches		}
306808eb9b80SJoe Perches
30697f619191SJoe Perches# check for missing blank lines after struct/union declarations
30707f619191SJoe Perches# with exceptions for various attributes and macros
30717f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
30727f619191SJoe Perches		    $line =~ /^\+/ &&
30737f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
30747f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
30757f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
30767f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
30777f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
30787f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
30797f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
30807f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3081d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3082d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3083d752fcc8SJoe Perches			    $fix) {
3084f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3085d752fcc8SJoe Perches			}
30867f619191SJoe Perches		}
30877f619191SJoe Perches
3088365dd4eaSJoe Perches# check for multiple consecutive blank lines
3089365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3090365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3091365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3092d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3093d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3094d752fcc8SJoe Perches			    $fix) {
3095f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3096d752fcc8SJoe Perches			}
3097d752fcc8SJoe Perches
3098365dd4eaSJoe Perches			$last_blank_line = $linenr;
3099365dd4eaSJoe Perches		}
3100365dd4eaSJoe Perches
31013b617e3bSJoe Perches# check for missing blank lines after declarations
31023f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
31033f7bac03SJoe Perches			# actual declarations
31043f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
31055a4e1fd3SJoe Perches			# function pointer declarations
31065a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
31073f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
31083f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
31093f7bac03SJoe Perches			# known declaration macros
31103f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
31113f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
31123f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
31133f7bac03SJoe Perches			# other possible extensions of declaration lines
31143f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
31153f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
31163f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
31173f7bac03SJoe Perches			# looks like a declaration
31183f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
31195a4e1fd3SJoe Perches			# function pointer declarations
31205a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
31213f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
31223f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
31233f7bac03SJoe Perches			# known declaration macros
31243f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
31253f7bac03SJoe Perches			# start of struct or union or enum
31263b617e3bSJoe Perches		      $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
31273f7bac03SJoe Perches			# start or end of block or continuation of declaration
31283f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
31293f7bac03SJoe Perches			# bitfield continuation
31303f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
31313f7bac03SJoe Perches			# other possible extensions of declaration lines
31323f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
31333f7bac03SJoe Perches			# indentation of previous and current line are the same
31343f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3135d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3136d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3137d752fcc8SJoe Perches			    $fix) {
3138f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3139d752fcc8SJoe Perches			}
31403b617e3bSJoe Perches		}
31413b617e3bSJoe Perches
31425f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
31436b4c5bebSAndy Whitcroft# Exceptions:
31446b4c5bebSAndy Whitcroft#  1) within comments
31456b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
31466b4c5bebSAndy Whitcroft#  3) hanging labels
31473705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
31485f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
31493705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
31503705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
31513705ce5bSJoe Perches			    $fix) {
3152194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
31533705ce5bSJoe Perches			}
31545f7ddae6SRaffaele Recalcati		}
31555f7ddae6SRaffaele Recalcati
3156b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3157b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3158b9ea10d6SAndy Whitcroft
31594dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
31604dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
31614dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
31624dbed76fSJoe Perches			$context_function = $1;
31634dbed76fSJoe Perches		}
31644dbed76fSJoe Perches
31654dbed76fSJoe Perches# check if this appears to be the end of function declaration
31664dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
31674dbed76fSJoe Perches			undef $context_function;
31684dbed76fSJoe Perches		}
31694dbed76fSJoe Perches
3170032a4c0fSJoe Perches# check indentation of any line with a bare else
3171840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3172032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3173032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3174032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3175840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3176840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3177840080a0SJoe Perches			     defined $lines[$linenr] &&
3178840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3179032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3180032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3181032a4c0fSJoe Perches			}
3182032a4c0fSJoe Perches		}
3183032a4c0fSJoe Perches
3184c00df19aSJoe Perches# check indentation of a line with a break;
3185c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3186c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3187c00df19aSJoe Perches			my $tabs = $1;
3188c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3189c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3190c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3191c00df19aSJoe Perches			}
3192c00df19aSJoe Perches		}
3193c00df19aSJoe Perches
3194c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3195cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3196000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3197000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3198c2fdda0dSAndy Whitcroft		}
319922f2a2efSAndy Whitcroft
320042e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
320142e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
320242e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3203000d1cc1SJoe Perches			ERROR("CSYNC",
3204000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
320542e41c54SMike Frysinger		}
320642e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
320742e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3208000d1cc1SJoe Perches			ERROR("SSYNC",
3209000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
321042e41c54SMike Frysinger		}
321142e41c54SMike Frysinger
321256e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
321356e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
321456e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
321556e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
321656e77d70SJoe Perches		}
321756e77d70SJoe Perches
32189c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
32192b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
32202b474a1aSAndy Whitcroft		    $realline_next);
32213e469cdcSAndy Whitcroft#print "LINE<$line>\n";
32223e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
32231b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3224170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3225f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3226171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3227171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3228171ae1a4SAndy Whitcroft
32293e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
32303e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
32313e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
32323e469cdcSAndy Whitcroft			# until we hit end of it.
32333e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
32343e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
32353e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
32363e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
32373e469cdcSAndy Whitcroft			}
3238f74bd194SAndy Whitcroft
32392b474a1aSAndy Whitcroft			# Find the real next line.
32402b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
32412b474a1aSAndy Whitcroft			if (defined $realline_next &&
32422b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
32432b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
32442b474a1aSAndy Whitcroft				$realline_next++;
32452b474a1aSAndy Whitcroft			}
32462b474a1aSAndy Whitcroft
3247171ae1a4SAndy Whitcroft			my $s = $stat;
3248171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3249cf655043SAndy Whitcroft
3250c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3251171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3252c2fdda0dSAndy Whitcroft
3253c2fdda0dSAndy Whitcroft			# Ignore functions being called
3254171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3255c2fdda0dSAndy Whitcroft
3256463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3257463f2864SAndy Whitcroft
3258c45dcabdSAndy Whitcroft			# declarations always start with types
3259d2506586SAndy 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) {
3260c45dcabdSAndy Whitcroft				my $type = $1;
3261c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3262c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3263c45dcabdSAndy Whitcroft
32646c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3265a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3266c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3267c2fdda0dSAndy Whitcroft			}
32688905a67cSAndy Whitcroft
32696c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
327065863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3271c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
32729c0ca6f9SAndy Whitcroft			}
32738905a67cSAndy Whitcroft
32748905a67cSAndy Whitcroft			# Check for any sort of function declaration.
32758905a67cSAndy Whitcroft			# int foo(something bar, other baz);
32768905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3277171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
32788905a67cSAndy Whitcroft				my ($name_len) = length($1);
32798905a67cSAndy Whitcroft
3280cf655043SAndy Whitcroft				my $ctx = $s;
3281773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
32828905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3283cf655043SAndy Whitcroft
32848905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3285c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
32868905a67cSAndy Whitcroft
3287c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
32888905a67cSAndy Whitcroft					}
32898905a67cSAndy Whitcroft				}
32908905a67cSAndy Whitcroft			}
32918905a67cSAndy Whitcroft
32929c0ca6f9SAndy Whitcroft		}
32939c0ca6f9SAndy Whitcroft
329400df344fSAndy Whitcroft#
329500df344fSAndy Whitcroft# Checks which may be anchored in the context.
329600df344fSAndy Whitcroft#
329700df344fSAndy Whitcroft
329800df344fSAndy Whitcroft# Check for switch () and associated case and default
329900df344fSAndy Whitcroft# statements should be at the same indent.
330000df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
330100df344fSAndy Whitcroft			my $err = '';
330200df344fSAndy Whitcroft			my $sep = '';
330300df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
330400df344fSAndy Whitcroft			shift(@ctx);
330500df344fSAndy Whitcroft			for my $ctx (@ctx) {
330600df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
330700df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
330800df344fSAndy Whitcroft							$indent != $cindent) {
330900df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
331000df344fSAndy Whitcroft					$sep = '';
331100df344fSAndy Whitcroft				} else {
331200df344fSAndy Whitcroft					$sep = "[...]\n";
331300df344fSAndy Whitcroft				}
331400df344fSAndy Whitcroft			}
331500df344fSAndy Whitcroft			if ($err ne '') {
3316000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3317000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3318de7d4f0eSAndy Whitcroft			}
3319de7d4f0eSAndy Whitcroft		}
3320de7d4f0eSAndy Whitcroft
3321de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3322de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
33230fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3324773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3325773647a0SAndy Whitcroft
33269c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
33278eef05ddSJoe Perches
33288eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
33298eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
33308eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
33318eef05ddSJoe Perches			}
33328eef05ddSJoe Perches
3333de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3334de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3335de7d4f0eSAndy Whitcroft
3336548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3337548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3338de7d4f0eSAndy Whitcroft
3339548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3340548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3341548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3342548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3343548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3344773647a0SAndy Whitcroft				$ctx_ln++;
3345773647a0SAndy Whitcroft			}
3346548596d5SAndy Whitcroft
334753210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
334853210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3349773647a0SAndy Whitcroft
3350773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3351000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3352000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
335301464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
335400df344fSAndy Whitcroft			}
3355773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3356773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3357773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3358773647a0SAndy Whitcroft			{
33599c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
33609c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3361000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3362000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
336301464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
33649c0ca6f9SAndy Whitcroft				}
33659c0ca6f9SAndy Whitcroft			}
336600df344fSAndy Whitcroft		}
336700df344fSAndy Whitcroft
33684d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
3369f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
33703e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
33713e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
33723e469cdcSAndy Whitcroft					if (!defined $stat);
33734d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
33744d001e4dSAndy Whitcroft
33754d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
33764d001e4dSAndy Whitcroft
33779f5af480SJoe Perches			# remove inline comments
33789f5af480SJoe Perches			$s =~ s/$;/ /g;
33799f5af480SJoe Perches			$c =~ s/$;/ /g;
33804d001e4dSAndy Whitcroft
33814d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
33826f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
33836f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
33844d001e4dSAndy Whitcroft
33859f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
33869f5af480SJoe Perches			# none on the first line, and are going to readd them
33879f5af480SJoe Perches			# where necessary.
33889f5af480SJoe Perches			$s =~ s/\n./\n/gs;
33899f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
33909f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
33919f5af480SJoe Perches			}
33929f5af480SJoe Perches
33934d001e4dSAndy Whitcroft			# We want to check the first line inside the block
33944d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
33954d001e4dSAndy Whitcroft			#  1) any blank line termination
33964d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
33974d001e4dSAndy Whitcroft			#  3) any do (...) {
33984d001e4dSAndy Whitcroft			my $continuation = 0;
33994d001e4dSAndy Whitcroft			my $check = 0;
34004d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
34014d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
34024d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
34034d001e4dSAndy Whitcroft				$continuation = 1;
34044d001e4dSAndy Whitcroft			}
34059bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
34064d001e4dSAndy Whitcroft				$check = 1;
34074d001e4dSAndy Whitcroft				$cond_lines++;
34084d001e4dSAndy Whitcroft			}
34094d001e4dSAndy Whitcroft
34104d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
34114d001e4dSAndy Whitcroft			# preprocessor statement.
34124d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
34134d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
34144d001e4dSAndy Whitcroft				$check = 0;
34154d001e4dSAndy Whitcroft			}
34164d001e4dSAndy Whitcroft
34179bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3418740504c6SAndy Whitcroft			$continuation = 0;
34199bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
34209bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
34214d001e4dSAndy Whitcroft
3422f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3423f16fa28fSAndy Whitcroft				# is not linear.
3424f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3425f16fa28fSAndy Whitcroft					$check = 0;
3426f16fa28fSAndy Whitcroft				}
3427f16fa28fSAndy Whitcroft
34289bd49efeSAndy Whitcroft				# Ignore:
34299bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
34309bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
34319bd49efeSAndy Whitcroft				#  3) labels.
3432740504c6SAndy Whitcroft				if ($continuation ||
3433740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
34349bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
34359bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3436740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
343730dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
34389bd49efeSAndy Whitcroft						$cond_lines++;
34399bd49efeSAndy Whitcroft					}
34404d001e4dSAndy Whitcroft				}
344130dad6ebSAndy Whitcroft			}
34424d001e4dSAndy Whitcroft
34434d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
34444d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
34454d001e4dSAndy Whitcroft
34464d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
34474d001e4dSAndy Whitcroft			# this is not this patch's fault.
34484d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
34494d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
34504d001e4dSAndy Whitcroft				$check = 0;
34514d001e4dSAndy Whitcroft			}
34524d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
34534d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
34544d001e4dSAndy Whitcroft			}
34554d001e4dSAndy Whitcroft
34569bd49efeSAndy 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";
34574d001e4dSAndy Whitcroft
34589f5af480SJoe Perches			if ($check && $s ne '' &&
34599f5af480SJoe Perches			    (($sindent % 8) != 0 ||
34609f5af480SJoe Perches			     ($sindent < $indent) ||
3461f6950a73SJoe Perches			     ($sindent == $indent &&
3462f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
34639f5af480SJoe Perches			     ($sindent > $indent + 8))) {
3464000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3465000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
34664d001e4dSAndy Whitcroft			}
34674d001e4dSAndy Whitcroft		}
34684d001e4dSAndy Whitcroft
34696c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
34706c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
34711f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
34721f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
34736c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3474c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3475c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3476cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3477cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
34781f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3479c2fdda0dSAndy Whitcroft		}
34806c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
34816c72ffaaSAndy Whitcroft
348200df344fSAndy Whitcroft#ignore lines not being added
34833705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
348400df344fSAndy Whitcroft
348511ca40a0SJoe Perches# check for dereferences that span multiple lines
348611ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
348711ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
348811ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
348911ca40a0SJoe Perches			my $ref = $1;
349011ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
349111ca40a0SJoe Perches			$ref .= $1;
349211ca40a0SJoe Perches			$ref =~ s/\s//g;
349311ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
349411ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
349511ca40a0SJoe Perches		}
349611ca40a0SJoe Perches
3497a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3498c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3499a1ce18e4SJoe Perches			my $type = $1;
3500a1ce18e4SJoe Perches			my $var = $2;
3501207a8e84SJoe Perches			$var = "" if (!defined $var);
3502207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3503a1ce18e4SJoe Perches				my $sign = $1;
3504a1ce18e4SJoe Perches				my $pointer = $2;
3505a1ce18e4SJoe Perches
3506a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3507a1ce18e4SJoe Perches
3508a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3509a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3510a1ce18e4SJoe Perches				    $fix) {
3511a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3512207a8e84SJoe Perches					my $comp_pointer = $pointer;
3513207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3514207a8e84SJoe Perches					$decl .= $comp_pointer;
3515207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3516207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3517a1ce18e4SJoe Perches				}
3518a1ce18e4SJoe Perches			}
3519a1ce18e4SJoe Perches		}
3520a1ce18e4SJoe Perches
3521653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
35227429c690SAndy Whitcroft		if ($dbg_type) {
35237429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3524000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3525000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
35267429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3527000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3528000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
35297429c690SAndy Whitcroft			}
3530653d4876SAndy Whitcroft			next;
3531653d4876SAndy Whitcroft		}
3532a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3533a1ef277eSAndy Whitcroft		if ($dbg_attr) {
35349360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3535000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3536000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
35379360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3538000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3539000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3540a1ef277eSAndy Whitcroft			}
3541a1ef277eSAndy Whitcroft			next;
3542a1ef277eSAndy Whitcroft		}
3543653d4876SAndy Whitcroft
3544f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
354599423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
354699423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3547d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3548d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3549f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3550f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3551f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3552d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3553d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3554f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3555d752fcc8SJoe Perches				$fixedline = $line;
3556d752fcc8SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1/;
3557f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3558d752fcc8SJoe Perches			}
3559f0a594c1SAndy Whitcroft		}
3560f0a594c1SAndy Whitcroft
356100df344fSAndy Whitcroft#
356200df344fSAndy Whitcroft# Checks which are anchored on the added line.
356300df344fSAndy Whitcroft#
356400df344fSAndy Whitcroft
3565653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3566c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3567653d4876SAndy Whitcroft			my $path = $1;
3568653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3569000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3570495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3571495e9d84SJoe Perches			}
3572495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3573495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3574495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3575653d4876SAndy Whitcroft			}
3576653d4876SAndy Whitcroft		}
3577653d4876SAndy Whitcroft
357800df344fSAndy Whitcroft# no C99 // comments
357900df344fSAndy Whitcroft		if ($line =~ m{//}) {
35803705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
35813705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
35823705ce5bSJoe Perches			    $fix) {
3583194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
35843705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
35853705ce5bSJoe Perches					my $comment = trim($1);
3586194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
35873705ce5bSJoe Perches				}
35883705ce5bSJoe Perches			}
358900df344fSAndy Whitcroft		}
359000df344fSAndy Whitcroft		# Remove C99 comments.
35910a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
35926c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
35930a920b5bSAndy Whitcroft
35942b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
35952b474a1aSAndy Whitcroft# the whole statement.
35962b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
35972b474a1aSAndy Whitcroft		if (defined $realline_next &&
35982b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
35992b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
36002b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36012b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36023cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
36033cbf62dfSAndy Whitcroft			# a prefix:
36043cbf62dfSAndy Whitcroft			#   XXX(foo);
36053cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3606653d4876SAndy Whitcroft			my $name = $1;
360787a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
36083cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
36093cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
36103cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36113cbf62dfSAndy Whitcroft
36123cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
36132b474a1aSAndy Whitcroft				\n.}\s*$|
361448012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
361548012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
361648012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
36172b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
36182b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
361948012058SAndy Whitcroft			    )/x) {
36202b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
36212b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
36222b474a1aSAndy Whitcroft			} else {
36232b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36240a920b5bSAndy Whitcroft			}
36250a920b5bSAndy Whitcroft		}
36262b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
36272b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
36282b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36292b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36302b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
36312b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
36322b474a1aSAndy Whitcroft		}
36332b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
36342b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3635000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3636000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
36372b474a1aSAndy Whitcroft		}
36380a920b5bSAndy Whitcroft
36395150bda4SJoe Eloff# check for global initialisers.
36406d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3641d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
36426d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3643d5e616fcSJoe Perches			    $fix) {
36446d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3645d5e616fcSJoe Perches			}
3646f0a594c1SAndy Whitcroft		}
36470a920b5bSAndy Whitcroft# check for static initialisers.
36486d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3649d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
36506d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3651d5e616fcSJoe Perches				      $herecurr) &&
3652d5e616fcSJoe Perches			    $fix) {
36536d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3654d5e616fcSJoe Perches			}
36550a920b5bSAndy Whitcroft		}
36560a920b5bSAndy Whitcroft
36571813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
36581813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
36591813087dSJoe Perches			my $tmp = trim($1);
36601813087dSJoe Perches			WARN("MISORDERED_TYPE",
36611813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
36621813087dSJoe Perches		}
36631813087dSJoe Perches
3664cb710ecaSJoe Perches# check for static const char * arrays.
3665cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3666000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3667000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3668cb710ecaSJoe Perches				$herecurr);
3669cb710ecaSJoe Perches               }
3670cb710ecaSJoe Perches
3671cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3672cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3673000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3674000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3675cb710ecaSJoe Perches				$herecurr);
3676cb710ecaSJoe Perches               }
3677cb710ecaSJoe Perches
3678ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3679ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3680ab7e23f3SJoe Perches			my $found = $1;
3681ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3682ab7e23f3SJoe Perches				WARN("CONST_CONST",
3683ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3684ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3685ab7e23f3SJoe Perches				WARN("CONST_CONST",
3686ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3687ab7e23f3SJoe Perches			}
3688ab7e23f3SJoe Perches		}
3689ab7e23f3SJoe Perches
36909b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
36919b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
36929b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
36939b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
36949b0fa60dSJoe Perches				$herecurr);
36959b0fa60dSJoe Perches               }
36969b0fa60dSJoe Perches
3697b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3698b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3699b598b670SJoe Perches			my $array = $1;
3700b598b670SJoe Perches			if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
3701b598b670SJoe Perches				my $array_div = $1;
3702b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3703b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3704b598b670SJoe Perches				    $fix) {
3705b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3706b598b670SJoe Perches				}
3707b598b670SJoe Perches			}
3708b598b670SJoe Perches		}
3709b598b670SJoe Perches
3710b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
3711b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3712b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
3713b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3714b36190c5SJoe Perches			    $fix) {
3715194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3716b36190c5SJoe Perches			}
3717b36190c5SJoe Perches		}
3718b36190c5SJoe Perches
3719653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
3720653d4876SAndy Whitcroft# make sense.
3721653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
37228054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3723c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
37248ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
372546d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
3726000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
3727000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
37280a920b5bSAndy Whitcroft		}
37290a920b5bSAndy Whitcroft
37300a920b5bSAndy Whitcroft# * goes on variable not on type
373165863862SAndy Whitcroft		# (char*[ const])
3732bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3733bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
37343705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
3735d8aaf121SAndy Whitcroft
373665863862SAndy Whitcroft			# Should start with a space.
373765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
373865863862SAndy Whitcroft			# Should not end with a space.
373965863862SAndy Whitcroft			$to =~ s/\s+$//;
374065863862SAndy Whitcroft			# '*'s should not have spaces between.
3741f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
374265863862SAndy Whitcroft			}
3743d8aaf121SAndy Whitcroft
37443705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
374565863862SAndy Whitcroft			if ($from ne $to) {
37463705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37473705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
37483705ce5bSJoe Perches				    $fix) {
37493705ce5bSJoe Perches					my $sub_from = $ident;
37503705ce5bSJoe Perches					my $sub_to = $ident;
37513705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3752194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37533705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37543705ce5bSJoe Perches				}
375565863862SAndy Whitcroft			}
3756bfcb2cc7SAndy Whitcroft		}
3757bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3758bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
37593705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3760d8aaf121SAndy Whitcroft
376165863862SAndy Whitcroft			# Should start with a space.
376265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
376365863862SAndy Whitcroft			# Should not end with a space.
376465863862SAndy Whitcroft			$to =~ s/\s+$//;
376565863862SAndy Whitcroft			# '*'s should not have spaces between.
3766f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
376765863862SAndy Whitcroft			}
376865863862SAndy Whitcroft			# Modifiers should have spaces.
376965863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
377065863862SAndy Whitcroft
37713705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
3772667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
37733705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37743705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
37753705ce5bSJoe Perches				    $fix) {
37763705ce5bSJoe Perches
37773705ce5bSJoe Perches					my $sub_from = $match;
37783705ce5bSJoe Perches					my $sub_to = $match;
37793705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3780194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37813705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37823705ce5bSJoe Perches				}
378365863862SAndy Whitcroft			}
37840a920b5bSAndy Whitcroft		}
37850a920b5bSAndy Whitcroft
37869d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
37879d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
37889d3e3c70SJoe Perches			my $msg_type = \&WARN;
37899d3e3c70SJoe Perches			$msg_type = \&CHK if ($file);
37909d3e3c70SJoe Perches			&{$msg_type}("AVOID_BUG",
37919d3e3c70SJoe Perches				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
37929d3e3c70SJoe Perches		}
37930a920b5bSAndy Whitcroft
37949d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
37958905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3796000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
3797000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
37988905a67cSAndy Whitcroft		}
37998905a67cSAndy Whitcroft
380017441227SJoe Perches# check for uses of printk_ratelimit
380117441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
3802000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
3803000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
380417441227SJoe Perches		}
380517441227SJoe Perches
380600df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
380700df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
380800df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
380925985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
381000df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
3811f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
381200df344fSAndy Whitcroft			my $ok = 0;
381300df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
381400df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
381525985edcSLucas De Marchi				# we have a preceding printk if it ends
381600df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
381700df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
381800df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
381900df344fSAndy Whitcroft						$ok = 1;
382000df344fSAndy Whitcroft					}
382100df344fSAndy Whitcroft					last;
382200df344fSAndy Whitcroft				}
382300df344fSAndy Whitcroft			}
382400df344fSAndy Whitcroft			if ($ok == 0) {
3825000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
3826000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
38270a920b5bSAndy Whitcroft			}
382800df344fSAndy Whitcroft		}
38290a920b5bSAndy Whitcroft
3830243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3831243f3803SJoe Perches			my $orig = $1;
3832243f3803SJoe Perches			my $level = lc($orig);
3833243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
38348f26b837SJoe Perches			my $level2 = $level;
38358f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
3836243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
3837daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
3838243f3803SJoe Perches		}
3839243f3803SJoe Perches
3840243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
3841d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
3842d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3843d5e616fcSJoe Perches			    $fix) {
3844194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3845d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
3846d5e616fcSJoe Perches			}
3847243f3803SJoe Perches		}
3848243f3803SJoe Perches
3849dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3850dc139313SJoe Perches			my $orig = $1;
3851dc139313SJoe Perches			my $level = lc($orig);
3852dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
3853dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
3854dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
3855dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3856dc139313SJoe Perches		}
3857dc139313SJoe Perches
385891c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
385991c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
386091c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
386191c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
386291c9afafSAndy Lutomirski			WARN("ENOSYS",
386391c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
386491c9afafSAndy Lutomirski		}
386591c9afafSAndy Lutomirski
3866653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
3867653d4876SAndy Whitcroft# or if closed on same line
38688d182478SJoe Perches		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
38694e5d56bdSEddie Kovsky		    !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
38708d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38718d182478SJoe Perches				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
38728d182478SJoe Perches			    $fix) {
38738d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38748d182478SJoe Perches				my $fixed_line = $rawline;
38758d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
38768d182478SJoe Perches				my $line1 = $1;
38778d182478SJoe Perches				my $line2 = $2;
38788d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
38798d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
38808d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
38818d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
38828d182478SJoe Perches				}
38838d182478SJoe Perches			}
38840a920b5bSAndy Whitcroft		}
3885653d4876SAndy Whitcroft
38868905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
38878905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
38888905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
38898d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38908d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
38918d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
38928d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
38938d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38948d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
38958d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
38968d182478SJoe Perches				$fixedline = $rawline;
38978d182478SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1\t/;
38988d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
38998d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
39008d182478SJoe Perches				}
39018d182478SJoe Perches			}
39028905a67cSAndy Whitcroft		}
39038905a67cSAndy Whitcroft
39040c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
39053705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
39063705ce5bSJoe Perches			if (WARN("SPACING",
39073705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
39083705ce5bSJoe Perches			    $fix) {
3909194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39103705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
39113705ce5bSJoe Perches			}
39120c73b4ebSAndy Whitcroft		}
39130c73b4ebSAndy Whitcroft
391431070b5dSJoe Perches# Function pointer declarations
391531070b5dSJoe Perches# check spacing between type, funcptr, and args
391631070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
391791f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
391831070b5dSJoe Perches			my $declare = $1;
391931070b5dSJoe Perches			my $pre_pointer_space = $2;
392031070b5dSJoe Perches			my $post_pointer_space = $3;
392131070b5dSJoe Perches			my $funcname = $4;
392231070b5dSJoe Perches			my $post_funcname_space = $5;
392331070b5dSJoe Perches			my $pre_args_space = $6;
392431070b5dSJoe Perches
392591f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
392691f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
392791f72e9cSJoe Perches# don't need a space so don't warn for those.
392891f72e9cSJoe Perches			my $post_declare_space = "";
392991f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
393091f72e9cSJoe Perches				$post_declare_space = $1;
393191f72e9cSJoe Perches				$declare = rtrim($declare);
393291f72e9cSJoe Perches			}
393391f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
393431070b5dSJoe Perches				WARN("SPACING",
393531070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
393691f72e9cSJoe Perches				$post_declare_space = " ";
393731070b5dSJoe Perches			}
393831070b5dSJoe Perches
393931070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
394091f72e9cSJoe Perches# This test is not currently implemented because these declarations are
394191f72e9cSJoe Perches# equivalent to
394291f72e9cSJoe Perches#	int  foo(int bar, ...)
394391f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
394491f72e9cSJoe Perches#
394591f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
394691f72e9cSJoe Perches#				WARN("SPACING",
394791f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
394891f72e9cSJoe Perches#			}
394931070b5dSJoe Perches
395031070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
395131070b5dSJoe Perches			if (defined $pre_pointer_space &&
395231070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
395331070b5dSJoe Perches				WARN("SPACING",
395431070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
395531070b5dSJoe Perches			}
395631070b5dSJoe Perches
395731070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
395831070b5dSJoe Perches			if (defined $post_pointer_space &&
395931070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
396031070b5dSJoe Perches				WARN("SPACING",
396131070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
396231070b5dSJoe Perches			}
396331070b5dSJoe Perches
396431070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
396531070b5dSJoe Perches			if (defined $post_funcname_space &&
396631070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
396731070b5dSJoe Perches				WARN("SPACING",
396831070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
396931070b5dSJoe Perches			}
397031070b5dSJoe Perches
397131070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
397231070b5dSJoe Perches			if (defined $pre_args_space &&
397331070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
397431070b5dSJoe Perches				WARN("SPACING",
397531070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
397631070b5dSJoe Perches			}
397731070b5dSJoe Perches
397831070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
3979194f66fcSJoe Perches				$fixed[$fixlinenr] =~
398091f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
398131070b5dSJoe Perches			}
398231070b5dSJoe Perches		}
398331070b5dSJoe Perches
39848d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
39858d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
3986fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
3987fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
39888d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
39898d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
39908d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
3991fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
3992daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
39933705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
39943705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
39953705ce5bSJoe Perches				    $fix) {
3996194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
39973705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
39983705ce5bSJoe Perches				}
39998d31cfceSAndy Whitcroft			}
40008d31cfceSAndy Whitcroft		}
40018d31cfceSAndy Whitcroft
4002f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
40036c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4004c2fdda0dSAndy Whitcroft			my $name = $1;
4005773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4006773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4007c2fdda0dSAndy Whitcroft
4008c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4009773647a0SAndy Whitcroft			if ($name =~ /^(?:
4010773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4011773647a0SAndy Whitcroft				volatile|__volatile__|
4012773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4013773647a0SAndy Whitcroft				asm|__asm__)$/x)
4014773647a0SAndy Whitcroft			{
4015c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4016c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4017c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4018c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4019773647a0SAndy Whitcroft
4020773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4021c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4022c2fdda0dSAndy Whitcroft
4023c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4024c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4025773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4026c2fdda0dSAndy Whitcroft
4027c2fdda0dSAndy Whitcroft			} else {
40283705ce5bSJoe Perches				if (WARN("SPACING",
40293705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
40303705ce5bSJoe Perches					     $fix) {
4031194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40323705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
40333705ce5bSJoe Perches				}
4034f0a594c1SAndy Whitcroft			}
40356c72ffaaSAndy Whitcroft		}
40369a4cad4eSEric Nelson
4037653d4876SAndy Whitcroft# Check operator spacing.
40380a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
40393705ce5bSJoe Perches			my $fixed_line = "";
40403705ce5bSJoe Perches			my $line_fixed = 0;
40413705ce5bSJoe Perches
40429c0ca6f9SAndy Whitcroft			my $ops = qr{
40439c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
40449c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
40459c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
40461f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
404784731623SJoe Perches				\?:|\?|:
40489c0ca6f9SAndy Whitcroft			}x;
4049cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
40503705ce5bSJoe Perches
40513705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
40523705ce5bSJoe Perches##			foreach my $el (@elements) {
40533705ce5bSJoe Perches##				print("el: <$el>\n");
40543705ce5bSJoe Perches##			}
40553705ce5bSJoe Perches
40563705ce5bSJoe Perches			my @fix_elements = ();
405700df344fSAndy Whitcroft			my $off = 0;
40586c72ffaaSAndy Whitcroft
40593705ce5bSJoe Perches			foreach my $el (@elements) {
40603705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
40613705ce5bSJoe Perches				$off += length($el);
40623705ce5bSJoe Perches			}
40633705ce5bSJoe Perches
40643705ce5bSJoe Perches			$off = 0;
40653705ce5bSJoe Perches
40666c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4067b34c648bSJoe Perches			my $last_after = -1;
40686c72ffaaSAndy Whitcroft
40690a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
40703705ce5bSJoe Perches
40713705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
40723705ce5bSJoe Perches
40733705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
40743705ce5bSJoe Perches
40754a0df2efSAndy Whitcroft				$off += length($elements[$n]);
40764a0df2efSAndy Whitcroft
407725985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4078773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4079773647a0SAndy Whitcroft				my $cc = '';
4080773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4081773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4082773647a0SAndy Whitcroft				}
4083773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4084773647a0SAndy Whitcroft
40854a0df2efSAndy Whitcroft				my $a = '';
40864a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
40874a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4088cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
40894a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
40904a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4091773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
40924a0df2efSAndy Whitcroft
40930a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
40944a0df2efSAndy Whitcroft
40954a0df2efSAndy Whitcroft				my $c = '';
40960a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
40974a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
40984a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4099cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
41004a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
41014a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
41028b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
41034a0df2efSAndy Whitcroft				} else {
41044a0df2efSAndy Whitcroft					$c = 'E';
41050a920b5bSAndy Whitcroft				}
41060a920b5bSAndy Whitcroft
41074a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
41084a0df2efSAndy Whitcroft
41094a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
41104a0df2efSAndy Whitcroft
41116c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4112de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
41130a920b5bSAndy Whitcroft
411474048ed8SAndy Whitcroft				# Pull out the value of this operator.
41156c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
41160a920b5bSAndy Whitcroft
41171f65f947SAndy Whitcroft				# Get the full operator variant.
41181f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
41191f65f947SAndy Whitcroft
412013214adfSAndy Whitcroft				# Ignore operators passed as parameters.
412113214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4122d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
412313214adfSAndy Whitcroft
4124cf655043SAndy Whitcroft#				# Ignore comments
4125cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
412613214adfSAndy Whitcroft
4127d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
412813214adfSAndy Whitcroft				} elsif ($op eq ';') {
4129cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4130cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
41313705ce5bSJoe Perches						if (ERROR("SPACING",
41323705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4133b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
41343705ce5bSJoe Perches							$line_fixed = 1;
41353705ce5bSJoe Perches						}
4136d8aaf121SAndy Whitcroft					}
4137d8aaf121SAndy Whitcroft
4138d8aaf121SAndy Whitcroft				# // is a comment
4139d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
41400a920b5bSAndy Whitcroft
4141b00e4814SJoe Perches				#   :   when part of a bitfield
4142b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4143b00e4814SJoe Perches					# skip the bitfield test for now
4144b00e4814SJoe Perches
41451f65f947SAndy Whitcroft				# No spaces for:
41461f65f947SAndy Whitcroft				#   ->
4147b00e4814SJoe Perches				} elsif ($op eq '->') {
41484a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
41493705ce5bSJoe Perches						if (ERROR("SPACING",
41503705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4151b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41523705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
41533705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
41543705ce5bSJoe Perches							}
4155b34c648bSJoe Perches							$line_fixed = 1;
41563705ce5bSJoe Perches						}
41570a920b5bSAndy Whitcroft					}
41580a920b5bSAndy Whitcroft
41592381097bSJoe Perches				# , must not have a space before and must have a space on the right.
41600a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
41612381097bSJoe Perches					my $rtrim_before = 0;
41622381097bSJoe Perches					my $space_after = 0;
41632381097bSJoe Perches					if ($ctx =~ /Wx./) {
41642381097bSJoe Perches						if (ERROR("SPACING",
41652381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
41662381097bSJoe Perches							$line_fixed = 1;
41672381097bSJoe Perches							$rtrim_before = 1;
41682381097bSJoe Perches						}
41692381097bSJoe Perches					}
4170cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
41713705ce5bSJoe Perches						if (ERROR("SPACING",
41723705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
41733705ce5bSJoe Perches							$line_fixed = 1;
4174b34c648bSJoe Perches							$last_after = $n;
41752381097bSJoe Perches							$space_after = 1;
41762381097bSJoe Perches						}
41772381097bSJoe Perches					}
41782381097bSJoe Perches					if ($rtrim_before || $space_after) {
41792381097bSJoe Perches						if ($rtrim_before) {
41802381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41812381097bSJoe Perches						} else {
41822381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
41832381097bSJoe Perches						}
41842381097bSJoe Perches						if ($space_after) {
41852381097bSJoe Perches							$good .= " ";
41863705ce5bSJoe Perches						}
41870a920b5bSAndy Whitcroft					}
41880a920b5bSAndy Whitcroft
41899c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
419074048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
41919c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
41929c0ca6f9SAndy Whitcroft
41939c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
41949c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
41959c0ca6f9SAndy Whitcroft				# unary operator, or a cast
41969c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
419774048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
41980d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4199cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
42003705ce5bSJoe Perches						if (ERROR("SPACING",
42013705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4202b34c648bSJoe Perches							if ($n != $last_after + 2) {
4203b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
42043705ce5bSJoe Perches								$line_fixed = 1;
42053705ce5bSJoe Perches							}
42060a920b5bSAndy Whitcroft						}
4207b34c648bSJoe Perches					}
4208a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4209171ae1a4SAndy Whitcroft						# A unary '*' may be const
4210171ae1a4SAndy Whitcroft
4211171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
42123705ce5bSJoe Perches						if (ERROR("SPACING",
42133705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4214b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
42153705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42163705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
42173705ce5bSJoe Perches							}
4218b34c648bSJoe Perches							$line_fixed = 1;
42193705ce5bSJoe Perches						}
42200a920b5bSAndy Whitcroft					}
42210a920b5bSAndy Whitcroft
42220a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
42230a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4224773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
42253705ce5bSJoe Perches						if (ERROR("SPACING",
42263705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4227b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
42283705ce5bSJoe Perches							$line_fixed = 1;
42293705ce5bSJoe Perches						}
42300a920b5bSAndy Whitcroft					}
4231773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4232773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
42333705ce5bSJoe Perches						if (ERROR("SPACING",
42343705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4235b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42363705ce5bSJoe Perches							$line_fixed = 1;
42373705ce5bSJoe Perches						}
4238653d4876SAndy Whitcroft					}
4239773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
42403705ce5bSJoe Perches						if (ERROR("SPACING",
42413705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4242b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
42433705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42443705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4245773647a0SAndy Whitcroft							}
4246b34c648bSJoe Perches							$line_fixed = 1;
42473705ce5bSJoe Perches						}
42483705ce5bSJoe Perches					}
42490a920b5bSAndy Whitcroft
42500a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
42519c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
42529c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
42539c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4254c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4255c2fdda0dSAndy Whitcroft					 $op eq '%')
42560a920b5bSAndy Whitcroft				{
4257d2e025f3SJoe Perches					if ($check) {
4258d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4259d2e025f3SJoe Perches							if (CHK("SPACING",
4260d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4261d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4262d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4263d2e025f3SJoe Perches								$line_fixed = 1;
4264d2e025f3SJoe Perches							}
4265d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4266d2e025f3SJoe Perches							if (CHK("SPACING",
4267d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4268d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4269d2e025f3SJoe Perches								$line_fixed = 1;
4270d2e025f3SJoe Perches							}
4271d2e025f3SJoe Perches						}
4272d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
42733705ce5bSJoe Perches						if (ERROR("SPACING",
42743705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4275b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4276b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4277b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4278b34c648bSJoe Perches							}
42793705ce5bSJoe Perches							$line_fixed = 1;
42803705ce5bSJoe Perches						}
42810a920b5bSAndy Whitcroft					}
42820a920b5bSAndy Whitcroft
42831f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
42841f65f947SAndy Whitcroft				# terminating a case value or a label.
42851f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
42861f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
42873705ce5bSJoe Perches						if (ERROR("SPACING",
42883705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4289b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42903705ce5bSJoe Perches							$line_fixed = 1;
42913705ce5bSJoe Perches						}
42921f65f947SAndy Whitcroft					}
42931f65f947SAndy Whitcroft
42940a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4295cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
42961f65f947SAndy Whitcroft					my $ok = 0;
42971f65f947SAndy Whitcroft
429822f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
42991f65f947SAndy Whitcroft					if (($op eq '<' &&
43001f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
43011f65f947SAndy Whitcroft					    ($op eq '>' &&
43021f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
43031f65f947SAndy Whitcroft					{
43041f65f947SAndy Whitcroft					    	$ok = 1;
43051f65f947SAndy Whitcroft					}
43061f65f947SAndy Whitcroft
4307e0df7e1fSJoe Perches					# for asm volatile statements
4308e0df7e1fSJoe Perches					# ignore a colon with another
4309e0df7e1fSJoe Perches					# colon immediately before or after
4310e0df7e1fSJoe Perches					if (($op eq ':') &&
4311e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4312e0df7e1fSJoe Perches						$ok = 1;
4313e0df7e1fSJoe Perches					}
4314e0df7e1fSJoe Perches
431584731623SJoe Perches					# messages are ERROR, but ?: are CHK
43161f65f947SAndy Whitcroft					if ($ok == 0) {
431784731623SJoe Perches						my $msg_type = \&ERROR;
431884731623SJoe Perches						$msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
431984731623SJoe Perches
432084731623SJoe Perches						if (&{$msg_type}("SPACING",
43213705ce5bSJoe Perches								 "spaces required around that '$op' $at\n" . $hereptr)) {
4322b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4323b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4324b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4325b34c648bSJoe Perches							}
43263705ce5bSJoe Perches							$line_fixed = 1;
43273705ce5bSJoe Perches						}
43280a920b5bSAndy Whitcroft					}
432922f2a2efSAndy Whitcroft				}
43304a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
43313705ce5bSJoe Perches
43323705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
43333705ce5bSJoe Perches
43343705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
43350a920b5bSAndy Whitcroft			}
43363705ce5bSJoe Perches
43373705ce5bSJoe Perches			if (($#elements % 2) == 0) {
43383705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
43393705ce5bSJoe Perches			}
43403705ce5bSJoe Perches
4341194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4342194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
43433705ce5bSJoe Perches			}
43443705ce5bSJoe Perches
43453705ce5bSJoe Perches
43460a920b5bSAndy Whitcroft		}
43470a920b5bSAndy Whitcroft
4348786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4349d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4350786b6326SJoe Perches			if (WARN("SPACING",
4351786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4352786b6326SJoe Perches			    $fix) {
4353194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4354786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4355786b6326SJoe Perches			}
4356786b6326SJoe Perches		}
4357786b6326SJoe Perches
4358f0a594c1SAndy Whitcroft# check for multiple assignments
4359f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4360000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4361000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4362f0a594c1SAndy Whitcroft		}
4363f0a594c1SAndy Whitcroft
436422f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
436522f2a2efSAndy Whitcroft## # continuation.
436622f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
436722f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
436822f2a2efSAndy Whitcroft##
436922f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
437022f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
437122f2a2efSAndy Whitcroft## 			my $ln = $line;
437222f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
437322f2a2efSAndy Whitcroft## 			}
437422f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4375000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4376000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
437722f2a2efSAndy Whitcroft## 			}
437822f2a2efSAndy Whitcroft## 		}
4379f0a594c1SAndy Whitcroft
43800a920b5bSAndy Whitcroft#need space before brace following if, while, etc
43816b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
43824e5d56bdSEddie Kovsky		    $line =~ /do\{/) {
43833705ce5bSJoe Perches			if (ERROR("SPACING",
43843705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
43853705ce5bSJoe Perches			    $fix) {
4386194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/;
43873705ce5bSJoe Perches			}
4388de7d4f0eSAndy Whitcroft		}
4389de7d4f0eSAndy Whitcroft
4390c4a62ef9SJoe Perches## # check for blank lines before declarations
4391c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4392c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4393c4a62ef9SJoe Perches##			WARN("SPACING",
4394c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4395c4a62ef9SJoe Perches##		}
4396c4a62ef9SJoe Perches##
4397c4a62ef9SJoe Perches
4398de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4399de7d4f0eSAndy Whitcroft# on the line
4400de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
4401d5e616fcSJoe Perches			if (ERROR("SPACING",
4402d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4403d5e616fcSJoe Perches			    $fix) {
4404194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4405d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4406d5e616fcSJoe Perches			}
44070a920b5bSAndy Whitcroft		}
44080a920b5bSAndy Whitcroft
440922f2a2efSAndy Whitcroft# check spacing on square brackets
441022f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
44113705ce5bSJoe Perches			if (ERROR("SPACING",
44123705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
44133705ce5bSJoe Perches			    $fix) {
4414194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44153705ce5bSJoe Perches				    s/\[\s+/\[/;
44163705ce5bSJoe Perches			}
441722f2a2efSAndy Whitcroft		}
441822f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
44193705ce5bSJoe Perches			if (ERROR("SPACING",
44203705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
44213705ce5bSJoe Perches			    $fix) {
4422194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44233705ce5bSJoe Perches				    s/\s+\]/\]/;
44243705ce5bSJoe Perches			}
442522f2a2efSAndy Whitcroft		}
442622f2a2efSAndy Whitcroft
4427c45dcabdSAndy Whitcroft# check spacing on parentheses
44289c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
44299c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
44303705ce5bSJoe Perches			if (ERROR("SPACING",
44313705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
44323705ce5bSJoe Perches			    $fix) {
4433194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44343705ce5bSJoe Perches				    s/\(\s+/\(/;
44353705ce5bSJoe Perches			}
443622f2a2efSAndy Whitcroft		}
443713214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4438c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4439c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
44403705ce5bSJoe Perches			if (ERROR("SPACING",
44413705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
44423705ce5bSJoe Perches			    $fix) {
4443194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44443705ce5bSJoe Perches				    s/\s+\)/\)/;
44453705ce5bSJoe Perches			}
444622f2a2efSAndy Whitcroft		}
444722f2a2efSAndy Whitcroft
4448e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4449e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4450e2826fd0SJoe Perches
4451e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4452ea4acbb1SJoe Perches			my $var = $1;
4453ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4454ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4455ea4acbb1SJoe Perches			    $fix) {
4456ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4457ea4acbb1SJoe Perches			}
4458ea4acbb1SJoe Perches		}
4459ea4acbb1SJoe Perches
4460ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4461ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4462ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4463ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4464ea4acbb1SJoe Perches			my $var = $2;
4465ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4466ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4467ea4acbb1SJoe Perches			    $fix) {
4468ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4469ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4470ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4471ea4acbb1SJoe Perches			}
4472e2826fd0SJoe Perches		}
4473e2826fd0SJoe Perches
44740a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
44754a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
44760a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
44773705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
44783705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
44793705ce5bSJoe Perches			    $fix) {
4480194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44813705ce5bSJoe Perches				    s/^(.)\s+/$1/;
44823705ce5bSJoe Perches			}
44830a920b5bSAndy Whitcroft		}
44840a920b5bSAndy Whitcroft
44855b9553abSJoe Perches# return is not a function
4486507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4487c45dcabdSAndy Whitcroft			my $spacing = $1;
4488507e5141SJoe Perches			if ($^V && $^V ge 5.10.0 &&
44895b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
44905b9553abSJoe Perches				my $value = $1;
44915b9553abSJoe Perches				$value = deparenthesize($value);
44925b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4493000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4494000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
44955b9553abSJoe Perches				}
4496c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4497000d1cc1SJoe Perches				ERROR("SPACING",
4498000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4499c45dcabdSAndy Whitcroft			}
4500c45dcabdSAndy Whitcroft		}
4501507e5141SJoe Perches
4502b43ae21bSJoe Perches# unnecessary return in a void function
4503b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4504b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4505b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4506b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4507b43ae21bSJoe Perches		    $linenr >= 3 &&
4508b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4509b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
45109819cf25SJoe Perches			WARN("RETURN_VOID",
4511b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
45129819cf25SJoe Perches               }
45139819cf25SJoe Perches
4514189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
4515189248d8SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4516189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4517189248d8SJoe Perches			my $openparens = $1;
4518189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4519189248d8SJoe Perches			my $msg = "";
4520189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4521189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4522189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4523189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4524189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4525189248d8SJoe Perches			}
4526189248d8SJoe Perches		}
4527189248d8SJoe Perches
4528c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4529c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4530c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4531c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4532c5595fa2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4533c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4534c5595fa2SJoe Perches			my $lead = $1;
4535c5595fa2SJoe Perches			my $const = $2;
4536c5595fa2SJoe Perches			my $comp = $3;
4537c5595fa2SJoe Perches			my $to = $4;
4538c5595fa2SJoe Perches			my $newcomp = $comp;
4539f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4540c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4541c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4542c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4543c5595fa2SJoe Perches			    $fix) {
4544c5595fa2SJoe Perches				if ($comp eq "<") {
4545c5595fa2SJoe Perches					$newcomp = ">";
4546c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4547c5595fa2SJoe Perches					$newcomp = ">=";
4548c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4549c5595fa2SJoe Perches					$newcomp = "<";
4550c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4551c5595fa2SJoe Perches					$newcomp = "<=";
4552c5595fa2SJoe Perches				}
4553c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4554c5595fa2SJoe Perches			}
4555c5595fa2SJoe Perches		}
4556c5595fa2SJoe Perches
4557f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4558f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
455953a3c448SAndy Whitcroft			my $name = $1;
456053a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4561000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4562f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
456353a3c448SAndy Whitcroft			}
456453a3c448SAndy Whitcroft		}
4565c45dcabdSAndy Whitcroft
45660a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
45674a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
45683705ce5bSJoe Perches			if (ERROR("SPACING",
45693705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
45703705ce5bSJoe Perches			    $fix) {
4571194f66fcSJoe Perches				$fixed[$fixlinenr] =~
45723705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
45733705ce5bSJoe Perches			}
45740a920b5bSAndy Whitcroft		}
45750a920b5bSAndy Whitcroft
4576f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4577f5fe35ddSAndy Whitcroft# statements after the conditional.
4578170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
45793e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
45803e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
45813e469cdcSAndy Whitcroft					if (!defined $stat);
4582170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4583170d3a22SAndy Whitcroft						$remain_next, $off_next);
4584170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4585170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4586170d3a22SAndy Whitcroft
4587170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4588170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4589170d3a22SAndy Whitcroft				# then count those as offsets.
4590170d3a22SAndy Whitcroft				my ($whitespace) =
4591170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4592170d3a22SAndy Whitcroft				my $offset =
4593170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4594170d3a22SAndy Whitcroft
4595170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4596170d3a22SAndy Whitcroft								$offset} = 1;
4597170d3a22SAndy Whitcroft			}
4598170d3a22SAndy Whitcroft		}
4599170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4600c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4601170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4602171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
46038905a67cSAndy Whitcroft
4604b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4605000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4606000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
46078905a67cSAndy Whitcroft			}
46088905a67cSAndy Whitcroft
46098905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
46108905a67cSAndy Whitcroft			# conditional.
4611773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
46128905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
461313214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
461453210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
461553210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4616773647a0SAndy Whitcroft			{
4617bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4618bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4619bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
462042bdf74cSHidetoshi Seto				my $stat_real = '';
4621bb44ad39SAndy Whitcroft
462242bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
462342bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4624bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4625bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4626bb44ad39SAndy Whitcroft				}
4627bb44ad39SAndy Whitcroft
4628000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4629000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
46308905a67cSAndy Whitcroft			}
46318905a67cSAndy Whitcroft		}
46328905a67cSAndy Whitcroft
463313214adfSAndy Whitcroft# Check for bitwise tests written as boolean
463413214adfSAndy Whitcroft		if ($line =~ /
463513214adfSAndy Whitcroft			(?:
463613214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
463713214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
463813214adfSAndy Whitcroft				(?:\&\&|\|\|)
463913214adfSAndy Whitcroft			|
464013214adfSAndy Whitcroft				(?:\&\&|\|\|)
464113214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
464213214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
464313214adfSAndy Whitcroft			)/x)
464413214adfSAndy Whitcroft		{
4645000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4646000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
464713214adfSAndy Whitcroft		}
464813214adfSAndy Whitcroft
46498905a67cSAndy Whitcroft# if and else should not have general statements after it
465013214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
465113214adfSAndy Whitcroft			my $s = $1;
465213214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
465313214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4654000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4655000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
46560a920b5bSAndy Whitcroft			}
465713214adfSAndy Whitcroft		}
465839667782SAndy Whitcroft# if should not continue a brace
465939667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4660000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4661048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
466239667782SAndy Whitcroft				$herecurr);
466339667782SAndy Whitcroft		}
4664a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4665a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4666a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
46673fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4668a1080bf8SAndy Whitcroft			\s*return\s+
4669a1080bf8SAndy Whitcroft		    )/xg)
4670a1080bf8SAndy Whitcroft		{
4671000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4672000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4673a1080bf8SAndy Whitcroft		}
46740a920b5bSAndy Whitcroft
46750a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
46760a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
46778b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
46780a920b5bSAndy Whitcroft		    $previndent == $indent) {
46798b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
46808b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
46818b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46828b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46838b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46848b8856f4SJoe Perches				my $fixedline = $prevrawline;
46858b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
46868b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46878b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46888b8856f4SJoe Perches				}
46898b8856f4SJoe Perches				$fixedline = $rawline;
46908b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
46918b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46928b8856f4SJoe Perches			}
46930a920b5bSAndy Whitcroft		}
46940a920b5bSAndy Whitcroft
46958b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4696c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
4697c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4698c2fdda0dSAndy Whitcroft
4699c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
4700c2fdda0dSAndy Whitcroft			# conditional.
4701773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
4702c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
4703c2fdda0dSAndy Whitcroft
4704c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
47058b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
47068b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
47078b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
47088b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
47098b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
47108b8856f4SJoe Perches					my $fixedline = $prevrawline;
47118b8856f4SJoe Perches					my $trailing = $rawline;
47128b8856f4SJoe Perches					$trailing =~ s/^\+//;
47138b8856f4SJoe Perches					$trailing = trim($trailing);
47148b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
47158b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47168b8856f4SJoe Perches				}
4717c2fdda0dSAndy Whitcroft			}
4718c2fdda0dSAndy Whitcroft		}
4719c2fdda0dSAndy Whitcroft
472095e2c602SJoe Perches#Specific variable tests
4721323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
4722323c1260SJoe Perches			my $var = $1;
472395e2c602SJoe Perches
472495e2c602SJoe Perches#gcc binary extension
472595e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
4726d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
4727d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4728d5e616fcSJoe Perches				    $fix) {
4729d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
4730194f66fcSJoe Perches					$fixed[$fixlinenr] =~
4731d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
4732d5e616fcSJoe Perches				}
473395e2c602SJoe Perches			}
473495e2c602SJoe Perches
473595e2c602SJoe Perches#CamelCase
4736807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
4737be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
473822735ce8SJoe Perches#Ignore Page<foo> variants
4739807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
474022735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4741f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4742f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
4743f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
47447e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
47457e781f67SJoe Perches					my $word = $1;
47467e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4747d8b07710SJoe Perches					if ($check) {
4748d8b07710SJoe Perches						seed_camelcase_includes();
4749d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
4750d8b07710SJoe Perches							seed_camelcase_file($realfile);
4751d8b07710SJoe Perches							$camelcase_file_seeded = 1;
4752d8b07710SJoe Perches						}
4753d8b07710SJoe Perches					}
47547e781f67SJoe Perches					if (!defined $camelcase{$word}) {
47557e781f67SJoe Perches						$camelcase{$word} = 1;
4756be79794bSJoe Perches						CHK("CAMELCASE",
47577e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
47587e781f67SJoe Perches					}
4759323c1260SJoe Perches				}
4760323c1260SJoe Perches			}
47613445686aSJoe Perches		}
47620a920b5bSAndy Whitcroft
47630a920b5bSAndy Whitcroft#no spaces allowed after \ in define
4764d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
4765d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4766d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4767d5e616fcSJoe Perches			    $fix) {
4768194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
4769d5e616fcSJoe Perches			}
47700a920b5bSAndy Whitcroft		}
47710a920b5bSAndy Whitcroft
47720e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
47730e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
4774c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4775e09dec48SAndy Whitcroft			my $file = "$1.h";
4776e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
4777e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
4778e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
47797840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
4780c45dcabdSAndy Whitcroft			{
47810e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
47820e212e0aSFabian Frederick				if ($asminclude > 0) {
4783e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
4784000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
4785000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4786e09dec48SAndy Whitcroft					} else {
4787000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
4788000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4789e09dec48SAndy Whitcroft					}
47900a920b5bSAndy Whitcroft				}
47910a920b5bSAndy Whitcroft			}
47920e212e0aSFabian Frederick		}
47930a920b5bSAndy Whitcroft
4794653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
4795653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
4796cf655043SAndy Whitcroft# in a known good container
4797b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
4798b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4799d8aaf121SAndy Whitcroft			my $ln = $linenr;
4800d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
4801c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
4802c45dcabdSAndy Whitcroft			my $ctx = '';
480308a2843eSJoe Perches			my $has_flow_statement = 0;
480408a2843eSJoe Perches			my $has_arg_concat = 0;
4805c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
4806f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4807f74bd194SAndy Whitcroft			$ctx = $dstat;
4808c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4809a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4810c45dcabdSAndy Whitcroft
481108a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
481262e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
481308a2843eSJoe Perches
4814f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
4815f59b64bfSJoe Perches			my $define_args = $1;
4816f59b64bfSJoe Perches			my $define_stmt = $dstat;
4817f59b64bfSJoe Perches			my @def_args = ();
4818f59b64bfSJoe Perches
4819f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
4820f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
4821f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
4822f59b64bfSJoe Perches				@def_args = split(",", $define_args);
4823f59b64bfSJoe Perches			}
4824f59b64bfSJoe Perches
4825292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
4826c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
4827c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
4828c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
4829c45dcabdSAndy Whitcroft
4830c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
4831bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4832bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
48336b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
4834bf30d6edSAndy Whitcroft			{
4835c45dcabdSAndy Whitcroft			}
4836c45dcabdSAndy Whitcroft
4837e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
483833acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
483933acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
4840e45bab8eSAndy Whitcroft			{
4841e45bab8eSAndy Whitcroft			}
4842e45bab8eSAndy Whitcroft
484342e15293SJoe Perches			# Make asm volatile uses seem like a generic function
484442e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
484542e15293SJoe Perches
4846c45dcabdSAndy Whitcroft			my $exceptions = qr{
4847c45dcabdSAndy Whitcroft				$Declare|
4848c45dcabdSAndy Whitcroft				module_param_named|
4849a0a0a7a9SKees Cook				MODULE_PARM_DESC|
4850c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
4851c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
4852383099fdSAndy Whitcroft				__typeof__\(|
485322fd2d3eSStefani Seibold				union|
485422fd2d3eSStefani Seibold				struct|
4855ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
48566b10df42SVladimir Zapolskiy				^\"|\"$|
48576b10df42SVladimir Zapolskiy				^\[
4858c45dcabdSAndy Whitcroft			}x;
48595eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4860f59b64bfSJoe Perches
4861f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
4862f59b64bfSJoe Perches			my $herectx = $here . "\n";
4863f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
4864f59b64bfSJoe Perches
4865f59b64bfSJoe Perches			for (my $n = 0; $n < $stmt_cnt; $n++) {
4866f59b64bfSJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
4867f59b64bfSJoe Perches			}
4868f59b64bfSJoe Perches
4869f74bd194SAndy Whitcroft			if ($dstat ne '' &&
4870f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
4871f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
48723cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4873356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
4874f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
4875f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
4876e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
487772f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
4878f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
4879f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
4880f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
48814e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
4882f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4883c45dcabdSAndy Whitcroft			{
4884e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
4885e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4886e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
4887e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
4888f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4889f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4890f74bd194SAndy Whitcroft				} else {
4891000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
4892388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4893d8aaf121SAndy Whitcroft				}
4894f59b64bfSJoe Perches
4895f59b64bfSJoe Perches			}
48965207649bSJoe Perches
48975207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
48985207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
48995207649bSJoe Perches			my $first = 1;
49005207649bSJoe Perches			$define_stmt = "";
49015207649bSJoe Perches			foreach my $l (@stmt_array) {
49025207649bSJoe Perches				$l =~ s/\\$//;
49035207649bSJoe Perches				if ($first) {
49045207649bSJoe Perches					$define_stmt = $l;
49055207649bSJoe Perches					$first = 0;
49065207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
49075207649bSJoe Perches					$define_stmt .= substr($l, 1);
49085207649bSJoe Perches				}
49095207649bSJoe Perches			}
49105207649bSJoe Perches			$define_stmt =~ s/$;//g;
49115207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
49125207649bSJoe Perches			$define_stmt = trim($define_stmt);
49135207649bSJoe Perches
4914f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
4915f59b64bfSJoe Perches			foreach my $arg (@def_args) {
4916f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
49179192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
4918f59b64bfSJoe Perches				my $tmp = $define_stmt;
4919f59b64bfSJoe Perches				$tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
49205207649bSJoe Perches				$tmp =~ s/\#+\s*$arg\b//g;
4921f59b64bfSJoe Perches				$tmp =~ s/\b$arg\s*\#\#//g;
4922f59b64bfSJoe Perches				my $use_cnt = $tmp =~ s/\b$arg\b//g;
4923f59b64bfSJoe Perches				if ($use_cnt > 1) {
4924f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
4925f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
4926f59b64bfSJoe Perches				    }
49279192d41aSJoe Perches# check if any macro arguments may have other precedence issues
49289192d41aSJoe Perches				if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
49299192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
49309192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
49319192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
49329192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
49339192d41aSJoe Perches				}
49340a920b5bSAndy Whitcroft			}
49355023d347SJoe Perches
493608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
493708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
493808a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
493908a2843eSJoe Perches				my $herectx = $here . "\n";
494008a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
494108a2843eSJoe Perches
494208a2843eSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
494308a2843eSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
494408a2843eSJoe Perches				}
494508a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
494608a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
494708a2843eSJoe Perches			}
494808a2843eSJoe Perches
4949481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
49505023d347SJoe Perches
49515023d347SJoe Perches		} else {
49525023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
4953481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
4954481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
49555023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
49565023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
49575023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
49585023d347SJoe Perches			}
4959653d4876SAndy Whitcroft		}
49600a920b5bSAndy Whitcroft
4961b13edf7fSJoe Perches# do {} while (0) macro tests:
4962b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
4963b13edf7fSJoe Perches# macro should not end with a semicolon
4964b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4965b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
4966b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
4967b13edf7fSJoe Perches			my $ln = $linenr;
4968b13edf7fSJoe Perches			my $cnt = $realcnt;
4969b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
4970b13edf7fSJoe Perches			my $ctx = '';
4971b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
4972b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
4973b13edf7fSJoe Perches			$ctx = $dstat;
4974b13edf7fSJoe Perches
4975b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
49761b36b201SJoe Perches			$dstat =~ s/$;/ /g;
4977b13edf7fSJoe Perches
4978b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
4979b13edf7fSJoe Perches				my $stmts = $2;
4980b13edf7fSJoe Perches				my $semis = $3;
4981b13edf7fSJoe Perches
4982b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
4983b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
4984b13edf7fSJoe Perches				my $herectx = $here . "\n";
4985b13edf7fSJoe Perches
4986b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4987b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4988b13edf7fSJoe Perches				}
4989b13edf7fSJoe Perches
4990ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
4991ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
4992b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
4993b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
4994b13edf7fSJoe Perches				}
4995b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
4996b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
4997b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
4998b13edf7fSJoe Perches				}
4999f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5000f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5001f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5002f5ef95b1SJoe Perches				my $herectx = $here . "\n";
5003f5ef95b1SJoe Perches
5004f5ef95b1SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
5005f5ef95b1SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
5006f5ef95b1SJoe Perches				}
5007f5ef95b1SJoe Perches
5008f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5009f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5010b13edf7fSJoe Perches			}
5011b13edf7fSJoe Perches		}
5012b13edf7fSJoe Perches
5013080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5014080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
5015080ba929SMike Frysinger#	.
5016080ba929SMike Frysinger#	ALIGN(...)
5017080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
5018080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5019000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
5020000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5021080ba929SMike Frysinger		}
5022080ba929SMike Frysinger
5023f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
502413214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
502513214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5026cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
502713214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5028cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5029cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5030aad4f614SJoe Perches				my @allowed = ();
5031aad4f614SJoe Perches				my $allow = 0;
503213214adfSAndy Whitcroft				my $seen = 0;
5033773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5034cf655043SAndy Whitcroft				my $ln = $linenr - 1;
503513214adfSAndy Whitcroft				for my $chunk (@chunks) {
503613214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
503713214adfSAndy Whitcroft
5038773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5039773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5040773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5041773647a0SAndy Whitcroft
5042aad4f614SJoe Perches					$allowed[$allow] = 0;
5043773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5044773647a0SAndy Whitcroft
5045773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5046773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5047773647a0SAndy Whitcroft
5048773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5049cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5050cf655043SAndy Whitcroft
5051773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
505213214adfSAndy Whitcroft
505313214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
505413214adfSAndy Whitcroft
5055aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5056cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5057cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5058aad4f614SJoe Perches						$allowed[$allow] = 1;
505913214adfSAndy Whitcroft					}
506013214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5061cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5062aad4f614SJoe Perches						$allowed[$allow] = 1;
506313214adfSAndy Whitcroft					}
5064cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5065cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5066aad4f614SJoe Perches						$allowed[$allow] = 1;
506713214adfSAndy Whitcroft					}
5068aad4f614SJoe Perches					$allow++;
506913214adfSAndy Whitcroft				}
5070aad4f614SJoe Perches				if ($seen) {
5071aad4f614SJoe Perches					my $sum_allowed = 0;
5072aad4f614SJoe Perches					foreach (@allowed) {
5073aad4f614SJoe Perches						$sum_allowed += $_;
5074aad4f614SJoe Perches					}
5075aad4f614SJoe Perches					if ($sum_allowed == 0) {
5076000d1cc1SJoe Perches						WARN("BRACES",
5077000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5078aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5079aad4f614SJoe Perches						 $seen != $allow) {
5080aad4f614SJoe Perches						CHK("BRACES",
5081aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5082aad4f614SJoe Perches					}
508313214adfSAndy Whitcroft				}
508413214adfSAndy Whitcroft			}
508513214adfSAndy Whitcroft		}
5086773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
508713214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5088cf655043SAndy Whitcroft			my $allowed = 0;
5089f0a594c1SAndy Whitcroft
5090cf655043SAndy Whitcroft			# Check the pre-context.
5091cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5092cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5093cf655043SAndy Whitcroft				$allowed = 1;
5094f0a594c1SAndy Whitcroft			}
5095773647a0SAndy Whitcroft
5096773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5097773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5098773647a0SAndy Whitcroft
5099cf655043SAndy Whitcroft			# Check the condition.
5100cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5101773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5102cf655043SAndy Whitcroft			if (defined $cond) {
5103773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5104cf655043SAndy Whitcroft			}
5105cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5106cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5107cf655043SAndy Whitcroft				$allowed = 1;
5108cf655043SAndy Whitcroft			}
5109cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5110cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5111cf655043SAndy Whitcroft				$allowed = 1;
5112cf655043SAndy Whitcroft			}
5113cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5114cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5115cf655043SAndy Whitcroft				$allowed = 1;
5116cf655043SAndy Whitcroft			}
5117cf655043SAndy Whitcroft			# Check the post-context.
5118cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5119cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5120cf655043SAndy Whitcroft				if (defined $cond) {
5121773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5122cf655043SAndy Whitcroft				}
5123cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5124cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5125cf655043SAndy Whitcroft					$allowed = 1;
5126cf655043SAndy Whitcroft				}
5127cf655043SAndy Whitcroft			}
5128cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
512969932487SJustin P. Mattock				my $herectx = $here . "\n";
5130f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5131cf655043SAndy Whitcroft
5132f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
513369932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
5134cf655043SAndy Whitcroft				}
5135cf655043SAndy Whitcroft
5136000d1cc1SJoe Perches				WARN("BRACES",
5137000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5138f0a594c1SAndy Whitcroft			}
5139f0a594c1SAndy Whitcroft		}
5140f0a594c1SAndy Whitcroft
5141e4c5babdSJoe Perches# check for single line unbalanced braces
514295330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
514395330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5144e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5145e4c5babdSJoe Perches		}
5146e4c5babdSJoe Perches
51470979ae66SJoe Perches# check for unnecessary blank lines around braces
514877b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5149f8e58219SJoe Perches			if (CHK("BRACES",
5150f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5151f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5152f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5153f8e58219SJoe Perches			}
51540979ae66SJoe Perches		}
515577b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5156f8e58219SJoe Perches			if (CHK("BRACES",
5157f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5158f8e58219SJoe Perches			    $fix) {
5159f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5160f8e58219SJoe Perches			}
51610979ae66SJoe Perches		}
51620979ae66SJoe Perches
51634a0df2efSAndy Whitcroft# no volatiles please
51646c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
51656c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5166000d1cc1SJoe Perches			WARN("VOLATILE",
51678c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
51684a0df2efSAndy Whitcroft		}
51694a0df2efSAndy Whitcroft
51705e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
51715e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
51725e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
51735e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
517433acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
51755e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
51765e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
51775e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
51785e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
51795e4f6ba5SJoe Perches				     $fix &&
51805e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
51815e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
51825e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
51835e4f6ba5SJoe Perches				my $comma_close = "";
51845e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
51855e4f6ba5SJoe Perches					$comma_close = $1;
51865e4f6ba5SJoe Perches				}
51875e4f6ba5SJoe Perches
51885e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
51895e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
51905e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
51915e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
51925e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
51935e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
51945e4f6ba5SJoe Perches				$fixedline = $rawline;
51955e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
51965e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
51975e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
51985e4f6ba5SJoe Perches				}
51995e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
52005e4f6ba5SJoe Perches			}
52015e4f6ba5SJoe Perches		}
52025e4f6ba5SJoe Perches
52035e4f6ba5SJoe Perches# check for missing a space in a string concatenation
52045e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
52055e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
52065e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
52075e4f6ba5SJoe Perches		}
52085e4f6ba5SJoe Perches
520977cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5210e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5211e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5212e4b7d309SJoe Perches# function declarations
521377cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
521477cb8546SJoe Perches		    defined($context_function) &&
5215e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5216e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
521777cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5218e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
521977cb8546SJoe Perches		}
522077cb8546SJoe Perches
52215e4f6ba5SJoe Perches# check for spaces before a quoted newline
52225e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
52235e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
52245e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
52255e4f6ba5SJoe Perches			    $fix) {
52265e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
52275e4f6ba5SJoe Perches			}
52285e4f6ba5SJoe Perches
52295e4f6ba5SJoe Perches		}
52305e4f6ba5SJoe Perches
5231f17dba4fSJoe Perches# concatenated string without spaces between elements
523233acb54aSJoe Perches		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5233f17dba4fSJoe Perches			CHK("CONCATENATED_STRING",
5234f17dba4fSJoe Perches			    "Concatenated strings should use spaces between elements\n" . $herecurr);
5235f17dba4fSJoe Perches		}
5236f17dba4fSJoe Perches
523790ad30e5SJoe Perches# uncoalesced string fragments
523833acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
523990ad30e5SJoe Perches			WARN("STRING_FRAGMENTS",
524090ad30e5SJoe Perches			     "Consecutive strings are generally better as a single string\n" . $herecurr);
524190ad30e5SJoe Perches		}
524290ad30e5SJoe Perches
5243522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5244522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5245522b837cSAlexey Dobriyan		my $show_Z = 1;
52465e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5247522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
52485e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5249522b837cSAlexey Dobriyan			# check for %L
5250522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
52515e4f6ba5SJoe Perches				WARN("PRINTF_L",
5252522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5253522b837cSAlexey Dobriyan				$show_L = 0;
52545e4f6ba5SJoe Perches			}
5255522b837cSAlexey Dobriyan			# check for %Z
5256522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5257522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5258522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5259522b837cSAlexey Dobriyan				$show_Z = 0;
5260522b837cSAlexey Dobriyan			}
5261522b837cSAlexey Dobriyan			# check for 0x<decimal>
5262522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5263522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
52646e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
52656e300757SJoe Perches			}
52665e4f6ba5SJoe Perches		}
52675e4f6ba5SJoe Perches
52685e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
52695e4f6ba5SJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
52705e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
52715e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
52725e4f6ba5SJoe Perches		}
52735e4f6ba5SJoe Perches
527400df344fSAndy Whitcroft# warn about #if 0
5275c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5276000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
5277000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
5278de7d4f0eSAndy Whitcroft				$herecurr);
52794a0df2efSAndy Whitcroft		}
52804a0df2efSAndy Whitcroft
528103df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
528203df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5283100425deSJoe Perches			my $tested = quotemeta($1);
5284100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5285100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5286100425deSJoe Perches				my $func = $1;
5287100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5288100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5289100425deSJoe Perches				    $fix) {
5290100425deSJoe Perches					my $do_fix = 1;
5291100425deSJoe Perches					my $leading_tabs = "";
5292100425deSJoe Perches					my $new_leading_tabs = "";
5293100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5294100425deSJoe Perches						$leading_tabs = $1;
5295100425deSJoe Perches					} else {
5296100425deSJoe Perches						$do_fix = 0;
5297100425deSJoe Perches					}
5298100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5299100425deSJoe Perches						$new_leading_tabs = $1;
5300100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5301100425deSJoe Perches							$do_fix = 0;
5302100425deSJoe Perches						}
5303100425deSJoe Perches					} else {
5304100425deSJoe Perches						$do_fix = 0;
5305100425deSJoe Perches					}
5306100425deSJoe Perches					if ($do_fix) {
5307100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5308100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5309100425deSJoe Perches					}
5310100425deSJoe Perches				}
53114c432a8fSGreg Kroah-Hartman			}
53124c432a8fSGreg Kroah-Hartman		}
5313f0a594c1SAndy Whitcroft
5314ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5315ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5316ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5317ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5318ebfdc409SJoe Perches		    $linenr > 3) {
5319ebfdc409SJoe Perches			my $testval = $2;
5320ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5321ebfdc409SJoe Perches
5322ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5323ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5324ebfdc409SJoe Perches
5325fb0d0e08SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
5326ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5327ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5328ebfdc409SJoe Perches			}
5329ebfdc409SJoe Perches		}
5330ebfdc409SJoe Perches
5331f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5332dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5333f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5334f78d98f6SJoe Perches			my $level = $1;
5335f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5336f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5337f78d98f6SJoe Perches			    $fix) {
5338f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5339f78d98f6SJoe Perches			}
5340f78d98f6SJoe Perches		}
5341f78d98f6SJoe Perches
534245c55e92SJoe Perches# check for logging continuations
534345c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
534445c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
534545c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
534645c55e92SJoe Perches		}
534745c55e92SJoe Perches
5348abb08a53SJoe Perches# check for mask then right shift without a parentheses
5349abb08a53SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5350abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5351abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5352abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5353abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5354abb08a53SJoe Perches		}
5355abb08a53SJoe Perches
5356b75ac618SJoe Perches# check for pointer comparisons to NULL
5357b75ac618SJoe Perches		if ($^V && $^V ge 5.10.0) {
5358b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5359b75ac618SJoe Perches				my $val = $1;
5360b75ac618SJoe Perches				my $equal = "!";
5361b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5362b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5363b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5364b75ac618SJoe Perches					    $fix) {
5365b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5366b75ac618SJoe Perches				}
5367b75ac618SJoe Perches			}
5368b75ac618SJoe Perches		}
5369b75ac618SJoe Perches
53708716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
53718716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
53728716de38SJoe Perches			my $attr = $1;
53738716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
53748716de38SJoe Perches				my $ptr = $1;
53758716de38SJoe Perches				my $var = $2;
53768716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
53778716de38SJoe Perches				      ERROR("MISPLACED_INIT",
53788716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
53798716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
53808716de38SJoe Perches				      WARN("MISPLACED_INIT",
53818716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
53828716de38SJoe Perches				    $fix) {
5383194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
53848716de38SJoe Perches				}
53858716de38SJoe Perches			}
53868716de38SJoe Perches		}
53878716de38SJoe Perches
5388e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5389e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5390e970b884SJoe Perches			my $attr = $1;
5391e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5392e970b884SJoe Perches			my $attr_prefix = $1;
5393e970b884SJoe Perches			my $attr_type = $2;
5394e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5395e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5396e970b884SJoe Perches			    $fix) {
5397194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5398e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5399e970b884SJoe Perches			}
5400e970b884SJoe Perches		}
5401e970b884SJoe Perches
5402e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5403e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5404e970b884SJoe Perches			my $attr = $1;
5405e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5406e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5407e970b884SJoe Perches			    $fix) {
5408194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5409e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5410e970b884SJoe Perches				$lead = rtrim($1);
5411e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5412e970b884SJoe Perches				$lead = "${lead}const ";
5413194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5414e970b884SJoe Perches			}
5415e970b884SJoe Perches		}
5416e970b884SJoe Perches
5417c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5418c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5419c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5420c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5421c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5422c17893c7SJoe Perches			    $fix) {
5423c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5424c17893c7SJoe Perches			}
5425c17893c7SJoe Perches		}
5426c17893c7SJoe Perches
5427fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5428fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5429fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5430fbdb8138SJoe Perches			my $constant_func = $1;
5431fbdb8138SJoe Perches			my $func = $constant_func;
5432fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5433fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5434fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5435fbdb8138SJoe Perches			    $fix) {
5436194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5437fbdb8138SJoe Perches			}
5438fbdb8138SJoe Perches		}
5439fbdb8138SJoe Perches
54401a15a250SPatrick Pannuto# prefer usleep_range over udelay
544137581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
544243c1d77cSJoe Perches			my $delay = $1;
54431a15a250SPatrick Pannuto			# ignore udelay's < 10, however
544443c1d77cSJoe Perches			if (! ($delay < 10) ) {
5445000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
544643c1d77cSJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
544743c1d77cSJoe Perches			}
544843c1d77cSJoe Perches			if ($delay > 2000) {
544943c1d77cSJoe Perches				WARN("LONG_UDELAY",
545043c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
54511a15a250SPatrick Pannuto			}
54521a15a250SPatrick Pannuto		}
54531a15a250SPatrick Pannuto
545409ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
545509ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
545609ef8725SPatrick Pannuto			if ($1 < 20) {
5457000d1cc1SJoe Perches				WARN("MSLEEP",
545843c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
545909ef8725SPatrick Pannuto			}
546009ef8725SPatrick Pannuto		}
546109ef8725SPatrick Pannuto
546236ec1939SJoe Perches# check for comparisons of jiffies
546336ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
546436ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
546536ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
546636ec1939SJoe Perches		}
546736ec1939SJoe Perches
54689d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
54699d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
54709d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
54719d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
54729d7a34a5SJoe Perches		}
54739d7a34a5SJoe Perches
547400df344fSAndy Whitcroft# warn about #ifdefs in C files
5475c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
547600df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
547700df344fSAndy Whitcroft#			print "$herecurr";
547800df344fSAndy Whitcroft#			$clean = 0;
547900df344fSAndy Whitcroft#		}
548000df344fSAndy Whitcroft
548122f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5482c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
54833705ce5bSJoe Perches			if (ERROR("SPACING",
54843705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
54853705ce5bSJoe Perches			    $fix) {
5486194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54873705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
54883705ce5bSJoe Perches			}
54893705ce5bSJoe Perches
549022f2a2efSAndy Whitcroft		}
549122f2a2efSAndy Whitcroft
54924a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5493171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5494171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
54954a0df2efSAndy Whitcroft			my $which = $1;
54964a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5497000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5498000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
54994a0df2efSAndy Whitcroft			}
55004a0df2efSAndy Whitcroft		}
55014a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5502402c2553SMichael S. Tsirkin
5503402c2553SMichael S. Tsirkin		my $barriers = qr{
5504402c2553SMichael S. Tsirkin			mb|
5505402c2553SMichael S. Tsirkin			rmb|
5506402c2553SMichael S. Tsirkin			wmb|
5507402c2553SMichael S. Tsirkin			read_barrier_depends
5508402c2553SMichael S. Tsirkin		}x;
5509402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5510402c2553SMichael S. Tsirkin			mb__before_atomic|
5511402c2553SMichael S. Tsirkin			mb__after_atomic|
5512402c2553SMichael S. Tsirkin			store_release|
5513402c2553SMichael S. Tsirkin			load_acquire|
5514402c2553SMichael S. Tsirkin			store_mb|
5515402c2553SMichael S. Tsirkin			(?:$barriers)
5516402c2553SMichael S. Tsirkin		}x;
5517402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5518402c2553SMichael S. Tsirkin			(?:$barriers)|
551943e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
552043e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5521402c2553SMichael S. Tsirkin		}x;
5522402c2553SMichael S. Tsirkin
5523402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
55244a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5525c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5526000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
55274a0df2efSAndy Whitcroft			}
55284a0df2efSAndy Whitcroft		}
55293ad81779SPaul E. McKenney
5530f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5531f4073b0fSMichael S. Tsirkin
5532f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5533f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5534f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5535f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5536f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5537f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5538f4073b0fSMichael S. Tsirkin		}
5539f4073b0fSMichael S. Tsirkin
5540cb426e99SJoe Perches# check for waitqueue_active without a comment.
5541cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5542cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5543cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5544cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5545cb426e99SJoe Perches			}
5546cb426e99SJoe Perches		}
55473ad81779SPaul E. McKenney
55484a0df2efSAndy Whitcroft# check of hardware specific defines
5549c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5550000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5551000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
55520a920b5bSAndy Whitcroft		}
5553653d4876SAndy Whitcroft
5554d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
5555d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
5556000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5557000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
5558d4977c78STobias Klauser		}
5559d4977c78STobias Klauser
5560de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5561de7d4f0eSAndy Whitcroft# storage class and type.
55629c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
55639c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5564000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5565000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5566de7d4f0eSAndy Whitcroft		}
5567de7d4f0eSAndy Whitcroft
55688905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
55692b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55702b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5571d5e616fcSJoe Perches			if (WARN("INLINE",
5572d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5573d5e616fcSJoe Perches			    $fix) {
5574194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5575d5e616fcSJoe Perches
5576d5e616fcSJoe Perches			}
55778905a67cSAndy Whitcroft		}
55788905a67cSAndy Whitcroft
55793d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
55802b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55812b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5582000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5583000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
55843d130fd0SJoe Perches		}
55853d130fd0SJoe Perches
558639b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
55872b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55882b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5589000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5590000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
559139b7e287SJoe Perches		}
559239b7e287SJoe Perches
55935f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
55942b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55952b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5596d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5597d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5598d5e616fcSJoe Perches			    $fix) {
5599194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5600d5e616fcSJoe Perches
5601d5e616fcSJoe Perches			}
56025f14d3bdSJoe Perches		}
56035f14d3bdSJoe Perches
56046061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
56052b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
56062b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5607d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5608d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5609d5e616fcSJoe Perches			    $fix) {
5610194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5611d5e616fcSJoe Perches			}
56126061d949SJoe Perches		}
56136061d949SJoe Perches
5614619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
5615619a908aSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5616619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5617619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5618619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5619619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5620619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5621619a908aSJoe Perches		}
5622619a908aSJoe Perches
5623fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5624e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5625fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
5626e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5627e6176fa4SJoe Perches			my $type = $1;
5628e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
5629e6176fa4SJoe Perches				$type = $1;
5630e6176fa4SJoe Perches				my $kernel_type = 'u';
5631e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
5632e6176fa4SJoe Perches				$type =~ /(\d+)/;
5633e6176fa4SJoe Perches				$kernel_type .= $1;
5634e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5635e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5636e6176fa4SJoe Perches				    $fix) {
5637e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5638e6176fa4SJoe Perches				}
5639e6176fa4SJoe Perches			}
5640e6176fa4SJoe Perches		}
5641e6176fa4SJoe Perches
5642938224b5SJoe Perches# check for cast of C90 native int or longer types constants
5643938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5644938224b5SJoe Perches			my $cast = $1;
5645938224b5SJoe Perches			my $const = $2;
5646938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
5647938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5648938224b5SJoe Perches			    $fix) {
5649938224b5SJoe Perches				my $suffix = "";
5650938224b5SJoe Perches				my $newconst = $const;
5651938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
5652938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5653938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
5654938224b5SJoe Perches					$suffix .= 'LL';
5655938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
5656938224b5SJoe Perches					$suffix .= 'L';
5657938224b5SJoe Perches				}
5658938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5659938224b5SJoe Perches			}
5660938224b5SJoe Perches		}
5661938224b5SJoe Perches
56628f53a9b8SJoe Perches# check for sizeof(&)
56638f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5664000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5665000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
56668f53a9b8SJoe Perches		}
56678f53a9b8SJoe Perches
566866c80b60SJoe Perches# check for sizeof without parenthesis
566966c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5670d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5671d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5672d5e616fcSJoe Perches			    $fix) {
5673194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5674d5e616fcSJoe Perches			}
567566c80b60SJoe Perches		}
567666c80b60SJoe Perches
567788982feaSJoe Perches# check for struct spinlock declarations
567888982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
567988982feaSJoe Perches			WARN("USE_SPINLOCK_T",
568088982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
568188982feaSJoe Perches		}
568288982feaSJoe Perches
5683a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
568406668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5685a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5686caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5687caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5688d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5689d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5690d5e616fcSJoe Perches				    $fix) {
5691194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5692d5e616fcSJoe Perches				}
5693a6962d72SJoe Perches			}
5694a6962d72SJoe Perches		}
5695a6962d72SJoe Perches
56960b523769SJoe Perches		# check for vsprintf extension %p<foo> misuses
56970b523769SJoe Perches		if ($^V && $^V ge 5.10.0 &&
56980b523769SJoe Perches		    defined $stat &&
56990b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
57000b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
57010b523769SJoe Perches			my $bad_extension = "";
57020b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
57030b523769SJoe Perches			$lc = $lc + $linenr;
57040b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
57050b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
57060b523769SJoe Perches				$fmt =~ s/%%//g;
5707ce4fecf1SPantelis Antoniou				if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
57080b523769SJoe Perches					$bad_extension = $1;
57090b523769SJoe Perches					last;
57100b523769SJoe Perches				}
57110b523769SJoe Perches			}
57120b523769SJoe Perches			if ($bad_extension ne "") {
57130b523769SJoe Perches				my $stat_real = raw_line($linenr, 0);
57140b523769SJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
57150b523769SJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
57160b523769SJoe Perches				}
57170b523769SJoe Perches				WARN("VSPRINTF_POINTER_EXTENSION",
57180b523769SJoe Perches				     "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
57190b523769SJoe Perches			}
57200b523769SJoe Perches		}
57210b523769SJoe Perches
5722554e165cSAndy Whitcroft# Check for misused memsets
5723d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5724d1fe9c09SJoe Perches		    defined $stat &&
57259e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
5726554e165cSAndy Whitcroft
5727d7c76ba7SJoe Perches			my $ms_addr = $2;
5728d1fe9c09SJoe Perches			my $ms_val = $7;
5729d1fe9c09SJoe Perches			my $ms_size = $12;
5730d7c76ba7SJoe Perches
5731554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
5732554e165cSAndy Whitcroft				ERROR("MEMSET",
5733d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5734554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
5735554e165cSAndy Whitcroft				WARN("MEMSET",
5736d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5737d7c76ba7SJoe Perches			}
5738d7c76ba7SJoe Perches		}
5739d7c76ba7SJoe Perches
574098a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
5741f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5742f333195dSJoe Perches#		    defined $stat &&
5743f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5744f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
5745f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5746f333195dSJoe Perches#			    $fix) {
5747f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5748f333195dSJoe Perches#			}
5749f333195dSJoe Perches#		}
575098a9bba5SJoe Perches
5751b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
5752f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5753f333195dSJoe Perches#		    defined $stat &&
5754f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5755f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
5756f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5757f333195dSJoe Perches#		}
5758b6117d17SMateusz Kulikowski
57598617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
57608617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
5761f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5762f333195dSJoe Perches#		    defined $stat &&
5763f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5764f333195dSJoe Perches#
5765f333195dSJoe Perches#			my $ms_val = $7;
5766f333195dSJoe Perches#
5767f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
5768f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
5769f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5770f333195dSJoe Perches#				    $fix) {
5771f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5772f333195dSJoe Perches#				}
5773f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5774f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
5775f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
5776f333195dSJoe Perches#				    $fix) {
5777f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
5778f333195dSJoe Perches#				}
5779f333195dSJoe Perches#			}
5780f333195dSJoe Perches#		}
57818617cd09SMateusz Kulikowski
5782d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
5783d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5784d1fe9c09SJoe Perches		    defined $stat &&
5785d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5786d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
5787d7c76ba7SJoe Perches				my $call = $1;
5788d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
5789d7c76ba7SJoe Perches				my $arg1 = $3;
5790d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
5791d1fe9c09SJoe Perches				my $arg2 = $8;
5792d7c76ba7SJoe Perches				my $cast;
5793d7c76ba7SJoe Perches
5794d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5795d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
5796d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
5797d7c76ba7SJoe Perches					$cast = $cast1;
5798d7c76ba7SJoe Perches				} else {
5799d7c76ba7SJoe Perches					$cast = $cast2;
5800d7c76ba7SJoe Perches				}
5801d7c76ba7SJoe Perches				WARN("MINMAX",
5802d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5803554e165cSAndy Whitcroft			}
5804554e165cSAndy Whitcroft		}
5805554e165cSAndy Whitcroft
58064a273195SJoe Perches# check usleep_range arguments
58074a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
58084a273195SJoe Perches		    defined $stat &&
58094a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
58104a273195SJoe Perches			my $min = $1;
58114a273195SJoe Perches			my $max = $7;
58124a273195SJoe Perches			if ($min eq $max) {
58134a273195SJoe Perches				WARN("USLEEP_RANGE",
58144a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58154a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
58164a273195SJoe Perches				 $min > $max) {
58174a273195SJoe Perches				WARN("USLEEP_RANGE",
58184a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58194a273195SJoe Perches			}
58204a273195SJoe Perches		}
58214a273195SJoe Perches
5822823b794cSJoe Perches# check for naked sscanf
5823823b794cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5824823b794cSJoe Perches		    defined $stat &&
58256c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
5826823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5827823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5828823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5829823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
5830823b794cSJoe Perches			$lc = $lc + $linenr;
5831823b794cSJoe Perches			my $stat_real = raw_line($linenr, 0);
5832823b794cSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5833823b794cSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5834823b794cSJoe Perches			}
5835823b794cSJoe Perches			WARN("NAKED_SSCANF",
5836823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5837823b794cSJoe Perches		}
5838823b794cSJoe Perches
5839afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
5840afc819abSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5841afc819abSJoe Perches		    defined $stat &&
5842afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
5843afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
5844afc819abSJoe Perches			$lc = $lc + $linenr;
5845afc819abSJoe Perches			my $stat_real = raw_line($linenr, 0);
5846afc819abSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5847afc819abSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5848afc819abSJoe Perches			}
5849afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5850afc819abSJoe Perches				my $format = $6;
5851afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
5852afc819abSJoe Perches				if ($count == 1 &&
5853afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5854afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
5855afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5856afc819abSJoe Perches				}
5857afc819abSJoe Perches			}
5858afc819abSJoe Perches		}
5859afc819abSJoe Perches
586070dc8a48SJoe Perches# check for new externs in .h files.
586170dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
586270dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5863d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
586470dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
586570dc8a48SJoe Perches			    $fix) {
5866194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
586770dc8a48SJoe Perches			}
586870dc8a48SJoe Perches		}
586970dc8a48SJoe Perches
5870de7d4f0eSAndy Whitcroft# check for new externs in .c files.
5871171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
5872c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5873171ae1a4SAndy Whitcroft		{
5874c45dcabdSAndy Whitcroft			my $function_name = $1;
5875c45dcabdSAndy Whitcroft			my $paren_space = $2;
5876171ae1a4SAndy Whitcroft
5877171ae1a4SAndy Whitcroft			my $s = $stat;
5878171ae1a4SAndy Whitcroft			if (defined $cond) {
5879171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
5880171ae1a4SAndy Whitcroft			}
5881c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
5882c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
5883c45dcabdSAndy Whitcroft			{
5884000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
5885000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
5886de7d4f0eSAndy Whitcroft			}
5887de7d4f0eSAndy Whitcroft
5888171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
5889000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
5890000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
5891171ae1a4SAndy Whitcroft			}
58929c9ba34eSAndy Whitcroft
58939c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
58949c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
58959c9ba34eSAndy Whitcroft		{
5896000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
5897000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
5898171ae1a4SAndy Whitcroft		}
5899171ae1a4SAndy Whitcroft
5900ca0d8929SJoe Perches		if ($realfile =~ /\.[ch]$/ && defined $stat &&
5901ca0d8929SJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
5902ca0d8929SJoe Perches		    $1 ne "void") {
5903ca0d8929SJoe Perches			my $args = trim($1);
5904ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
5905ca0d8929SJoe Perches				my $arg = trim($1);
5906ca0d8929SJoe Perches				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
5907ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
5908ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
5909ca0d8929SJoe Perches				}
5910ca0d8929SJoe Perches			}
5911ca0d8929SJoe Perches		}
5912ca0d8929SJoe Perches
5913de7d4f0eSAndy Whitcroft# checks for new __setup's
5914de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
5915de7d4f0eSAndy Whitcroft			my $name = $1;
5916de7d4f0eSAndy Whitcroft
5917de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
5918000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
59198c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
5920de7d4f0eSAndy Whitcroft			}
5921653d4876SAndy Whitcroft		}
59229c0ca6f9SAndy Whitcroft
59239c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
5924caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
5925000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
5926000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
59279c0ca6f9SAndy Whitcroft		}
592813214adfSAndy Whitcroft
5929a640d25cSJoe Perches# alloc style
5930a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
5931a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5932a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
5933a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
5934a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
5935a640d25cSJoe Perches		}
5936a640d25cSJoe Perches
593760a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
593860a55369SJoe Perches		if ($^V && $^V ge 5.10.0 &&
59391b4a2ed4SJoe Perches		    defined $stat &&
59401b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
594160a55369SJoe Perches			my $oldfunc = $3;
594260a55369SJoe Perches			my $a1 = $4;
594360a55369SJoe Perches			my $a2 = $10;
594460a55369SJoe Perches			my $newfunc = "kmalloc_array";
594560a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
594660a55369SJoe Perches			my $r1 = $a1;
594760a55369SJoe Perches			my $r2 = $a2;
594860a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
594960a55369SJoe Perches				$r1 = $a2;
595060a55369SJoe Perches				$r2 = $a1;
595160a55369SJoe Perches			}
5952e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
5953e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
59541b4a2ed4SJoe Perches				my $ctx = '';
59551b4a2ed4SJoe Perches				my $herectx = $here . "\n";
59561b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
59571b4a2ed4SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
59581b4a2ed4SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
59591b4a2ed4SJoe Perches				}
5960e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
59611b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
59621b4a2ed4SJoe Perches				    $cnt == 1 &&
5963e367455aSJoe Perches				    $fix) {
5964194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
596560a55369SJoe Perches				}
596660a55369SJoe Perches			}
596760a55369SJoe Perches		}
596860a55369SJoe Perches
5969972fdea2SJoe Perches# check for krealloc arg reuse
5970972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5971972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
5972972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
5973972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
5974972fdea2SJoe Perches		}
5975972fdea2SJoe Perches
59765ce59ae0SJoe Perches# check for alloc argument mismatch
59775ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
59785ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
59795ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
59805ce59ae0SJoe Perches		}
59815ce59ae0SJoe Perches
5982caf2a54fSJoe Perches# check for multiple semicolons
5983caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
5984d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
5985d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
5986d5e616fcSJoe Perches			    $fix) {
5987194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
5988d5e616fcSJoe Perches			}
5989d1e2ad07SJoe Perches		}
5990d1e2ad07SJoe Perches
5991cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
5992cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
5993cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
59940ab90191SJoe Perches			my $ull = "";
59950ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
59960ab90191SJoe Perches			if (CHK("BIT_MACRO",
59970ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
59980ab90191SJoe Perches			    $fix) {
59990ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
60000ab90191SJoe Perches			}
60010ab90191SJoe Perches		}
60020ab90191SJoe Perches
60032d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
60042d632745SJoe Perches		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
60052d632745SJoe Perches			my $config = $1;
60062d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
60072d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
60082d632745SJoe Perches			    $fix) {
60092d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
60102d632745SJoe Perches			}
60112d632745SJoe Perches		}
60122d632745SJoe Perches
6013e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6014c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6015c34c09a8SJoe Perches			my $has_break = 0;
6016c34c09a8SJoe Perches			my $has_statement = 0;
6017c34c09a8SJoe Perches			my $count = 0;
6018c34c09a8SJoe Perches			my $prevline = $linenr;
6019e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6020c34c09a8SJoe Perches				$prevline--;
6021c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6022c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6023c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6024c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6025c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6026c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6027c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6028c34c09a8SJoe Perches				$has_statement = 1;
6029c34c09a8SJoe Perches				$count++;
6030c34c09a8SJoe Perches				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
6031c34c09a8SJoe Perches			}
6032c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6033c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6034224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6035c34c09a8SJoe Perches			}
6036c34c09a8SJoe Perches		}
6037c34c09a8SJoe Perches
6038d1e2ad07SJoe Perches# check for switch/default statements without a break;
6039d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
6040d1e2ad07SJoe Perches		    defined $stat &&
6041d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6042d1e2ad07SJoe Perches			my $ctx = '';
6043d1e2ad07SJoe Perches			my $herectx = $here . "\n";
6044d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6045d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6046d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
6047d1e2ad07SJoe Perches			}
6048d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6049d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6050caf2a54fSJoe Perches		}
6051caf2a54fSJoe Perches
605213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6053d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6054d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6055d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6056d5e616fcSJoe Perches			    $fix) {
6057194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6058d5e616fcSJoe Perches			}
605913214adfSAndy Whitcroft		}
6060773647a0SAndy Whitcroft
606162ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
606262ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
606362ec818fSJoe Perches			ERROR("DATE_TIME",
606462ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
606562ec818fSJoe Perches		}
606662ec818fSJoe Perches
60672c92488aSJoe Perches# check for use of yield()
60682c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
60692c92488aSJoe Perches			WARN("YIELD",
60702c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
60712c92488aSJoe Perches		}
60722c92488aSJoe Perches
6073179f8f40SJoe Perches# check for comparisons against true and false
6074179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6075179f8f40SJoe Perches			my $lead = $1;
6076179f8f40SJoe Perches			my $arg = $2;
6077179f8f40SJoe Perches			my $test = $3;
6078179f8f40SJoe Perches			my $otype = $4;
6079179f8f40SJoe Perches			my $trail = $5;
6080179f8f40SJoe Perches			my $op = "!";
6081179f8f40SJoe Perches
6082179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6083179f8f40SJoe Perches
6084179f8f40SJoe Perches			my $type = lc($otype);
6085179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6086179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6087179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6088179f8f40SJoe Perches					$op = "";
6089179f8f40SJoe Perches				}
6090179f8f40SJoe Perches
6091179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6092179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6093179f8f40SJoe Perches
6094179f8f40SJoe Perches## maybe suggesting a correct construct would better
6095179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6096179f8f40SJoe Perches
6097179f8f40SJoe Perches			}
6098179f8f40SJoe Perches		}
6099179f8f40SJoe Perches
61004882720bSThomas Gleixner# check for semaphores initialized locked
61014882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6102000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6103000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6104773647a0SAndy Whitcroft		}
61056712d858SJoe Perches
610667d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
610767d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6108000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
610967d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6110773647a0SAndy Whitcroft		}
61116712d858SJoe Perches
6112ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6113f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6114000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6115ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6116f3db6639SMichael Ellerman		}
61176712d858SJoe Perches
61180f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6119d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
61206903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6121d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6122000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6123d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
61242b6db5cbSAndy Whitcroft		}
6125773647a0SAndy Whitcroft
6126773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6127773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6128773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6129c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6130c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6131171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6132171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6133171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6134773647a0SAndy Whitcroft		{
6135000d1cc1SJoe Perches			WARN("NR_CPUS",
6136000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6137773647a0SAndy Whitcroft		}
61389c9ba34eSAndy Whitcroft
613952ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
614052ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
614152ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
614252ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
614352ea8506SJoe Perches		}
614452ea8506SJoe Perches
6145acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6146acd9362cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6147acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6148acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6149acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6150acd9362cSJoe Perches		}
6151acd9362cSJoe Perches
6152691d77b6SAndy Whitcroft# whine mightly about in_atomic
6153691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6154691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6155000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6156000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6157f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6158000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6159000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6160691d77b6SAndy Whitcroft			}
6161691d77b6SAndy Whitcroft		}
61621704f47bSPeter Zijlstra
6163481aea5cSJoe Perches# whine about ACCESS_ONCE
6164481aea5cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6165481aea5cSJoe Perches		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
6166481aea5cSJoe Perches			my $par = $1;
6167481aea5cSJoe Perches			my $eq = $2;
6168481aea5cSJoe Perches			my $fun = $3;
6169481aea5cSJoe Perches			$par =~ s/^\(\s*(.*)\s*\)$/$1/;
6170481aea5cSJoe Perches			if (defined($eq)) {
6171481aea5cSJoe Perches				if (WARN("PREFER_WRITE_ONCE",
6172481aea5cSJoe Perches					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
6173481aea5cSJoe Perches				    $fix) {
6174481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
6175481aea5cSJoe Perches				}
6176481aea5cSJoe Perches			} else {
6177481aea5cSJoe Perches				if (WARN("PREFER_READ_ONCE",
6178481aea5cSJoe Perches					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
6179481aea5cSJoe Perches				    $fix) {
6180481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
6181481aea5cSJoe Perches				}
6182481aea5cSJoe Perches			}
6183481aea5cSJoe Perches		}
6184481aea5cSJoe Perches
61850f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
61860f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
61870f5225b0SPeter Zijlstra			ERROR("LOCKING",
61880f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
61890f5225b0SPeter Zijlstra		}
61900f5225b0SPeter Zijlstra
61911704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
61921704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
61931704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
61941704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
61951704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
61961704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6197000d1cc1SJoe Perches				ERROR("LOCKDEP",
6198000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
61991704f47bSPeter Zijlstra			}
62001704f47bSPeter Zijlstra		}
620188f8831cSDave Jones
6202b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6203b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6204000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6205000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
620688f8831cSDave Jones		}
62072435880fSJoe Perches
6208515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6209515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6210515a235eSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6211459cf0aeSJoe Perches		    defined $stat &&
6212515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
62132435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
62142435880fSJoe Perches				my $func = $entry->[0];
62152435880fSJoe Perches				my $arg_pos = $entry->[1];
62162435880fSJoe Perches
6217459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6218459cf0aeSJoe Perches				$lc = $lc + $linenr;
6219459cf0aeSJoe Perches				my $stat_real = raw_line($linenr, 0);
6220459cf0aeSJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
6221459cf0aeSJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
6222459cf0aeSJoe Perches				}
6223459cf0aeSJoe Perches
62242435880fSJoe Perches				my $skip_args = "";
62252435880fSJoe Perches				if ($arg_pos > 1) {
62262435880fSJoe Perches					$arg_pos--;
62272435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
62282435880fSJoe Perches				}
6229f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6230459cf0aeSJoe Perches				if ($stat =~ /$test/) {
62312435880fSJoe Perches					my $val = $1;
62322435880fSJoe Perches					$val = $6 if ($skip_args ne "");
6233f90774e1SJoe Perches					if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6234f90774e1SJoe Perches					    ($val =~ /^$Octal$/ && length($val) ne 4)) {
62352435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6236459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6237f90774e1SJoe Perches					}
6238f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6239c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6240459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
62412435880fSJoe Perches					}
6242459cf0aeSJoe Perches				}
6243459cf0aeSJoe Perches			}
6244459cf0aeSJoe Perches		}
6245459cf0aeSJoe Perches
6246459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6247459cf0aeSJoe Perches		if ($line =~ /\b$mode_perms_string_search\b/) {
6248459cf0aeSJoe Perches			my $val = "";
6249459cf0aeSJoe Perches			my $oval = "";
6250f90774e1SJoe Perches			my $to = 0;
6251459cf0aeSJoe Perches			my $curpos = 0;
6252459cf0aeSJoe Perches			my $lastpos = 0;
6253459cf0aeSJoe Perches			while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6254459cf0aeSJoe Perches				$curpos = pos($line);
6255459cf0aeSJoe Perches				my $match = $2;
6256459cf0aeSJoe Perches				my $omatch = $1;
6257459cf0aeSJoe Perches				last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6258459cf0aeSJoe Perches				$lastpos = $curpos;
6259459cf0aeSJoe Perches				$to |= $mode_permission_string_types{$match};
6260459cf0aeSJoe Perches				$val .= '\s*\|\s*' if ($val ne "");
6261459cf0aeSJoe Perches				$val .= $match;
6262459cf0aeSJoe Perches				$oval .= $omatch;
6263f90774e1SJoe Perches			}
6264459cf0aeSJoe Perches			$oval =~ s/^\s*\|\s*//;
6265459cf0aeSJoe Perches			$oval =~ s/\s*\|\s*$//;
6266459cf0aeSJoe Perches			my $octal = sprintf("%04o", $to);
6267f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6268459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6269f90774e1SJoe Perches			    $fix) {
6270459cf0aeSJoe Perches				$fixed[$fixlinenr] =~ s/$val/$octal/;
62712435880fSJoe Perches			}
627213214adfSAndy Whitcroft		}
62735a6d20ceSBjorn Andersson
62745a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
62755a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
62765a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
62775a6d20ceSBjorn Andersson			my $valid_licenses = qr{
62785a6d20ceSBjorn Andersson						GPL|
62795a6d20ceSBjorn Andersson						GPL\ v2|
62805a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
62815a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
62825a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
62835a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
62845a6d20ceSBjorn Andersson						Proprietary
62855a6d20ceSBjorn Andersson					}x;
62865a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
62875a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
62885a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
62895a6d20ceSBjorn Andersson			}
62905a6d20ceSBjorn Andersson		}
6291515a235eSJoe Perches	}
629213214adfSAndy Whitcroft
629313214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
629413214adfSAndy Whitcroft	# so just keep quiet.
629513214adfSAndy Whitcroft	if ($#rawlines == -1) {
629613214adfSAndy Whitcroft		exit(0);
62970a920b5bSAndy Whitcroft	}
62980a920b5bSAndy Whitcroft
62998905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
63008905a67cSAndy Whitcroft	# things that appear to be patches.
63018905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
63028905a67cSAndy Whitcroft		exit(0);
63038905a67cSAndy Whitcroft	}
63048905a67cSAndy Whitcroft
63058905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
63068905a67cSAndy Whitcroft	# just keep quiet.
63078905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
63088905a67cSAndy Whitcroft		exit(0);
63098905a67cSAndy Whitcroft	}
63108905a67cSAndy Whitcroft
631106330fc4SJoe Perches	if (!$is_patch && $file !~ /cover-letter\.patch$/) {
6312000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6313000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
63140a920b5bSAndy Whitcroft	}
6315ed43c4e5SAllen Hubbe	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
6316000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
6317000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
63180a920b5bSAndy Whitcroft	}
63190a920b5bSAndy Whitcroft
6320f0a594c1SAndy Whitcroft	print report_dump();
632113214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
632213214adfSAndy Whitcroft		print "$filename " if ($summary_file);
63236c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
63246c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
63256c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
63266c72ffaaSAndy Whitcroft	}
63278905a67cSAndy Whitcroft
6328d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6329ef212196SJoe Perches		# If there were any defects found and not already fixing them
6330ef212196SJoe Perches		if (!$clean and !$fix) {
6331ef212196SJoe Perches			print << "EOM"
6332ef212196SJoe Perches
6333ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6334ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6335ef212196SJoe PerchesEOM
6336ef212196SJoe Perches		}
6337d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6338d2c0a235SAndy Whitcroft		# then suggest that.
6339d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6340b0781216SMike Frysinger			$rpt_cleaners = 0;
6341d8469f16SJoe Perches			print << "EOM"
6342d8469f16SJoe Perches
6343d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6344d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6345d8469f16SJoe PerchesEOM
6346d2c0a235SAndy Whitcroft		}
6347d2c0a235SAndy Whitcroft	}
6348d2c0a235SAndy Whitcroft
6349d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6350d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6351d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
63529624b8d6SJoe Perches		my $newfile = $filename;
63539624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
63543705ce5bSJoe Perches		my $linecount = 0;
63553705ce5bSJoe Perches		my $f;
63563705ce5bSJoe Perches
6357d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6358d752fcc8SJoe Perches
63593705ce5bSJoe Perches		open($f, '>', $newfile)
63603705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
63613705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
63623705ce5bSJoe Perches			$linecount++;
63633705ce5bSJoe Perches			if ($file) {
63643705ce5bSJoe Perches				if ($linecount > 3) {
63653705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
63663705ce5bSJoe Perches					print $f $fixed_line . "\n";
63673705ce5bSJoe Perches				}
63683705ce5bSJoe Perches			} else {
63693705ce5bSJoe Perches				print $f $fixed_line . "\n";
63703705ce5bSJoe Perches			}
63713705ce5bSJoe Perches		}
63723705ce5bSJoe Perches		close($f);
63733705ce5bSJoe Perches
63743705ce5bSJoe Perches		if (!$quiet) {
63753705ce5bSJoe Perches			print << "EOM";
6376d8469f16SJoe Perches
63773705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
63783705ce5bSJoe Perches
63793705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
63803705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
63813705ce5bSJoe Perches
63823705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
63833705ce5bSJoe PerchesNo warranties, expressed or implied...
63843705ce5bSJoe PerchesEOM
63853705ce5bSJoe Perches		}
63863705ce5bSJoe Perches	}
63873705ce5bSJoe Perches
6388d8469f16SJoe Perches	if ($quiet == 0) {
6389d8469f16SJoe Perches		print "\n";
6390d8469f16SJoe Perches		if ($clean == 1) {
6391d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6392d8469f16SJoe Perches		} else {
6393d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
63940a920b5bSAndy Whitcroft		}
63950a920b5bSAndy Whitcroft	}
63960a920b5bSAndy Whitcroft	return $clean;
63970a920b5bSAndy Whitcroft}
6398