xref: /linux-6.15/scripts/checkpatch.pl (revision bdc48fa1)
1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl
2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0
3882ea1d6SJoe Perches#
4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit)
500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit)
62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)
7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]>
8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]>
90a920b5bSAndy Whitcroft
100a920b5bSAndy Whitcroftuse strict;
11cb77f0d6SKamil Rytarowskiuse warnings;
12c707a81dSJoe Perchesuse POSIX;
1336061e38SJoe Perchesuse File::Basename;
1436061e38SJoe Perchesuse Cwd 'abs_path';
1557230297SJoe Perchesuse Term::ANSIColor qw(:constants);
16cd261496SGeert Uytterhoevenuse Encode qw(decode encode);
170a920b5bSAndy Whitcroft
180a920b5bSAndy Whitcroftmy $P = $0;
1936061e38SJoe Perchesmy $D = dirname(abs_path($P));
200a920b5bSAndy Whitcroft
21000d1cc1SJoe Perchesmy $V = '0.32';
220a920b5bSAndy Whitcroft
230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
240a920b5bSAndy Whitcroft
250a920b5bSAndy Whitcroftmy $quiet = 0;
260a920b5bSAndy Whitcroftmy $tree = 1;
270a920b5bSAndy Whitcroftmy $chk_signoff = 1;
280a920b5bSAndy Whitcroftmy $chk_patch = 1;
29773647a0SAndy Whitcroftmy $tst_only;
306c72ffaaSAndy Whitcroftmy $emacs = 0;
318905a67cSAndy Whitcroftmy $terse = 0;
3234d8815fSJoe Perchesmy $showfile = 0;
336c72ffaaSAndy Whitcroftmy $file = 0;
344a593c34SDu, Changbinmy $git = 0;
350dea9f1eSJoe Perchesmy %git_commits = ();
366c72ffaaSAndy Whitcroftmy $check = 0;
372ac73b4fSJoe Perchesmy $check_orig = 0;
388905a67cSAndy Whitcroftmy $summary = 1;
398905a67cSAndy Whitcroftmy $mailback = 0;
4013214adfSAndy Whitcroftmy $summary_file = 0;
41000d1cc1SJoe Perchesmy $show_types = 0;
423beb42ecSJoe Perchesmy $list_types = 0;
433705ce5bSJoe Perchesmy $fix = 0;
449624b8d6SJoe Perchesmy $fix_inplace = 0;
456c72ffaaSAndy Whitcroftmy $root;
46c2fdda0dSAndy Whitcroftmy %debug;
473445686aSJoe Perchesmy %camelcase = ();
4891bfe484SJoe Perchesmy %use_type = ();
4991bfe484SJoe Perchesmy @use = ();
5091bfe484SJoe Perchesmy %ignore_type = ();
51000d1cc1SJoe Perchesmy @ignore = ();
5277f5b10aSHannes Edermy $help = 0;
53000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
54*bdc48fa1SJoe Perchesmy $max_line_length = 100;
55d62a201fSDave Hansenmy $ignore_perl_version = 0;
56d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5756193274SVadim Bendeburymy $min_conf_desc_length = 4;
5866b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
59ebfd7d62SJoe Perchesmy $codespell = 0;
60f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
61bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
6275ad8c57SJerome Forissiermy $typedefsfile = "";
63737c0767SJohn Brooksmy $color = "auto";
6498005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
65dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
66dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
67713a09deSAntonio Borneomy $tabsize = 8;
6877f5b10aSHannes Eder
6977f5b10aSHannes Edersub help {
7077f5b10aSHannes Eder	my ($exitcode) = @_;
7177f5b10aSHannes Eder
7277f5b10aSHannes Eder	print << "EOM";
7377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
7477f5b10aSHannes EderVersion: $V
7577f5b10aSHannes Eder
7677f5b10aSHannes EderOptions:
7777f5b10aSHannes Eder  -q, --quiet                quiet
7877f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7977f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
8077f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
8177f5b10aSHannes Eder  --emacs                    emacs compile window format
8277f5b10aSHannes Eder  --terse                    one line per report
8334d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
844a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
854a593c34SDu, Changbin                             single git commit with:
864a593c34SDu, Changbin                               <rev>
874a593c34SDu, Changbin                               <rev>^
884a593c34SDu, Changbin                               <rev>~n
894a593c34SDu, Changbin                             multiple git commits with:
904a593c34SDu, Changbin                               <rev1>..<rev2>
914a593c34SDu, Changbin                               <rev1>...<rev2>
924a593c34SDu, Changbin                               <rev>-<count>
934a593c34SDu, Changbin                             git merges are ignored
9477f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
9577f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
963beb42ecSJoe Perches  --list-types               list the possible message types
9791bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
98000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
993beb42ecSJoe Perches  --show-types               show the specific message type in the output
100*bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
101*bdc48fa1SJoe Perches                             if exceeded, warn on patches
102*bdc48fa1SJoe Perches                             requires --strict for use with --file
10356193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
104*bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
10577f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
10677f5b10aSHannes Eder  --no-summary               suppress the per-file summary
10777f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
10877f5b10aSHannes Eder  --summary-file             include the filename in summary
10977f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
11077f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
11177f5b10aSHannes Eder                             is all off)
11277f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
11377f5b10aSHannes Eder                             literally
1143705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1153705ce5bSJoe Perches                             If correctable single-line errors exist, create
1163705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1173705ce5bSJoe Perches                             with potential errors corrected to the preferred
1183705ce5bSJoe Perches                             checkpatch style
1199624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1209624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1219624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
122d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
123d62a201fSDave Hansen                             runtime errors.
124ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
125f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
126ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
12775ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
128737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
129737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
13077f5b10aSHannes Eder  -h, --help, --version      display this help and exit
13177f5b10aSHannes Eder
13277f5b10aSHannes EderWhen FILE is - read standard input.
13377f5b10aSHannes EderEOM
13477f5b10aSHannes Eder
13577f5b10aSHannes Eder	exit($exitcode);
13677f5b10aSHannes Eder}
13777f5b10aSHannes Eder
1383beb42ecSJoe Perchessub uniq {
1393beb42ecSJoe Perches	my %seen;
1403beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1413beb42ecSJoe Perches}
1423beb42ecSJoe Perches
1433beb42ecSJoe Perchessub list_types {
1443beb42ecSJoe Perches	my ($exitcode) = @_;
1453beb42ecSJoe Perches
1463beb42ecSJoe Perches	my $count = 0;
1473beb42ecSJoe Perches
1483beb42ecSJoe Perches	local $/ = undef;
1493beb42ecSJoe Perches
1503beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1513beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1523beb42ecSJoe Perches
1533beb42ecSJoe Perches	my $text = <$script>;
1543beb42ecSJoe Perches	close($script);
1553beb42ecSJoe Perches
1563beb42ecSJoe Perches	my @types = ();
1570547fa58SJean Delvare	# Also catch when type or level is passed through a variable
1580547fa58SJean Delvare	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
1593beb42ecSJoe Perches		push (@types, $_);
1603beb42ecSJoe Perches	}
1613beb42ecSJoe Perches	@types = sort(uniq(@types));
1623beb42ecSJoe Perches	print("#\tMessage type\n\n");
1633beb42ecSJoe Perches	foreach my $type (@types) {
1643beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1653beb42ecSJoe Perches	}
1663beb42ecSJoe Perches
1673beb42ecSJoe Perches	exit($exitcode);
1683beb42ecSJoe Perches}
1693beb42ecSJoe Perches
170000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
171000d1cc1SJoe Perchesif (-f $conf) {
172000d1cc1SJoe Perches	my @conf_args;
173000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
174000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
175000d1cc1SJoe Perches
176000d1cc1SJoe Perches	while (<$conffile>) {
177000d1cc1SJoe Perches		my $line = $_;
178000d1cc1SJoe Perches
179000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
180000d1cc1SJoe Perches		$line =~ s/^\s*//g;
181000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
182000d1cc1SJoe Perches
183000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
184000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
185000d1cc1SJoe Perches
186000d1cc1SJoe Perches		my @words = split(" ", $line);
187000d1cc1SJoe Perches		foreach my $word (@words) {
188000d1cc1SJoe Perches			last if ($word =~ m/^#/);
189000d1cc1SJoe Perches			push (@conf_args, $word);
190000d1cc1SJoe Perches		}
191000d1cc1SJoe Perches	}
192000d1cc1SJoe Perches	close($conffile);
193000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
194000d1cc1SJoe Perches}
195000d1cc1SJoe Perches
196737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
197737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
198737c0767SJohn Brooksforeach (@ARGV) {
199737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
200737c0767SJohn Brooks		$_ = "--color=$color";
201737c0767SJohn Brooks	}
202737c0767SJohn Brooks}
203737c0767SJohn Brooks
2040a920b5bSAndy WhitcroftGetOptions(
2056c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
2060a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2070a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2080a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2096c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2108905a67cSAndy Whitcroft	'terse!'	=> \$terse,
21134d8815fSJoe Perches	'showfile!'	=> \$showfile,
21277f5b10aSHannes Eder	'f|file!'	=> \$file,
2134a593c34SDu, Changbin	'g|git!'	=> \$git,
2146c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
2156c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
216000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
21791bfe484SJoe Perches	'types=s'	=> \@use,
218000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2193beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2206cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
22156193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
222713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
2236c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2248905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2258905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
22613214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2273705ce5bSJoe Perches	'fix!'		=> \$fix,
2289624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
229d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
230c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
231773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
232ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
233ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
23475ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
235737c0767SJohn Brooks	'color=s'	=> \$color,
236737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
237737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
23877f5b10aSHannes Eder	'h|help'	=> \$help,
23977f5b10aSHannes Eder	'version'	=> \$help
24077f5b10aSHannes Eder) or help(1);
24177f5b10aSHannes Eder
24277f5b10aSHannes Ederhelp(0) if ($help);
2430a920b5bSAndy Whitcroft
2443beb42ecSJoe Percheslist_types(0) if ($list_types);
2453beb42ecSJoe Perches
2469624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2472ac73b4fSJoe Perches$check_orig = $check;
2489624b8d6SJoe Perches
2490a920b5bSAndy Whitcroftmy $exit = 0;
2500a920b5bSAndy Whitcroft
2515b57980dSJoe Perchesmy $perl_version_ok = 1;
252d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
2535b57980dSJoe Perches	$perl_version_ok = 0;
254d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
2555b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
256d62a201fSDave Hansen}
257d62a201fSDave Hansen
25845107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2590a920b5bSAndy Whitcroftif ($#ARGV < 0) {
26045107ff6SAllen Hubbe	push(@ARGV, '-');
2610a920b5bSAndy Whitcroft}
2620a920b5bSAndy Whitcroft
263737c0767SJohn Brooksif ($color =~ /^[01]$/) {
264737c0767SJohn Brooks	$color = !$color;
265737c0767SJohn Brooks} elsif ($color =~ /^always$/i) {
266737c0767SJohn Brooks	$color = 1;
267737c0767SJohn Brooks} elsif ($color =~ /^never$/i) {
268737c0767SJohn Brooks	$color = 0;
269737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) {
270737c0767SJohn Brooks	$color = (-t STDOUT);
271737c0767SJohn Brooks} else {
272737c0767SJohn Brooks	die "Invalid color mode: $color\n";
273737c0767SJohn Brooks}
274737c0767SJohn Brooks
275713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
276713a09deSAntonio Borneodie "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
277713a09deSAntonio Borneo
27891bfe484SJoe Perchessub hash_save_array_words {
27991bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
28091bfe484SJoe Perches
28191bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
28291bfe484SJoe Perches	foreach my $word (@array) {
283000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
284000d1cc1SJoe Perches		$word =~ s/^\s*//g;
285000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
286000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
287000d1cc1SJoe Perches
288000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
289000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
290000d1cc1SJoe Perches
29191bfe484SJoe Perches		$hashRef->{$word}++;
292000d1cc1SJoe Perches	}
29391bfe484SJoe Perches}
29491bfe484SJoe Perches
29591bfe484SJoe Perchessub hash_show_words {
29691bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
29791bfe484SJoe Perches
2983c816e49SJoe Perches	if (keys %$hashRef) {
299d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
30058cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
30191bfe484SJoe Perches			print " $word";
30291bfe484SJoe Perches		}
303d8469f16SJoe Perches		print "\n";
30491bfe484SJoe Perches	}
30591bfe484SJoe Perches}
30691bfe484SJoe Perches
30791bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
30891bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
309000d1cc1SJoe Perches
310c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
311c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
3127429c690SAndy Whitcroftmy $dbg_type = 0;
313a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
314c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
31521caa13cSAndy Whitcroft	## no critic
31621caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
31721caa13cSAndy Whitcroft	die "$@" if ($@);
318c2fdda0dSAndy Whitcroft}
319c2fdda0dSAndy Whitcroft
320d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
321d2c0a235SAndy Whitcroft
3228905a67cSAndy Whitcroftif ($terse) {
3238905a67cSAndy Whitcroft	$emacs = 1;
3248905a67cSAndy Whitcroft	$quiet++;
3258905a67cSAndy Whitcroft}
3268905a67cSAndy Whitcroft
3276c72ffaaSAndy Whitcroftif ($tree) {
3286c72ffaaSAndy Whitcroft	if (defined $root) {
3296c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
3306c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
3316c72ffaaSAndy Whitcroft		}
3326c72ffaaSAndy Whitcroft	} else {
3336c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
3346c72ffaaSAndy Whitcroft			$root = '.';
3356c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
3366c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3376c72ffaaSAndy Whitcroft			$root = $1;
3386c72ffaaSAndy Whitcroft		}
3396c72ffaaSAndy Whitcroft	}
3406c72ffaaSAndy Whitcroft
3416c72ffaaSAndy Whitcroft	if (!defined $root) {
3420a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3430a920b5bSAndy Whitcroft		exit(2);
3440a920b5bSAndy Whitcroft	}
3456c72ffaaSAndy Whitcroft}
3466c72ffaaSAndy Whitcroft
3476c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3486c72ffaaSAndy Whitcroft
3492ceb532bSAndy Whitcroftour $Ident	= qr{
3502ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3512ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3522ceb532bSAndy Whitcroft		}x;
3536c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3546c72ffaaSAndy Whitcroftour $Sparse	= qr{
3556c72ffaaSAndy Whitcroft			__user|
3566c72ffaaSAndy Whitcroft			__kernel|
3576c72ffaaSAndy Whitcroft			__force|
3586c72ffaaSAndy Whitcroft			__iomem|
3596c72ffaaSAndy Whitcroft			__must_check|
360417495edSAndy Whitcroft			__kprobes|
361165e72a6SSven Eckelmann			__ref|
36233aa4597SGeert Uytterhoeven			__refconst|
36333aa4597SGeert Uytterhoeven			__refdata|
364ad315455SBoqun Feng			__rcu|
365ad315455SBoqun Feng			__private
3666c72ffaaSAndy Whitcroft		}x;
367e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
368e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
369e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
370e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
371e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3728716de38SJoe Perches
37352131292SWolfram Sang# Notes to $Attribute:
37452131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3756c72ffaaSAndy Whitcroftour $Attribute	= qr{
3766c72ffaaSAndy Whitcroft			const|
37703f1df7dSJoe Perches			__percpu|
37803f1df7dSJoe Perches			__nocast|
37903f1df7dSJoe Perches			__safe|
38046d832f5SMichael S. Tsirkin			__bitwise|
38103f1df7dSJoe Perches			__packed__|
38203f1df7dSJoe Perches			__packed2__|
38303f1df7dSJoe Perches			__naked|
38403f1df7dSJoe Perches			__maybe_unused|
38503f1df7dSJoe Perches			__always_unused|
38603f1df7dSJoe Perches			__noreturn|
38703f1df7dSJoe Perches			__used|
38803f1df7dSJoe Perches			__cold|
389e23ef1f3SJoe Perches			__pure|
39003f1df7dSJoe Perches			__noclone|
39103f1df7dSJoe Perches			__deprecated|
3926c72ffaaSAndy Whitcroft			__read_mostly|
393c5967e98SJoe Perches			__ro_after_init|
3946c72ffaaSAndy Whitcroft			__kprobes|
3958716de38SJoe Perches			$InitAttribute|
39624e1d81aSAndy Whitcroft			____cacheline_aligned|
39724e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3985fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3995fe3af11SAndy Whitcroft			__weak
4006c72ffaaSAndy Whitcroft		  }x;
401c45dcabdSAndy Whitcroftour $Modifier;
40291cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
4036c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
4046c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
4056c72ffaaSAndy Whitcroft
40695e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
40795e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
40895e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
40995e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
4102435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
411c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
412326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
413326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
414326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
41574349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
4162435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
417326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
418447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
41923f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
4206c72ffaaSAndy Whitcroftour $Operators	= qr{
4216c72ffaaSAndy Whitcroft			<=|>=|==|!=|
4226c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
42323f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
4246c72ffaaSAndy Whitcroft		  }x;
4256c72ffaaSAndy Whitcroft
42691cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
42791cb5195SJoe Perches
428ab7e23f3SJoe Perchesour $BasicType;
4298905a67cSAndy Whitcroftour $NonptrType;
4301813087dSJoe Perchesour $NonptrTypeMisordered;
4318716de38SJoe Perchesour $NonptrTypeWithAttr;
4328905a67cSAndy Whitcroftour $Type;
4331813087dSJoe Perchesour $TypeMisordered;
4348905a67cSAndy Whitcroftour $Declare;
4351813087dSJoe Perchesour $DeclareMisordered;
4368905a67cSAndy Whitcroft
43715662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
43815662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
439171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
440171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
441171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
442171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
443171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
444171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
445171ae1a4SAndy Whitcroft}x;
446171ae1a4SAndy Whitcroft
44715662b3eSJoe Perchesour $UTF8	= qr{
44815662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
44915662b3eSJoe Perches	| $NON_ASCII_UTF8
45015662b3eSJoe Perches}x;
45115662b3eSJoe Perches
452e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
453021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
454021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
455021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
456021158b4SJoe Perches)};
457e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
458fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4598ed22cadSAndy Whitcroft	atomic_t
4608ed22cadSAndy Whitcroft)};
461e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
462e6176fa4SJoe Perches	$typeC99Typedefs\b|
463e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
464e6176fa4SJoe Perches	$typeKernelTypedefs\b
465e6176fa4SJoe Perches)};
4668ed22cadSAndy Whitcroft
4676d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4686d32f7a3SJoe Perches
469691e669bSJoe Perchesour $logFunctions = qr{(?x:
470758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4717d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
47287bd499aSJoe Perches	TP_printk|
4736e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
474b0531722SJoe Perches	panic|
47506668727SJoe Perches	MODULE_[A-Z_]+|
47606668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
477691e669bSJoe Perches)};
478691e669bSJoe Perches
479e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
480e29a70f1SJoe Perches	(?:(?:devm_)?
481e29a70f1SJoe Perches		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
482e29a70f1SJoe Perches		kstrdup(?:_const)? |
483e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
484461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
485e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
486e29a70f1SJoe Perches	dma_alloc_coherent
487e29a70f1SJoe Perches)};
488e29a70f1SJoe Perches
48920112475SJoe Perchesour $signature_tags = qr{(?xi:
49020112475SJoe Perches	Signed-off-by:|
491d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
49220112475SJoe Perches	Acked-by:|
49320112475SJoe Perches	Tested-by:|
49420112475SJoe Perches	Reviewed-by:|
49520112475SJoe Perches	Reported-by:|
4968543ae12SMugunthan V N	Suggested-by:|
49720112475SJoe Perches	To:|
49820112475SJoe Perches	Cc:
49920112475SJoe Perches)};
50020112475SJoe Perches
5011813087dSJoe Perchesour @typeListMisordered = (
5021813087dSJoe Perches	qr{char\s+(?:un)?signed},
5031813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
5041813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
5051813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
5061813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
5071813087dSJoe Perches	qr{short\s+(?:un)?signed},
5081813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
5091813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
5101813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
5111813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
5121813087dSJoe Perches	qr{int\s+(?:un)?signed},
5131813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
5141813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
5151813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
5161813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
5171813087dSJoe Perches	qr{long\s+(?:un)?signed},
5181813087dSJoe Perches);
5191813087dSJoe Perches
5208905a67cSAndy Whitcroftour @typeList = (
5218905a67cSAndy Whitcroft	qr{void},
5220c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
5230c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
5240c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
5250c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
5260c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
5270c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
5280c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
5290c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
5300c773d9dSJoe Perches	qr{(?:un)?signed},
5318905a67cSAndy Whitcroft	qr{float},
5328905a67cSAndy Whitcroft	qr{double},
5338905a67cSAndy Whitcroft	qr{bool},
5348905a67cSAndy Whitcroft	qr{struct\s+$Ident},
5358905a67cSAndy Whitcroft	qr{union\s+$Ident},
5368905a67cSAndy Whitcroft	qr{enum\s+$Ident},
5378905a67cSAndy Whitcroft	qr{${Ident}_t},
5388905a67cSAndy Whitcroft	qr{${Ident}_handler},
5398905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
5401813087dSJoe Perches	@typeListMisordered,
5418905a67cSAndy Whitcroft);
542938224b5SJoe Perches
543938224b5SJoe Perchesour $C90_int_types = qr{(?x:
544938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
545938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
546938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
547938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
548938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
549938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
550938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
551938224b5SJoe Perches
552938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
553938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
554938224b5SJoe Perches	long\s+(?:un)?signed|
555938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
556938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
557938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
558938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
559938224b5SJoe Perches
560938224b5SJoe Perches	int\s+(?:un)?signed|
561938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
562938224b5SJoe Perches)};
563938224b5SJoe Perches
564485ff23eSAlex Dowadour @typeListFile = ();
5658716de38SJoe Perchesour @typeListWithAttr = (
5668716de38SJoe Perches	@typeList,
5678716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5688716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5698716de38SJoe Perches);
5708716de38SJoe Perches
571c45dcabdSAndy Whitcroftour @modifierList = (
572c45dcabdSAndy Whitcroft	qr{fastcall},
573c45dcabdSAndy Whitcroft);
574485ff23eSAlex Dowadour @modifierListFile = ();
5758905a67cSAndy Whitcroft
5762435880fSJoe Perchesour @mode_permission_funcs = (
5772435880fSJoe Perches	["module_param", 3],
5782435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5792435880fSJoe Perches	["module_param_array_named", 5],
5802435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5812435880fSJoe Perches	["proc_create(?:_data|)", 2],
582459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
583459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
584459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
585459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
586459cf0aeSJoe Perches	["__ATTR", 2],
5872435880fSJoe Perches);
5882435880fSJoe Perches
589515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
590515a235eSJoe Perchesour $mode_perms_search = "";
591515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
592515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
593515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
594515a235eSJoe Perches}
59500180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
596515a235eSJoe Perches
5979189c7e7SJoe Perchesour %deprecated_apis = (
5989189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
5999189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
6009189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
6019189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
6029189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
6039189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
6049189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
6059189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
6069189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
6079189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
6089189c7e7SJoe Perches);
6099189c7e7SJoe Perches
6109189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
6119189c7e7SJoe Perchesour $deprecated_apis_search = "";
6129189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
6139189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
6149189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
6159189c7e7SJoe Perches}
6169189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
6179189c7e7SJoe Perches
618b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
619b392c64fSJoe Perches	S_IWUGO		|
620b392c64fSJoe Perches	S_IWOTH		|
621b392c64fSJoe Perches	S_IRWXUGO	|
622b392c64fSJoe Perches	S_IALLUGO	|
623b392c64fSJoe Perches	0[0-7][0-7][2367]
624b392c64fSJoe Perches}x;
625b392c64fSJoe Perches
626f90774e1SJoe Perchesour %mode_permission_string_types = (
627f90774e1SJoe Perches	"S_IRWXU" => 0700,
628f90774e1SJoe Perches	"S_IRUSR" => 0400,
629f90774e1SJoe Perches	"S_IWUSR" => 0200,
630f90774e1SJoe Perches	"S_IXUSR" => 0100,
631f90774e1SJoe Perches	"S_IRWXG" => 0070,
632f90774e1SJoe Perches	"S_IRGRP" => 0040,
633f90774e1SJoe Perches	"S_IWGRP" => 0020,
634f90774e1SJoe Perches	"S_IXGRP" => 0010,
635f90774e1SJoe Perches	"S_IRWXO" => 0007,
636f90774e1SJoe Perches	"S_IROTH" => 0004,
637f90774e1SJoe Perches	"S_IWOTH" => 0002,
638f90774e1SJoe Perches	"S_IXOTH" => 0001,
639f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
640f90774e1SJoe Perches	"S_IRUGO" => 0444,
641f90774e1SJoe Perches	"S_IWUGO" => 0222,
642f90774e1SJoe Perches	"S_IXUGO" => 0111,
643f90774e1SJoe Perches);
644f90774e1SJoe Perches
645f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
646f90774e1SJoe Perchesour $mode_perms_string_search = "";
647f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
648f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
649f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
650f90774e1SJoe Perches}
65100180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
65200180468SJoe Perchesour $multi_mode_perms_string_search = qr{
65300180468SJoe Perches	${single_mode_perms_string_search}
65400180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
65500180468SJoe Perches}x;
65600180468SJoe Perches
65700180468SJoe Perchessub perms_to_octal {
65800180468SJoe Perches	my ($string) = @_;
65900180468SJoe Perches
66000180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
66100180468SJoe Perches
66200180468SJoe Perches	my $val = "";
66300180468SJoe Perches	my $oval = "";
66400180468SJoe Perches	my $to = 0;
66500180468SJoe Perches	my $curpos = 0;
66600180468SJoe Perches	my $lastpos = 0;
66700180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
66800180468SJoe Perches		$curpos = pos($string);
66900180468SJoe Perches		my $match = $2;
67000180468SJoe Perches		my $omatch = $1;
67100180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
67200180468SJoe Perches		$lastpos = $curpos;
67300180468SJoe Perches		$to |= $mode_permission_string_types{$match};
67400180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
67500180468SJoe Perches		$val .= $match;
67600180468SJoe Perches		$oval .= $omatch;
67700180468SJoe Perches	}
67800180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
67900180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
68000180468SJoe Perches	return sprintf("%04o", $to);
68100180468SJoe Perches}
682f90774e1SJoe Perches
6837840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
6847840a94cSWolfram Sang	irq|
685cdcee686SSergey Ryazanov	memory|
686cdcee686SSergey Ryazanov	time|
687cdcee686SSergey Ryazanov	reboot
6887840a94cSWolfram Sang)};
6897840a94cSWolfram Sang# memory.h: ARM has a custom one
6907840a94cSWolfram Sang
69166b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
69266b47b4aSKees Cookmy $misspellings;
69366b47b4aSKees Cookmy %spelling_fix;
69436061e38SJoe Perches
69536061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
69666b47b4aSKees Cook	while (<$spelling>) {
69766b47b4aSKees Cook		my $line = $_;
69866b47b4aSKees Cook
69966b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
70066b47b4aSKees Cook		$line =~ s/^\s*//g;
70166b47b4aSKees Cook
70266b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
70366b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
70466b47b4aSKees Cook
70566b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
70666b47b4aSKees Cook
70766b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
70866b47b4aSKees Cook	}
70966b47b4aSKees Cook	close($spelling);
71036061e38SJoe Perches} else {
71136061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
71236061e38SJoe Perches}
71366b47b4aSKees Cook
714ebfd7d62SJoe Perchesif ($codespell) {
715ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
716ebfd7d62SJoe Perches		while (<$spelling>) {
717ebfd7d62SJoe Perches			my $line = $_;
718ebfd7d62SJoe Perches
719ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
720ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
721ebfd7d62SJoe Perches
722ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
723ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
724ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
725ebfd7d62SJoe Perches
726ebfd7d62SJoe Perches			$line =~ s/,.*$//;
727ebfd7d62SJoe Perches
728ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
729ebfd7d62SJoe Perches
730ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
731ebfd7d62SJoe Perches		}
732ebfd7d62SJoe Perches		close($spelling);
733ebfd7d62SJoe Perches	} else {
734ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
735ebfd7d62SJoe Perches	}
736ebfd7d62SJoe Perches}
737ebfd7d62SJoe Perches
738ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
739ebfd7d62SJoe Perches
74075ad8c57SJerome Forissiersub read_words {
74175ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
74275ad8c57SJerome Forissier
74375ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
74475ad8c57SJerome Forissier		while (<$words>) {
745bf1fa1daSJoe Perches			my $line = $_;
746bf1fa1daSJoe Perches
747bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
748bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
749bf1fa1daSJoe Perches
750bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
751bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
752bf1fa1daSJoe Perches			if ($line =~ /\s/) {
75375ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
754bf1fa1daSJoe Perches				next;
755bf1fa1daSJoe Perches			}
756bf1fa1daSJoe Perches
75775ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
75875ad8c57SJerome Forissier			$$wordsRef .= $line;
759bf1fa1daSJoe Perches		}
76075ad8c57SJerome Forissier		close($file);
76175ad8c57SJerome Forissier		return 1;
762bf1fa1daSJoe Perches	}
763bf1fa1daSJoe Perches
76475ad8c57SJerome Forissier	return 0;
76575ad8c57SJerome Forissier}
76675ad8c57SJerome Forissier
76775ad8c57SJerome Forissiermy $const_structs = "";
76875ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
76975ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
77075ad8c57SJerome Forissier
77175ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
77275ad8c57SJerome Forissierif (length($typedefsfile)) {
77375ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
77475ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
77575ad8c57SJerome Forissier}
77675ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
77775ad8c57SJerome Forissier
7788905a67cSAndy Whitcroftsub build_types {
779485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
780485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
7811813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
7828716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
783c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
784ab7e23f3SJoe Perches	$BasicType	= qr{
785ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
786ab7e23f3SJoe Perches				(?:${all}\b)
787ab7e23f3SJoe Perches		}x;
7888905a67cSAndy Whitcroft	$NonptrType	= qr{
789d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
790cf655043SAndy Whitcroft			(?:
7916b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
7928ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
793c45dcabdSAndy Whitcroft				(?:${all}\b)
794cf655043SAndy Whitcroft			)
795c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
7968905a67cSAndy Whitcroft		  }x;
7971813087dSJoe Perches	$NonptrTypeMisordered	= qr{
7981813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
7991813087dSJoe Perches			(?:
8001813087dSJoe Perches				(?:${Misordered}\b)
8011813087dSJoe Perches			)
8021813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
8031813087dSJoe Perches		  }x;
8048716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
8058716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
8068716de38SJoe Perches			(?:
8078716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
8088716de38SJoe Perches				(?:$typeTypedefs\b)|
8098716de38SJoe Perches				(?:${allWithAttr}\b)
8108716de38SJoe Perches			)
8118716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
8128716de38SJoe Perches		  }x;
8138905a67cSAndy Whitcroft	$Type	= qr{
814c45dcabdSAndy Whitcroft			$NonptrType
8157b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
816c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
8178905a67cSAndy Whitcroft		  }x;
8181813087dSJoe Perches	$TypeMisordered	= qr{
8191813087dSJoe Perches			$NonptrTypeMisordered
8207b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
8211813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
8221813087dSJoe Perches		  }x;
82391cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
8241813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
8258905a67cSAndy Whitcroft}
8268905a67cSAndy Whitcroftbuild_types();
8276c72ffaaSAndy Whitcroft
8287d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
829d1fe9c09SJoe Perches
830d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
831d1fe9c09SJoe Perches# requires at least perl version v5.10.0
832d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
833d1fe9c09SJoe Perches
834d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
8352435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
836c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
8377d2367afSJoe Perches
838f8422308SJoe Perchesour $declaration_macros = qr{(?x:
8393e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
840fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
8413d102fc0SGilad Ben-Yossef	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
8423d102fc0SGilad Ben-Yossef	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
843f8422308SJoe Perches)};
844f8422308SJoe Perches
8457d2367afSJoe Perchessub deparenthesize {
8467d2367afSJoe Perches	my ($string) = @_;
8477d2367afSJoe Perches	return "" if (!defined($string));
8485b9553abSJoe Perches
8495b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
8505b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
8515b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
8525b9553abSJoe Perches	}
8535b9553abSJoe Perches
8547d2367afSJoe Perches	$string =~ s@\s+@ @g;
8555b9553abSJoe Perches
8567d2367afSJoe Perches	return $string;
8577d2367afSJoe Perches}
8587d2367afSJoe Perches
8593445686aSJoe Perchessub seed_camelcase_file {
8603445686aSJoe Perches	my ($file) = @_;
8613445686aSJoe Perches
8623445686aSJoe Perches	return if (!(-f $file));
8633445686aSJoe Perches
8643445686aSJoe Perches	local $/;
8653445686aSJoe Perches
8663445686aSJoe Perches	open(my $include_file, '<', "$file")
8673445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
8683445686aSJoe Perches	my $text = <$include_file>;
8693445686aSJoe Perches	close($include_file);
8703445686aSJoe Perches
8713445686aSJoe Perches	my @lines = split('\n', $text);
8723445686aSJoe Perches
8733445686aSJoe Perches	foreach my $line (@lines) {
8743445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
8753445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
8763445686aSJoe Perches			$camelcase{$1} = 1;
87711ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
87811ea516aSJoe Perches			$camelcase{$1} = 1;
87911ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
8803445686aSJoe Perches			$camelcase{$1} = 1;
8813445686aSJoe Perches		}
8823445686aSJoe Perches	}
8833445686aSJoe Perches}
8843445686aSJoe Perches
885cd28b119SJoe Perchesour %maintained_status = ();
886cd28b119SJoe Perches
88785b0ee18SJoe Perchessub is_maintained_obsolete {
88885b0ee18SJoe Perches	my ($filename) = @_;
88985b0ee18SJoe Perches
890f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
89185b0ee18SJoe Perches
892cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
893cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
894cd28b119SJoe Perches	}
89585b0ee18SJoe Perches
896cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
89785b0ee18SJoe Perches}
89885b0ee18SJoe Perches
8993b6e8ac9SJoe Perchessub is_SPDX_License_valid {
9003b6e8ac9SJoe Perches	my ($license) = @_;
9013b6e8ac9SJoe Perches
90256294112SJoe Perches	return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
9033b6e8ac9SJoe Perches
90456294112SJoe Perches	my $root_path = abs_path($root);
90556294112SJoe Perches	my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
9063b6e8ac9SJoe Perches	return 0 if ($status ne "");
9073b6e8ac9SJoe Perches	return 1;
9083b6e8ac9SJoe Perches}
9093b6e8ac9SJoe Perches
9103445686aSJoe Perchesmy $camelcase_seeded = 0;
9113445686aSJoe Perchessub seed_camelcase_includes {
9123445686aSJoe Perches	return if ($camelcase_seeded);
9133445686aSJoe Perches
9143445686aSJoe Perches	my $files;
915c707a81dSJoe Perches	my $camelcase_cache = "";
916c707a81dSJoe Perches	my @include_files = ();
917c707a81dSJoe Perches
918c707a81dSJoe Perches	$camelcase_seeded = 1;
919351b2a1fSJoe Perches
9203645e328SRichard Genoud	if (-e ".git") {
921dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
922351b2a1fSJoe Perches		chomp $git_last_include_commit;
923c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
924c707a81dSJoe Perches	} else {
925c707a81dSJoe Perches		my $last_mod_date = 0;
926c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
927c707a81dSJoe Perches		@include_files = split('\n', $files);
928c707a81dSJoe Perches		foreach my $file (@include_files) {
929c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
930c707a81dSJoe Perches						   localtime((stat $file)[9]));
931c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
932c707a81dSJoe Perches		}
933c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
934c707a81dSJoe Perches	}
935c707a81dSJoe Perches
936c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
937c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
938c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
939351b2a1fSJoe Perches		while (<$camelcase_file>) {
940351b2a1fSJoe Perches			chomp;
941351b2a1fSJoe Perches			$camelcase{$_} = 1;
942351b2a1fSJoe Perches		}
943351b2a1fSJoe Perches		close($camelcase_file);
944351b2a1fSJoe Perches
945351b2a1fSJoe Perches		return;
946351b2a1fSJoe Perches	}
947c707a81dSJoe Perches
9483645e328SRichard Genoud	if (-e ".git") {
949dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
950c707a81dSJoe Perches		@include_files = split('\n', $files);
9513445686aSJoe Perches	}
952c707a81dSJoe Perches
9533445686aSJoe Perches	foreach my $file (@include_files) {
9543445686aSJoe Perches		seed_camelcase_file($file);
9553445686aSJoe Perches	}
956351b2a1fSJoe Perches
957c707a81dSJoe Perches	if ($camelcase_cache ne "") {
958351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
959c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
960c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
961351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
962351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
963351b2a1fSJoe Perches		}
964351b2a1fSJoe Perches		close($camelcase_file);
965351b2a1fSJoe Perches	}
9663445686aSJoe Perches}
9673445686aSJoe Perches
968d311cd44SJoe Perchessub git_commit_info {
969d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
970d311cd44SJoe Perches
971d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
972d311cd44SJoe Perches
973dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
974d311cd44SJoe Perches	$output =~ s/^\s*//gm;
975d311cd44SJoe Perches	my @lines = split("\n", $output);
976d311cd44SJoe Perches
9770d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
9780d7835fcSJoe Perches
9795a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
980d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
981d311cd44SJoe Perches# all matching commit ids, but it's very slow...
982d311cd44SJoe Perches#
983d311cd44SJoe Perches#		echo "checking commits $1..."
984d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
985d311cd44SJoe Perches#		while read line ; do
986d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
987d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
988d311cd44SJoe Perches#		done
989d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
990948b133aSHeinrich Schuchardt		$id = undef;
991d311cd44SJoe Perches	} else {
992d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
993d311cd44SJoe Perches		$desc = substr($lines[0], 41);
994d311cd44SJoe Perches	}
995d311cd44SJoe Perches
996d311cd44SJoe Perches	return ($id, $desc);
997d311cd44SJoe Perches}
998d311cd44SJoe Perches
9996c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
10000a920b5bSAndy Whitcroft
100100df344fSAndy Whitcroftmy @rawlines = ();
1002c2fdda0dSAndy Whitcroftmy @lines = ();
10033705ce5bSJoe Perchesmy @fixed = ();
1004d752fcc8SJoe Perchesmy @fixed_inserted = ();
1005d752fcc8SJoe Perchesmy @fixed_deleted = ();
1006194f66fcSJoe Perchesmy $fixlinenr = -1;
1007194f66fcSJoe Perches
10084a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
10094a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
10104a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
10114a593c34SDu, Changbin
10124a593c34SDu, Changbinif ($git) {
10134a593c34SDu, Changbin	my @commits = ();
10140dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
10154a593c34SDu, Changbin		my $git_range;
101628898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
101728898fd1SJoe Perches			$git_range = "-$2 $1";
10184a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
10194a593c34SDu, Changbin			$git_range = "$commit_expr";
10204a593c34SDu, Changbin		} else {
10210dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
10220dea9f1eSJoe Perches		}
1023dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
10240dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
102528898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
102628898fd1SJoe Perches			next if (!defined($1) || !defined($2));
10270dea9f1eSJoe Perches			my $sha1 = $1;
10280dea9f1eSJoe Perches			my $subject = $2;
10290dea9f1eSJoe Perches			unshift(@commits, $sha1);
10300dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
10314a593c34SDu, Changbin		}
10324a593c34SDu, Changbin	}
10334a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
10344a593c34SDu, Changbin	@ARGV = @commits;
10354a593c34SDu, Changbin}
10364a593c34SDu, Changbin
1037c2fdda0dSAndy Whitcroftmy $vname;
103898005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
10396c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
104021caa13cSAndy Whitcroft	my $FILE;
10414a593c34SDu, Changbin	if ($git) {
10424a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
10434a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
10444a593c34SDu, Changbin	} elsif ($file) {
104521caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
10466c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
104721caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
104821caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
10496c72ffaaSAndy Whitcroft	} else {
105021caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
10516c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
10526c72ffaaSAndy Whitcroft	}
1053c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1054c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
10554a593c34SDu, Changbin	} elsif ($git) {
10560dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1057c2fdda0dSAndy Whitcroft	} else {
1058c2fdda0dSAndy Whitcroft		$vname = $filename;
1059c2fdda0dSAndy Whitcroft	}
106021caa13cSAndy Whitcroft	while (<$FILE>) {
10610a920b5bSAndy Whitcroft		chomp;
106200df344fSAndy Whitcroft		push(@rawlines, $_);
10636c72ffaaSAndy Whitcroft	}
106421caa13cSAndy Whitcroft	close($FILE);
1065d8469f16SJoe Perches
1066d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1067d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1068d8469f16SJoe Perches		print "$vname\n";
1069d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1070d8469f16SJoe Perches	}
1071d8469f16SJoe Perches
1072c2fdda0dSAndy Whitcroft	if (!process($filename)) {
10730a920b5bSAndy Whitcroft		$exit = 1;
10740a920b5bSAndy Whitcroft	}
107500df344fSAndy Whitcroft	@rawlines = ();
107613214adfSAndy Whitcroft	@lines = ();
10773705ce5bSJoe Perches	@fixed = ();
1078d752fcc8SJoe Perches	@fixed_inserted = ();
1079d752fcc8SJoe Perches	@fixed_deleted = ();
1080194f66fcSJoe Perches	$fixlinenr = -1;
1081485ff23eSAlex Dowad	@modifierListFile = ();
1082485ff23eSAlex Dowad	@typeListFile = ();
1083485ff23eSAlex Dowad	build_types();
10840a920b5bSAndy Whitcroft}
10850a920b5bSAndy Whitcroft
1086d8469f16SJoe Perchesif (!$quiet) {
10873c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
10883c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
10893c816e49SJoe Perches
10905b57980dSJoe Perches	if (!$perl_version_ok) {
1091d8469f16SJoe Perches		print << "EOM"
1092d8469f16SJoe Perches
1093d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
10945b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1095d8469f16SJoe PerchesEOM
1096d8469f16SJoe Perches	}
1097d8469f16SJoe Perches	if ($exit) {
1098d8469f16SJoe Perches		print << "EOM"
1099d8469f16SJoe Perches
1100d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1101d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1102d8469f16SJoe PerchesEOM
1103d8469f16SJoe Perches	}
1104d8469f16SJoe Perches}
1105d8469f16SJoe Perches
11060a920b5bSAndy Whitcroftexit($exit);
11070a920b5bSAndy Whitcroft
11080a920b5bSAndy Whitcroftsub top_of_kernel_tree {
11096c72ffaaSAndy Whitcroft	my ($root) = @_;
11106c72ffaaSAndy Whitcroft
11116c72ffaaSAndy Whitcroft	my @tree_check = (
11126c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
11136c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
11146c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
11156c72ffaaSAndy Whitcroft	);
11166c72ffaaSAndy Whitcroft
11176c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
11186c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
11190a920b5bSAndy Whitcroft			return 0;
11200a920b5bSAndy Whitcroft		}
11216c72ffaaSAndy Whitcroft	}
11226c72ffaaSAndy Whitcroft	return 1;
11236c72ffaaSAndy Whitcroft}
11240a920b5bSAndy Whitcroft
112520112475SJoe Perchessub parse_email {
112620112475SJoe Perches	my ($formatted_email) = @_;
112720112475SJoe Perches
112820112475SJoe Perches	my $name = "";
1129dfa05c28SJoe Perches	my $name_comment = "";
113020112475SJoe Perches	my $address = "";
113120112475SJoe Perches	my $comment = "";
113220112475SJoe Perches
113320112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
113420112475SJoe Perches		$name = $1;
113520112475SJoe Perches		$address = $2;
113620112475SJoe Perches		$comment = $3 if defined $3;
113720112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
113820112475SJoe Perches		$address = $1;
113920112475SJoe Perches		$comment = $2 if defined $2;
114020112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
114120112475SJoe Perches		$address = $1;
114220112475SJoe Perches		$comment = $2 if defined $2;
114385e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
114420112475SJoe Perches		$name = $formatted_email;
11453705ce5bSJoe Perches		$name = trim($name);
114620112475SJoe Perches		$name =~ s/^\"|\"$//g;
114720112475SJoe Perches		# If there's a name left after stripping spaces and
114820112475SJoe Perches		# leading quotes, and the address doesn't have both
114920112475SJoe Perches		# leading and trailing angle brackets, the address
115020112475SJoe Perches		# is invalid. ie:
115120112475SJoe Perches		#   "joe smith [email protected]" bad
115220112475SJoe Perches		#   "joe smith <[email protected]" bad
115320112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
115420112475SJoe Perches			$name = "";
115520112475SJoe Perches			$address = "";
115620112475SJoe Perches			$comment = "";
115720112475SJoe Perches		}
115820112475SJoe Perches	}
115920112475SJoe Perches
11603705ce5bSJoe Perches	$name = trim($name);
116120112475SJoe Perches	$name =~ s/^\"|\"$//g;
1162dfa05c28SJoe Perches	$name =~ s/(\s*\([^\)]+\))\s*//;
1163dfa05c28SJoe Perches	if (defined($1)) {
1164dfa05c28SJoe Perches		$name_comment = trim($1);
1165dfa05c28SJoe Perches	}
11663705ce5bSJoe Perches	$address = trim($address);
116720112475SJoe Perches	$address =~ s/^\<|\>$//g;
116820112475SJoe Perches
116920112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
117020112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
117120112475SJoe Perches		$name = "\"$name\"";
117220112475SJoe Perches	}
117320112475SJoe Perches
1174dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
117520112475SJoe Perches}
117620112475SJoe Perches
117720112475SJoe Perchessub format_email {
117820112475SJoe Perches	my ($name, $address) = @_;
117920112475SJoe Perches
118020112475SJoe Perches	my $formatted_email;
118120112475SJoe Perches
11823705ce5bSJoe Perches	$name = trim($name);
118320112475SJoe Perches	$name =~ s/^\"|\"$//g;
11843705ce5bSJoe Perches	$address = trim($address);
118520112475SJoe Perches
118620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
118720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
118820112475SJoe Perches		$name = "\"$name\"";
118920112475SJoe Perches	}
119020112475SJoe Perches
119120112475SJoe Perches	if ("$name" eq "") {
119220112475SJoe Perches		$formatted_email = "$address";
119320112475SJoe Perches	} else {
119420112475SJoe Perches		$formatted_email = "$name <$address>";
119520112475SJoe Perches	}
119620112475SJoe Perches
119720112475SJoe Perches	return $formatted_email;
119820112475SJoe Perches}
119920112475SJoe Perches
1200dfa05c28SJoe Perchessub reformat_email {
1201dfa05c28SJoe Perches	my ($email) = @_;
1202dfa05c28SJoe Perches
1203dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
1204dfa05c28SJoe Perches	return format_email($email_name, $email_address);
1205dfa05c28SJoe Perches}
1206dfa05c28SJoe Perches
1207dfa05c28SJoe Perchessub same_email_addresses {
1208dfa05c28SJoe Perches	my ($email1, $email2) = @_;
1209dfa05c28SJoe Perches
1210dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1211dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1212dfa05c28SJoe Perches
1213dfa05c28SJoe Perches	return $email1_name eq $email2_name &&
1214dfa05c28SJoe Perches	       $email1_address eq $email2_address;
1215dfa05c28SJoe Perches}
1216dfa05c28SJoe Perches
1217d311cd44SJoe Perchessub which {
1218d311cd44SJoe Perches	my ($bin) = @_;
1219d311cd44SJoe Perches
1220d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1221d311cd44SJoe Perches		if (-e "$path/$bin") {
1222d311cd44SJoe Perches			return "$path/$bin";
1223d311cd44SJoe Perches		}
1224d311cd44SJoe Perches	}
1225d311cd44SJoe Perches
1226d311cd44SJoe Perches	return "";
1227d311cd44SJoe Perches}
1228d311cd44SJoe Perches
1229000d1cc1SJoe Perchessub which_conf {
1230000d1cc1SJoe Perches	my ($conf) = @_;
1231000d1cc1SJoe Perches
1232000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1233000d1cc1SJoe Perches		if (-e "$path/$conf") {
1234000d1cc1SJoe Perches			return "$path/$conf";
1235000d1cc1SJoe Perches		}
1236000d1cc1SJoe Perches	}
1237000d1cc1SJoe Perches
1238000d1cc1SJoe Perches	return "";
1239000d1cc1SJoe Perches}
1240000d1cc1SJoe Perches
12410a920b5bSAndy Whitcroftsub expand_tabs {
12420a920b5bSAndy Whitcroft	my ($str) = @_;
12430a920b5bSAndy Whitcroft
12440a920b5bSAndy Whitcroft	my $res = '';
12450a920b5bSAndy Whitcroft	my $n = 0;
12460a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
12470a920b5bSAndy Whitcroft		if ($c eq "\t") {
12480a920b5bSAndy Whitcroft			$res .= ' ';
12490a920b5bSAndy Whitcroft			$n++;
1250713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
12510a920b5bSAndy Whitcroft				$res .= ' ';
12520a920b5bSAndy Whitcroft			}
12530a920b5bSAndy Whitcroft			next;
12540a920b5bSAndy Whitcroft		}
12550a920b5bSAndy Whitcroft		$res .= $c;
12560a920b5bSAndy Whitcroft		$n++;
12570a920b5bSAndy Whitcroft	}
12580a920b5bSAndy Whitcroft
12590a920b5bSAndy Whitcroft	return $res;
12600a920b5bSAndy Whitcroft}
12616c72ffaaSAndy Whitcroftsub copy_spacing {
1262773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
12636c72ffaaSAndy Whitcroft	return $res;
12646c72ffaaSAndy Whitcroft}
12650a920b5bSAndy Whitcroft
12664a0df2efSAndy Whitcroftsub line_stats {
12674a0df2efSAndy Whitcroft	my ($line) = @_;
12684a0df2efSAndy Whitcroft
12694a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
12704a0df2efSAndy Whitcroft	$line =~ s/^.//;
12714a0df2efSAndy Whitcroft	$line = expand_tabs($line);
12724a0df2efSAndy Whitcroft
12734a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
12744a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
12754a0df2efSAndy Whitcroft
12764a0df2efSAndy Whitcroft	return (length($line), length($white));
12774a0df2efSAndy Whitcroft}
12784a0df2efSAndy Whitcroft
1279773647a0SAndy Whitcroftmy $sanitise_quote = '';
1280773647a0SAndy Whitcroft
1281773647a0SAndy Whitcroftsub sanitise_line_reset {
1282773647a0SAndy Whitcroft	my ($in_comment) = @_;
1283773647a0SAndy Whitcroft
1284773647a0SAndy Whitcroft	if ($in_comment) {
1285773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1286773647a0SAndy Whitcroft	} else {
1287773647a0SAndy Whitcroft		$sanitise_quote = '';
1288773647a0SAndy Whitcroft	}
1289773647a0SAndy Whitcroft}
129000df344fSAndy Whitcroftsub sanitise_line {
129100df344fSAndy Whitcroft	my ($line) = @_;
129200df344fSAndy Whitcroft
129300df344fSAndy Whitcroft	my $res = '';
129400df344fSAndy Whitcroft	my $l = '';
129500df344fSAndy Whitcroft
1296c2fdda0dSAndy Whitcroft	my $qlen = 0;
1297773647a0SAndy Whitcroft	my $off = 0;
1298773647a0SAndy Whitcroft	my $c;
129900df344fSAndy Whitcroft
1300773647a0SAndy Whitcroft	# Always copy over the diff marker.
1301773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1302773647a0SAndy Whitcroft
1303773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1304773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1305773647a0SAndy Whitcroft
13068d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1307773647a0SAndy Whitcroft		# and end, all to $;.
1308773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1309773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1310773647a0SAndy Whitcroft
1311773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1312773647a0SAndy Whitcroft			$off++;
131300df344fSAndy Whitcroft			next;
1314773647a0SAndy Whitcroft		}
131581bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1316773647a0SAndy Whitcroft			$sanitise_quote = '';
1317773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1318773647a0SAndy Whitcroft			$off++;
1319773647a0SAndy Whitcroft			next;
1320773647a0SAndy Whitcroft		}
1321113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1322113f04a8SDaniel Walker			$sanitise_quote = '//';
1323113f04a8SDaniel Walker
1324113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1325113f04a8SDaniel Walker			$off++;
1326113f04a8SDaniel Walker			next;
1327113f04a8SDaniel Walker		}
1328773647a0SAndy Whitcroft
1329773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1330773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1331773647a0SAndy Whitcroft		    $c eq "\\") {
1332773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1333773647a0SAndy Whitcroft			$off++;
1334773647a0SAndy Whitcroft			next;
1335773647a0SAndy Whitcroft		}
1336773647a0SAndy Whitcroft		# Regular quotes.
1337773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1338773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1339773647a0SAndy Whitcroft				$sanitise_quote = $c;
1340773647a0SAndy Whitcroft
1341773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1342773647a0SAndy Whitcroft				next;
1343773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1344773647a0SAndy Whitcroft				$sanitise_quote = '';
134500df344fSAndy Whitcroft			}
134600df344fSAndy Whitcroft		}
1347773647a0SAndy Whitcroft
1348fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1349773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1350773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1351113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1352113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1353773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1354773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
135500df344fSAndy Whitcroft		} else {
1356773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
135700df344fSAndy Whitcroft		}
1358c2fdda0dSAndy Whitcroft	}
1359c2fdda0dSAndy Whitcroft
1360113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1361113f04a8SDaniel Walker		$sanitise_quote = '';
1362113f04a8SDaniel Walker	}
1363113f04a8SDaniel Walker
1364c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1365c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1366c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1367c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1368c2fdda0dSAndy Whitcroft
1369c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1370c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1371c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1372c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1373c2fdda0dSAndy Whitcroft	}
1374c2fdda0dSAndy Whitcroft
1375dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1376dadf680dSJoe Perches		my $match = $1;
1377dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1378dadf680dSJoe Perches	}
1379dadf680dSJoe Perches
138000df344fSAndy Whitcroft	return $res;
138100df344fSAndy Whitcroft}
138200df344fSAndy Whitcroft
1383a6962d72SJoe Perchessub get_quoted_string {
1384a6962d72SJoe Perches	my ($line, $rawline) = @_;
1385a6962d72SJoe Perches
1386478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
138733acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1388a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1389a6962d72SJoe Perches}
1390a6962d72SJoe Perches
13918905a67cSAndy Whitcroftsub ctx_statement_block {
13928905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
13938905a67cSAndy Whitcroft	my $line = $linenr - 1;
13948905a67cSAndy Whitcroft	my $blk = '';
13958905a67cSAndy Whitcroft	my $soff = $off;
13968905a67cSAndy Whitcroft	my $coff = $off - 1;
1397773647a0SAndy Whitcroft	my $coff_set = 0;
13988905a67cSAndy Whitcroft
139913214adfSAndy Whitcroft	my $loff = 0;
140013214adfSAndy Whitcroft
14018905a67cSAndy Whitcroft	my $type = '';
14028905a67cSAndy Whitcroft	my $level = 0;
1403a2750645SAndy Whitcroft	my @stack = ();
1404cf655043SAndy Whitcroft	my $p;
14058905a67cSAndy Whitcroft	my $c;
14068905a67cSAndy Whitcroft	my $len = 0;
140713214adfSAndy Whitcroft
140813214adfSAndy Whitcroft	my $remainder;
14098905a67cSAndy Whitcroft	while (1) {
1410a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1411a2750645SAndy Whitcroft
1412773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
14138905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
14148905a67cSAndy Whitcroft		# context.
14158905a67cSAndy Whitcroft		if ($off >= $len) {
14168905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1417dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1418c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
14198905a67cSAndy Whitcroft				$remain--;
142013214adfSAndy Whitcroft				$loff = $len;
1421c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
14228905a67cSAndy Whitcroft				$len = length($blk);
14238905a67cSAndy Whitcroft				$line++;
14248905a67cSAndy Whitcroft				last;
14258905a67cSAndy Whitcroft			}
14268905a67cSAndy Whitcroft			# Bail if there is no further context.
14278905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
142813214adfSAndy Whitcroft			if ($off >= $len) {
14298905a67cSAndy Whitcroft				last;
14308905a67cSAndy Whitcroft			}
1431f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1432f74bd194SAndy Whitcroft				$level++;
1433f74bd194SAndy Whitcroft				$type = '#';
1434f74bd194SAndy Whitcroft			}
14358905a67cSAndy Whitcroft		}
1436cf655043SAndy Whitcroft		$p = $c;
14378905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
143813214adfSAndy Whitcroft		$remainder = substr($blk, $off);
14398905a67cSAndy Whitcroft
1440773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
14414635f4fbSAndy Whitcroft
14424635f4fbSAndy Whitcroft		# Handle nested #if/#else.
14434635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
14444635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
14454635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
14464635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
14474635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
14484635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
14494635f4fbSAndy Whitcroft		}
14504635f4fbSAndy Whitcroft
14518905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
14528905a67cSAndy Whitcroft		# outermost level.
14538905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
14548905a67cSAndy Whitcroft			last;
14558905a67cSAndy Whitcroft		}
14568905a67cSAndy Whitcroft
145713214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1458773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1459773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1460773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1461773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1462773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1463773647a0SAndy Whitcroft			$coff_set = 1;
1464773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1465773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
146613214adfSAndy Whitcroft		}
146713214adfSAndy Whitcroft
14688905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
14698905a67cSAndy Whitcroft			$level++;
14708905a67cSAndy Whitcroft			$type = '(';
14718905a67cSAndy Whitcroft		}
14728905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
14738905a67cSAndy Whitcroft			$level--;
14748905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
14758905a67cSAndy Whitcroft
14768905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
14778905a67cSAndy Whitcroft				$coff = $off;
1478773647a0SAndy Whitcroft				$coff_set = 1;
1479773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
14808905a67cSAndy Whitcroft			}
14818905a67cSAndy Whitcroft		}
14828905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
14838905a67cSAndy Whitcroft			$level++;
14848905a67cSAndy Whitcroft			$type = '{';
14858905a67cSAndy Whitcroft		}
14868905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
14878905a67cSAndy Whitcroft			$level--;
14888905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
14898905a67cSAndy Whitcroft
14908905a67cSAndy Whitcroft			if ($level == 0) {
1491b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1492b998e001SPatrick Pannuto					$off++;
1493b998e001SPatrick Pannuto				}
14948905a67cSAndy Whitcroft				last;
14958905a67cSAndy Whitcroft			}
14968905a67cSAndy Whitcroft		}
1497f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1498f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1499f74bd194SAndy Whitcroft			$level--;
1500f74bd194SAndy Whitcroft			$type = '';
1501f74bd194SAndy Whitcroft			$off++;
1502f74bd194SAndy Whitcroft			last;
1503f74bd194SAndy Whitcroft		}
15048905a67cSAndy Whitcroft		$off++;
15058905a67cSAndy Whitcroft	}
1506a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
150713214adfSAndy Whitcroft	if ($off == $len) {
1508a3bb97a7SAndy Whitcroft		$loff = $len + 1;
150913214adfSAndy Whitcroft		$line++;
151013214adfSAndy Whitcroft		$remain--;
151113214adfSAndy Whitcroft	}
15128905a67cSAndy Whitcroft
15138905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
15148905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
15158905a67cSAndy Whitcroft
15168905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
15178905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
15188905a67cSAndy Whitcroft
1519773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
152013214adfSAndy Whitcroft
152113214adfSAndy Whitcroft	return ($statement, $condition,
152213214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
152313214adfSAndy Whitcroft}
152413214adfSAndy Whitcroft
1525cf655043SAndy Whitcroftsub statement_lines {
1526cf655043SAndy Whitcroft	my ($stmt) = @_;
1527cf655043SAndy Whitcroft
1528cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1529cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1530cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1531cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1532cf655043SAndy Whitcroft
1533cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1534cf655043SAndy Whitcroft
1535cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1536cf655043SAndy Whitcroft}
1537cf655043SAndy Whitcroft
1538cf655043SAndy Whitcroftsub statement_rawlines {
1539cf655043SAndy Whitcroft	my ($stmt) = @_;
1540cf655043SAndy Whitcroft
1541cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1542cf655043SAndy Whitcroft
1543cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1544cf655043SAndy Whitcroft}
1545cf655043SAndy Whitcroft
1546cf655043SAndy Whitcroftsub statement_block_size {
1547cf655043SAndy Whitcroft	my ($stmt) = @_;
1548cf655043SAndy Whitcroft
1549cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1550cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1551cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1552cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1553cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1554cf655043SAndy Whitcroft
1555cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1556cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1557cf655043SAndy Whitcroft
1558cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1559cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1560cf655043SAndy Whitcroft
1561cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1562cf655043SAndy Whitcroft		return $stmt_lines;
1563cf655043SAndy Whitcroft	} else {
1564cf655043SAndy Whitcroft		return $stmt_statements;
1565cf655043SAndy Whitcroft	}
1566cf655043SAndy Whitcroft}
1567cf655043SAndy Whitcroft
156813214adfSAndy Whitcroftsub ctx_statement_full {
156913214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
157013214adfSAndy Whitcroft	my ($statement, $condition, $level);
157113214adfSAndy Whitcroft
157213214adfSAndy Whitcroft	my (@chunks);
157313214adfSAndy Whitcroft
1574cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
157513214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
157613214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1577773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
157813214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1579cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1580cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1581cf655043SAndy Whitcroft	}
1582cf655043SAndy Whitcroft
1583cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1584cf655043SAndy Whitcroft	# could continue the statement.
1585cf655043SAndy Whitcroft	for (;;) {
158613214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
158713214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1588cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1589773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1590cf655043SAndy Whitcroft		#print "C: push\n";
1591cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
159213214adfSAndy Whitcroft	}
159313214adfSAndy Whitcroft
159413214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
15958905a67cSAndy Whitcroft}
15968905a67cSAndy Whitcroft
15974a0df2efSAndy Whitcroftsub ctx_block_get {
1598f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
15994a0df2efSAndy Whitcroft	my $line;
16004a0df2efSAndy Whitcroft	my $start = $linenr - 1;
16014a0df2efSAndy Whitcroft	my $blk = '';
16024a0df2efSAndy Whitcroft	my @o;
16034a0df2efSAndy Whitcroft	my @c;
16044a0df2efSAndy Whitcroft	my @res = ();
16054a0df2efSAndy Whitcroft
1606f0a594c1SAndy Whitcroft	my $level = 0;
16074635f4fbSAndy Whitcroft	my @stack = ($level);
160800df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
160900df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
161000df344fSAndy Whitcroft		$remain--;
161100df344fSAndy Whitcroft
161200df344fSAndy Whitcroft		$blk .= $rawlines[$line];
16134635f4fbSAndy Whitcroft
16144635f4fbSAndy Whitcroft		# Handle nested #if/#else.
161501464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
16164635f4fbSAndy Whitcroft			push(@stack, $level);
161701464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
16184635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
161901464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
16204635f4fbSAndy Whitcroft			$level = pop(@stack);
16214635f4fbSAndy Whitcroft		}
16224635f4fbSAndy Whitcroft
162301464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1624f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1625f0a594c1SAndy Whitcroft			if ($off > 0) {
1626f0a594c1SAndy Whitcroft				$off--;
1627f0a594c1SAndy Whitcroft				next;
1628f0a594c1SAndy Whitcroft			}
16294a0df2efSAndy Whitcroft
1630f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1631f0a594c1SAndy Whitcroft				$level--;
1632f0a594c1SAndy Whitcroft				last if ($level == 0);
1633f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1634f0a594c1SAndy Whitcroft				$level++;
1635f0a594c1SAndy Whitcroft			}
1636f0a594c1SAndy Whitcroft		}
16374a0df2efSAndy Whitcroft
1638f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
163900df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
16404a0df2efSAndy Whitcroft		}
16414a0df2efSAndy Whitcroft
1642f0a594c1SAndy Whitcroft		last if ($level == 0);
16434a0df2efSAndy Whitcroft	}
16444a0df2efSAndy Whitcroft
1645f0a594c1SAndy Whitcroft	return ($level, @res);
16464a0df2efSAndy Whitcroft}
16474a0df2efSAndy Whitcroftsub ctx_block_outer {
16484a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16494a0df2efSAndy Whitcroft
1650f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1651f0a594c1SAndy Whitcroft	return @r;
16524a0df2efSAndy Whitcroft}
16534a0df2efSAndy Whitcroftsub ctx_block {
16544a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16554a0df2efSAndy Whitcroft
1656f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1657f0a594c1SAndy Whitcroft	return @r;
1658653d4876SAndy Whitcroft}
1659653d4876SAndy Whitcroftsub ctx_statement {
1660f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1661f0a594c1SAndy Whitcroft
1662f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1663f0a594c1SAndy Whitcroft	return @r;
1664f0a594c1SAndy Whitcroft}
1665f0a594c1SAndy Whitcroftsub ctx_block_level {
1666653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1667653d4876SAndy Whitcroft
1668f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
16694a0df2efSAndy Whitcroft}
16709c0ca6f9SAndy Whitcroftsub ctx_statement_level {
16719c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16729c0ca6f9SAndy Whitcroft
16739c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
16749c0ca6f9SAndy Whitcroft}
16754a0df2efSAndy Whitcroft
16764a0df2efSAndy Whitcroftsub ctx_locate_comment {
16774a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
16784a0df2efSAndy Whitcroft
16794a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1680beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
16814a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
16824a0df2efSAndy Whitcroft
16834a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
16844a0df2efSAndy Whitcroft	# comment.
16854a0df2efSAndy Whitcroft	my $in_comment = 0;
16864a0df2efSAndy Whitcroft	$current_comment = '';
16874a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
168800df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
168900df344fSAndy Whitcroft		#warn "           $line\n";
16904a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
16914a0df2efSAndy Whitcroft			$in_comment = 1;
16924a0df2efSAndy Whitcroft		}
16934a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
16944a0df2efSAndy Whitcroft			$in_comment = 1;
16954a0df2efSAndy Whitcroft		}
16964a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
16974a0df2efSAndy Whitcroft			$current_comment = '';
16984a0df2efSAndy Whitcroft		}
16994a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
17004a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
17014a0df2efSAndy Whitcroft			$in_comment = 0;
17024a0df2efSAndy Whitcroft		}
17034a0df2efSAndy Whitcroft	}
17044a0df2efSAndy Whitcroft
17054a0df2efSAndy Whitcroft	chomp($current_comment);
17064a0df2efSAndy Whitcroft	return($current_comment);
17074a0df2efSAndy Whitcroft}
17084a0df2efSAndy Whitcroftsub ctx_has_comment {
17094a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
17104a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
17114a0df2efSAndy Whitcroft
171200df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
17134a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
17144a0df2efSAndy Whitcroft
17154a0df2efSAndy Whitcroft	return ($cmt ne '');
17164a0df2efSAndy Whitcroft}
17174a0df2efSAndy Whitcroft
17184d001e4dSAndy Whitcroftsub raw_line {
17194d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
17204d001e4dSAndy Whitcroft
17214d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
17224d001e4dSAndy Whitcroft	$cnt++;
17234d001e4dSAndy Whitcroft
17244d001e4dSAndy Whitcroft	my $line;
17254d001e4dSAndy Whitcroft	while ($cnt) {
17264d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
17274d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
17284d001e4dSAndy Whitcroft		$cnt--;
17294d001e4dSAndy Whitcroft	}
17304d001e4dSAndy Whitcroft
17314d001e4dSAndy Whitcroft	return $line;
17324d001e4dSAndy Whitcroft}
17334d001e4dSAndy Whitcroft
17342a9f9d85STobin C. Hardingsub get_stat_real {
17352a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
17362a9f9d85STobin C. Harding
17372a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
17382a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
17392a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
17402a9f9d85STobin C. Harding	}
17412a9f9d85STobin C. Harding
17422a9f9d85STobin C. Harding	return $stat_real;
17432a9f9d85STobin C. Harding}
17442a9f9d85STobin C. Harding
1745e3d95a2aSTobin C. Hardingsub get_stat_here {
1746e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1747e3d95a2aSTobin C. Harding
1748e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1749e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1750e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1751e3d95a2aSTobin C. Harding	}
1752e3d95a2aSTobin C. Harding
1753e3d95a2aSTobin C. Harding	return $herectx;
1754e3d95a2aSTobin C. Harding}
1755e3d95a2aSTobin C. Harding
17560a920b5bSAndy Whitcroftsub cat_vet {
17570a920b5bSAndy Whitcroft	my ($vet) = @_;
17589c0ca6f9SAndy Whitcroft	my ($res, $coded);
17590a920b5bSAndy Whitcroft
17609c0ca6f9SAndy Whitcroft	$res = '';
17616c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
17626c72ffaaSAndy Whitcroft		$res .= $1;
17636c72ffaaSAndy Whitcroft		if ($2 ne '') {
17649c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
17656c72ffaaSAndy Whitcroft			$res .= $coded;
17666c72ffaaSAndy Whitcroft		}
17679c0ca6f9SAndy Whitcroft	}
17689c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
17690a920b5bSAndy Whitcroft
17709c0ca6f9SAndy Whitcroft	return $res;
17710a920b5bSAndy Whitcroft}
17720a920b5bSAndy Whitcroft
1773c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1774cf655043SAndy Whitcroftmy $av_pending;
1775c2fdda0dSAndy Whitcroftmy @av_paren_type;
17761f65f947SAndy Whitcroftmy $av_pend_colon;
1777c2fdda0dSAndy Whitcroft
1778c2fdda0dSAndy Whitcroftsub annotate_reset {
1779c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1780cf655043SAndy Whitcroft	$av_pending = '_';
1781cf655043SAndy Whitcroft	@av_paren_type = ('E');
17821f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1783c2fdda0dSAndy Whitcroft}
1784c2fdda0dSAndy Whitcroft
17856c72ffaaSAndy Whitcroftsub annotate_values {
17866c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
17876c72ffaaSAndy Whitcroft
17886c72ffaaSAndy Whitcroft	my $res;
17891f65f947SAndy Whitcroft	my $var = '_' x length($stream);
17906c72ffaaSAndy Whitcroft	my $cur = $stream;
17916c72ffaaSAndy Whitcroft
1792c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
17936c72ffaaSAndy Whitcroft
17946c72ffaaSAndy Whitcroft	while (length($cur)) {
1795773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1796cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1797171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
17986c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1799c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1800c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1801cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1802c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
18036c72ffaaSAndy Whitcroft			}
18046c72ffaaSAndy Whitcroft
1805c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
18069446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
18079446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1808addcdceaSAndy Whitcroft			$type = 'c';
18099446ef56SAndy Whitcroft
1810e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1811c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
18126c72ffaaSAndy Whitcroft			$type = 'T';
18136c72ffaaSAndy Whitcroft
1814389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1815389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1816389a2fe5SAndy Whitcroft			$type = 'T';
1817389a2fe5SAndy Whitcroft
1818c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1819171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1820c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1821171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1822171ae1a4SAndy Whitcroft			if ($2 ne '') {
1823cf655043SAndy Whitcroft				$av_pending = 'N';
1824171ae1a4SAndy Whitcroft			}
1825171ae1a4SAndy Whitcroft			$type = 'E';
1826171ae1a4SAndy Whitcroft
1827c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1828171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1829171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1830171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
18316c72ffaaSAndy Whitcroft
1832c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1833cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1834c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1835cf655043SAndy Whitcroft
1836cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1837cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1838171ae1a4SAndy Whitcroft			$type = 'E';
1839cf655043SAndy Whitcroft
1840c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1841cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1842cf655043SAndy Whitcroft			$av_preprocessor = 1;
1843cf655043SAndy Whitcroft
1844cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1845cf655043SAndy Whitcroft
1846171ae1a4SAndy Whitcroft			$type = 'E';
1847cf655043SAndy Whitcroft
1848c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1849cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1850cf655043SAndy Whitcroft
1851cf655043SAndy Whitcroft			$av_preprocessor = 1;
1852cf655043SAndy Whitcroft
1853cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1854cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1855cf655043SAndy Whitcroft			pop(@av_paren_type);
1856cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1857171ae1a4SAndy Whitcroft			$type = 'E';
18586c72ffaaSAndy Whitcroft
18596c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1860c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
18616c72ffaaSAndy Whitcroft
1862171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1863171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1864171ae1a4SAndy Whitcroft			$av_pending = $type;
1865171ae1a4SAndy Whitcroft			$type = 'N';
1866171ae1a4SAndy Whitcroft
18676c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1868c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
18696c72ffaaSAndy Whitcroft			if (defined $2) {
1870cf655043SAndy Whitcroft				$av_pending = 'V';
18716c72ffaaSAndy Whitcroft			}
18726c72ffaaSAndy Whitcroft			$type = 'N';
18736c72ffaaSAndy Whitcroft
187414b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1875c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
187614b111c1SAndy Whitcroft			$av_pending = 'E';
18776c72ffaaSAndy Whitcroft			$type = 'N';
18786c72ffaaSAndy Whitcroft
18791f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
18801f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
18811f65f947SAndy Whitcroft			$av_pend_colon = 'C';
18821f65f947SAndy Whitcroft			$type = 'N';
18831f65f947SAndy Whitcroft
188414b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1885c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
18866c72ffaaSAndy Whitcroft			$type = 'N';
18876c72ffaaSAndy Whitcroft
18886c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1889c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1890cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1891cf655043SAndy Whitcroft			$av_pending = '_';
18926c72ffaaSAndy Whitcroft			$type = 'N';
18936c72ffaaSAndy Whitcroft
18946c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1895cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1896cf655043SAndy Whitcroft			if ($new_type ne '_') {
1897cf655043SAndy Whitcroft				$type = $new_type;
1898c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1899c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
19006c72ffaaSAndy Whitcroft			} else {
1901c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
19026c72ffaaSAndy Whitcroft			}
19036c72ffaaSAndy Whitcroft
1904c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1905c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1906c8cb2ca3SAndy Whitcroft			$type = 'V';
1907cf655043SAndy Whitcroft			$av_pending = 'V';
19086c72ffaaSAndy Whitcroft
19098e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
19108e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
19111f65f947SAndy Whitcroft				$av_pend_colon = 'B';
19128e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
19138e761b04SAndy Whitcroft				$av_pend_colon = 'L';
19141f65f947SAndy Whitcroft			}
19151f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
19161f65f947SAndy Whitcroft			$type = 'V';
19171f65f947SAndy Whitcroft
19186c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1919c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
19206c72ffaaSAndy Whitcroft			$type = 'V';
19216c72ffaaSAndy Whitcroft
19226c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1923c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
19246c72ffaaSAndy Whitcroft			$type = 'N';
19256c72ffaaSAndy Whitcroft
1926cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1927c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
192813214adfSAndy Whitcroft			$type = 'E';
19291f65f947SAndy Whitcroft			$av_pend_colon = 'O';
193013214adfSAndy Whitcroft
19318e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
19328e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
19338e761b04SAndy Whitcroft			$type = 'C';
19348e761b04SAndy Whitcroft
19351f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
19361f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
19371f65f947SAndy Whitcroft			$type = 'N';
19381f65f947SAndy Whitcroft
19391f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
19401f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
19411f65f947SAndy Whitcroft
19421f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
19431f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
19441f65f947SAndy Whitcroft				$type = 'E';
19451f65f947SAndy Whitcroft			} else {
19461f65f947SAndy Whitcroft				$type = 'N';
19471f65f947SAndy Whitcroft			}
19481f65f947SAndy Whitcroft			$av_pend_colon = 'O';
19491f65f947SAndy Whitcroft
19508e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
195113214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
19526c72ffaaSAndy Whitcroft			$type = 'N';
19536c72ffaaSAndy Whitcroft
19540d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
195574048ed8SAndy Whitcroft			my $variant;
195674048ed8SAndy Whitcroft
195774048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
195874048ed8SAndy Whitcroft			if ($type eq 'V') {
195974048ed8SAndy Whitcroft				$variant = 'B';
196074048ed8SAndy Whitcroft			} else {
196174048ed8SAndy Whitcroft				$variant = 'U';
196274048ed8SAndy Whitcroft			}
196374048ed8SAndy Whitcroft
196474048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
196574048ed8SAndy Whitcroft			$type = 'N';
196674048ed8SAndy Whitcroft
19676c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1968c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
19696c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
19706c72ffaaSAndy Whitcroft				$type = 'N';
19716c72ffaaSAndy Whitcroft			}
19726c72ffaaSAndy Whitcroft
19736c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1974c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
19756c72ffaaSAndy Whitcroft		}
19766c72ffaaSAndy Whitcroft		if (defined $1) {
19776c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
19786c72ffaaSAndy Whitcroft			$res .= $type x length($1);
19796c72ffaaSAndy Whitcroft		}
19806c72ffaaSAndy Whitcroft	}
19816c72ffaaSAndy Whitcroft
19821f65f947SAndy Whitcroft	return ($res, $var);
19836c72ffaaSAndy Whitcroft}
19846c72ffaaSAndy Whitcroft
19858905a67cSAndy Whitcroftsub possible {
198613214adfSAndy Whitcroft	my ($possible, $line) = @_;
19879a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
19880776e594SAndy Whitcroft		^(?:
19890776e594SAndy Whitcroft			$Modifier|
19900776e594SAndy Whitcroft			$Storage|
19910776e594SAndy Whitcroft			$Type|
19929a974fdbSAndy Whitcroft			DEFINE_\S+
19939a974fdbSAndy Whitcroft		)$|
19949a974fdbSAndy Whitcroft		^(?:
19950776e594SAndy Whitcroft			goto|
19960776e594SAndy Whitcroft			return|
19970776e594SAndy Whitcroft			case|
19980776e594SAndy Whitcroft			else|
19990776e594SAndy Whitcroft			asm|__asm__|
200089a88353SAndy Whitcroft			do|
200189a88353SAndy Whitcroft			\#|
200289a88353SAndy Whitcroft			\#\#|
20039a974fdbSAndy Whitcroft		)(?:\s|$)|
20040776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
20059a974fdbSAndy Whitcroft	    )}x;
20069a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
20079a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2008c45dcabdSAndy Whitcroft		# Check for modifiers.
2009c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2010c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2011c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2012c45dcabdSAndy Whitcroft
2013c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2014c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2015d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
20169a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2017d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2018485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2019d2506586SAndy Whitcroft				}
20209a974fdbSAndy Whitcroft			}
2021c45dcabdSAndy Whitcroft
2022c45dcabdSAndy Whitcroft		} else {
202313214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2024485ff23eSAlex Dowad			push(@typeListFile, $possible);
2025c45dcabdSAndy Whitcroft		}
20268905a67cSAndy Whitcroft		build_types();
20270776e594SAndy Whitcroft	} else {
20280776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
20298905a67cSAndy Whitcroft	}
20308905a67cSAndy Whitcroft}
20318905a67cSAndy Whitcroft
20326c72ffaaSAndy Whitcroftmy $prefix = '';
20336c72ffaaSAndy Whitcroft
2034000d1cc1SJoe Perchessub show_type {
2035cbec18afSJoe Perches	my ($type) = @_;
203691bfe484SJoe Perches
2037522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2038522b837cSAlexey Dobriyan
2039cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2040cbec18afSJoe Perches
2041cbec18afSJoe Perches	return !defined $ignore_type{$type};
2042000d1cc1SJoe Perches}
2043000d1cc1SJoe Perches
2044f0a594c1SAndy Whitcroftsub report {
2045cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2046cbec18afSJoe Perches
2047cbec18afSJoe Perches	if (!show_type($type) ||
2048cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2049773647a0SAndy Whitcroft		return 0;
2050773647a0SAndy Whitcroft	}
205157230297SJoe Perches	my $output = '';
2052737c0767SJohn Brooks	if ($color) {
205357230297SJoe Perches		if ($level eq 'ERROR') {
205457230297SJoe Perches			$output .= RED;
205557230297SJoe Perches		} elsif ($level eq 'WARNING') {
205657230297SJoe Perches			$output .= YELLOW;
2057000d1cc1SJoe Perches		} else {
205857230297SJoe Perches			$output .= GREEN;
2059000d1cc1SJoe Perches		}
206057230297SJoe Perches	}
206157230297SJoe Perches	$output .= $prefix . $level . ':';
206257230297SJoe Perches	if ($show_types) {
2063737c0767SJohn Brooks		$output .= BLUE if ($color);
206457230297SJoe Perches		$output .= "$type:";
206557230297SJoe Perches	}
2066737c0767SJohn Brooks	$output .= RESET if ($color);
206757230297SJoe Perches	$output .= ' ' . $msg . "\n";
206834d8815fSJoe Perches
206934d8815fSJoe Perches	if ($showfile) {
207034d8815fSJoe Perches		my @lines = split("\n", $output, -1);
207134d8815fSJoe Perches		splice(@lines, 1, 1);
207234d8815fSJoe Perches		$output = join("\n", @lines);
207334d8815fSJoe Perches	}
207457230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
20758905a67cSAndy Whitcroft
207657230297SJoe Perches	push(our @report, $output);
2077773647a0SAndy Whitcroft
2078773647a0SAndy Whitcroft	return 1;
2079f0a594c1SAndy Whitcroft}
2080cbec18afSJoe Perches
2081f0a594c1SAndy Whitcroftsub report_dump {
208213214adfSAndy Whitcroft	our @report;
2083f0a594c1SAndy Whitcroft}
2084000d1cc1SJoe Perches
2085d752fcc8SJoe Perchessub fixup_current_range {
2086d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2087d752fcc8SJoe Perches
2088d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2089d752fcc8SJoe Perches		my $o = $1;
2090d752fcc8SJoe Perches		my $l = $2;
2091d752fcc8SJoe Perches		my $no = $o + $offset;
2092d752fcc8SJoe Perches		my $nl = $l + $length;
2093d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2094d752fcc8SJoe Perches	}
2095d752fcc8SJoe Perches}
2096d752fcc8SJoe Perches
2097d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2098d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2099d752fcc8SJoe Perches
2100d752fcc8SJoe Perches	my $range_last_linenr = 0;
2101d752fcc8SJoe Perches	my $delta_offset = 0;
2102d752fcc8SJoe Perches
2103d752fcc8SJoe Perches	my $old_linenr = 0;
2104d752fcc8SJoe Perches	my $new_linenr = 0;
2105d752fcc8SJoe Perches
2106d752fcc8SJoe Perches	my $next_insert = 0;
2107d752fcc8SJoe Perches	my $next_delete = 0;
2108d752fcc8SJoe Perches
2109d752fcc8SJoe Perches	my @lines = ();
2110d752fcc8SJoe Perches
2111d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2112d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2113d752fcc8SJoe Perches
2114d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2115d752fcc8SJoe Perches		my $save_line = 1;
2116d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2117323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2118d752fcc8SJoe Perches			$delta_offset = 0;
2119d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2120d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2121d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2122d752fcc8SJoe Perches		}
2123d752fcc8SJoe Perches
2124d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2125d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2126d752fcc8SJoe Perches			$save_line = 0;
2127d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2128d752fcc8SJoe Perches		}
2129d752fcc8SJoe Perches
2130d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2131d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2132d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2133d752fcc8SJoe Perches			$new_linenr++;
2134d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2135d752fcc8SJoe Perches		}
2136d752fcc8SJoe Perches
2137d752fcc8SJoe Perches		if ($save_line) {
2138d752fcc8SJoe Perches			push(@lines, $line);
2139d752fcc8SJoe Perches			$new_linenr++;
2140d752fcc8SJoe Perches		}
2141d752fcc8SJoe Perches
2142d752fcc8SJoe Perches		$old_linenr++;
2143d752fcc8SJoe Perches	}
2144d752fcc8SJoe Perches
2145d752fcc8SJoe Perches	return @lines;
2146d752fcc8SJoe Perches}
2147d752fcc8SJoe Perches
2148f2d7e4d4SJoe Perchessub fix_insert_line {
2149f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2150f2d7e4d4SJoe Perches
2151f2d7e4d4SJoe Perches	my $inserted = {
2152f2d7e4d4SJoe Perches		LINENR => $linenr,
2153f2d7e4d4SJoe Perches		LINE => $line,
2154f2d7e4d4SJoe Perches	};
2155f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2156f2d7e4d4SJoe Perches}
2157f2d7e4d4SJoe Perches
2158f2d7e4d4SJoe Perchessub fix_delete_line {
2159f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2160f2d7e4d4SJoe Perches
2161f2d7e4d4SJoe Perches	my $deleted = {
2162f2d7e4d4SJoe Perches		LINENR => $linenr,
2163f2d7e4d4SJoe Perches		LINE => $line,
2164f2d7e4d4SJoe Perches	};
2165f2d7e4d4SJoe Perches
2166f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2167f2d7e4d4SJoe Perches}
2168f2d7e4d4SJoe Perches
2169de7d4f0eSAndy Whitcroftsub ERROR {
2170cbec18afSJoe Perches	my ($type, $msg) = @_;
2171cbec18afSJoe Perches
2172cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2173de7d4f0eSAndy Whitcroft		our $clean = 0;
21746c72ffaaSAndy Whitcroft		our $cnt_error++;
21753705ce5bSJoe Perches		return 1;
2176de7d4f0eSAndy Whitcroft	}
21773705ce5bSJoe Perches	return 0;
2178773647a0SAndy Whitcroft}
2179de7d4f0eSAndy Whitcroftsub WARN {
2180cbec18afSJoe Perches	my ($type, $msg) = @_;
2181cbec18afSJoe Perches
2182cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2183de7d4f0eSAndy Whitcroft		our $clean = 0;
21846c72ffaaSAndy Whitcroft		our $cnt_warn++;
21853705ce5bSJoe Perches		return 1;
2186de7d4f0eSAndy Whitcroft	}
21873705ce5bSJoe Perches	return 0;
2188773647a0SAndy Whitcroft}
2189de7d4f0eSAndy Whitcroftsub CHK {
2190cbec18afSJoe Perches	my ($type, $msg) = @_;
2191cbec18afSJoe Perches
2192cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2193de7d4f0eSAndy Whitcroft		our $clean = 0;
21946c72ffaaSAndy Whitcroft		our $cnt_chk++;
21953705ce5bSJoe Perches		return 1;
21966c72ffaaSAndy Whitcroft	}
21973705ce5bSJoe Perches	return 0;
2198de7d4f0eSAndy Whitcroft}
2199de7d4f0eSAndy Whitcroft
22006ecd9674SAndy Whitcroftsub check_absolute_file {
22016ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
22026ecd9674SAndy Whitcroft	my $file = $absolute;
22036ecd9674SAndy Whitcroft
22046ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
22056ecd9674SAndy Whitcroft
22066ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
22076ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
22086ecd9674SAndy Whitcroft		if (-f "$root/$file") {
22096ecd9674SAndy Whitcroft			##print "file<$file>\n";
22106ecd9674SAndy Whitcroft			last;
22116ecd9674SAndy Whitcroft		}
22126ecd9674SAndy Whitcroft	}
22136ecd9674SAndy Whitcroft	if (! -f _)  {
22146ecd9674SAndy Whitcroft		return 0;
22156ecd9674SAndy Whitcroft	}
22166ecd9674SAndy Whitcroft
22176ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
22186ecd9674SAndy Whitcroft	my $prefix = $absolute;
22196ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
22206ecd9674SAndy Whitcroft
22216ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
22226ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2223000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2224000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
22256ecd9674SAndy Whitcroft	}
22266ecd9674SAndy Whitcroft}
22276ecd9674SAndy Whitcroft
22283705ce5bSJoe Perchessub trim {
22293705ce5bSJoe Perches	my ($string) = @_;
22303705ce5bSJoe Perches
2231b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2232b34c648bSJoe Perches
2233b34c648bSJoe Perches	return $string;
2234b34c648bSJoe Perches}
2235b34c648bSJoe Perches
2236b34c648bSJoe Perchessub ltrim {
2237b34c648bSJoe Perches	my ($string) = @_;
2238b34c648bSJoe Perches
2239b34c648bSJoe Perches	$string =~ s/^\s+//;
2240b34c648bSJoe Perches
2241b34c648bSJoe Perches	return $string;
2242b34c648bSJoe Perches}
2243b34c648bSJoe Perches
2244b34c648bSJoe Perchessub rtrim {
2245b34c648bSJoe Perches	my ($string) = @_;
2246b34c648bSJoe Perches
2247b34c648bSJoe Perches	$string =~ s/\s+$//;
22483705ce5bSJoe Perches
22493705ce5bSJoe Perches	return $string;
22503705ce5bSJoe Perches}
22513705ce5bSJoe Perches
225252ea8506SJoe Perchessub string_find_replace {
225352ea8506SJoe Perches	my ($string, $find, $replace) = @_;
225452ea8506SJoe Perches
225552ea8506SJoe Perches	$string =~ s/$find/$replace/g;
225652ea8506SJoe Perches
225752ea8506SJoe Perches	return $string;
225852ea8506SJoe Perches}
225952ea8506SJoe Perches
22603705ce5bSJoe Perchessub tabify {
22613705ce5bSJoe Perches	my ($leading) = @_;
22623705ce5bSJoe Perches
2263713a09deSAntonio Borneo	my $source_indent = $tabsize;
22643705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
22653705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
22663705ce5bSJoe Perches
22673705ce5bSJoe Perches	#convert leading spaces to tabs
22683705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
22693705ce5bSJoe Perches	#Remove spaces before a tab
22703705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
22713705ce5bSJoe Perches
22723705ce5bSJoe Perches	return "$leading";
22733705ce5bSJoe Perches}
22743705ce5bSJoe Perches
2275d1fe9c09SJoe Perchessub pos_last_openparen {
2276d1fe9c09SJoe Perches	my ($line) = @_;
2277d1fe9c09SJoe Perches
2278d1fe9c09SJoe Perches	my $pos = 0;
2279d1fe9c09SJoe Perches
2280d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2281d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2282d1fe9c09SJoe Perches
2283d1fe9c09SJoe Perches	my $last_openparen = 0;
2284d1fe9c09SJoe Perches
2285d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2286d1fe9c09SJoe Perches		return -1;
2287d1fe9c09SJoe Perches	}
2288d1fe9c09SJoe Perches
2289d1fe9c09SJoe Perches	my $len = length($line);
2290d1fe9c09SJoe Perches
2291d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2292d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2293d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2294d1fe9c09SJoe Perches			$pos += length($1) - 1;
2295d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2296d1fe9c09SJoe Perches			$last_openparen = $pos;
2297d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2298d1fe9c09SJoe Perches			last;
2299d1fe9c09SJoe Perches		}
2300d1fe9c09SJoe Perches	}
2301d1fe9c09SJoe Perches
230291cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2303d1fe9c09SJoe Perches}
2304d1fe9c09SJoe Perches
2305f36d3eb8SJoe Perchessub get_raw_comment {
2306f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2307f36d3eb8SJoe Perches	my $comment = '';
2308f36d3eb8SJoe Perches
2309f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2310f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2311f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2312f36d3eb8SJoe Perches		}
2313f36d3eb8SJoe Perches	}
2314f36d3eb8SJoe Perches
2315f36d3eb8SJoe Perches	return $comment;
2316f36d3eb8SJoe Perches}
2317f36d3eb8SJoe Perches
23180a920b5bSAndy Whitcroftsub process {
23190a920b5bSAndy Whitcroft	my $filename = shift;
23200a920b5bSAndy Whitcroft
23210a920b5bSAndy Whitcroft	my $linenr=0;
23220a920b5bSAndy Whitcroft	my $prevline="";
2323c2fdda0dSAndy Whitcroft	my $prevrawline="";
23240a920b5bSAndy Whitcroft	my $stashline="";
2325c2fdda0dSAndy Whitcroft	my $stashrawline="";
23260a920b5bSAndy Whitcroft
23274a0df2efSAndy Whitcroft	my $length;
23280a920b5bSAndy Whitcroft	my $indent;
23290a920b5bSAndy Whitcroft	my $previndent=0;
23300a920b5bSAndy Whitcroft	my $stashindent=0;
23310a920b5bSAndy Whitcroft
2332de7d4f0eSAndy Whitcroft	our $clean = 1;
23330a920b5bSAndy Whitcroft	my $signoff = 0;
2334cd261496SGeert Uytterhoeven	my $author = '';
2335cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
23360a920b5bSAndy Whitcroft	my $is_patch = 0;
2337133712a2SRob Herring	my $is_binding_patch = -1;
233829ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
233915662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
234044d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2341ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2342490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2343bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
23442a076f40SJoe Perches	my $commit_log_long_line = 0;
2345e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
234613f1937eSJoe Perches	my $reported_maintainer_file = 0;
2347fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2348fa64205dSPasi Savanainen
2349365dd4eaSJoe Perches	my $last_blank_line = 0;
23505e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2351365dd4eaSJoe Perches
235213214adfSAndy Whitcroft	our @report = ();
23536c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
23546c72ffaaSAndy Whitcroft	our $cnt_error = 0;
23556c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
23566c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
23576c72ffaaSAndy Whitcroft
23580a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
23590a920b5bSAndy Whitcroft	my $realfile = '';
23600a920b5bSAndy Whitcroft	my $realline = 0;
23610a920b5bSAndy Whitcroft	my $realcnt = 0;
23620a920b5bSAndy Whitcroft	my $here = '';
236377cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
23640a920b5bSAndy Whitcroft	my $in_comment = 0;
2365c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
23660a920b5bSAndy Whitcroft	my $first_line = 0;
23671e855726SWolfram Sang	my $p1_prefix = '';
23680a920b5bSAndy Whitcroft
236913214adfSAndy Whitcroft	my $prev_values = 'E';
237013214adfSAndy Whitcroft
237113214adfSAndy Whitcroft	# suppression flags
2372773647a0SAndy Whitcroft	my %suppress_ifbraces;
2373170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
23742b474a1aSAndy Whitcroft	my %suppress_export;
23753e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2376653d4876SAndy Whitcroft
23777e51f197SJoe Perches	my %signatures = ();
2378323c1260SJoe Perches
2379c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2380de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2381c2fdda0dSAndy Whitcroft	#
2382de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2383de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2384773647a0SAndy Whitcroft
2385d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2386d8b07710SJoe Perches
23879f3a8992SRob Herring	my $checklicenseline = 1;
23889f3a8992SRob Herring
2389773647a0SAndy Whitcroft	sanitise_line_reset();
2390c2fdda0dSAndy Whitcroft	my $line;
2391c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2392773647a0SAndy Whitcroft		$linenr++;
2393773647a0SAndy Whitcroft		$line = $rawline;
2394c2fdda0dSAndy Whitcroft
23953705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
23963705ce5bSJoe Perches
2397773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2398de7d4f0eSAndy Whitcroft			$setup_docs = 0;
23998c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2400de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2401de7d4f0eSAndy Whitcroft			}
2402773647a0SAndy Whitcroft			#next;
2403de7d4f0eSAndy Whitcroft		}
240474fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2405773647a0SAndy Whitcroft			$realline=$1-1;
2406773647a0SAndy Whitcroft			if (defined $2) {
2407773647a0SAndy Whitcroft				$realcnt=$3+1;
2408773647a0SAndy Whitcroft			} else {
2409773647a0SAndy Whitcroft				$realcnt=1+1;
2410773647a0SAndy Whitcroft			}
2411c45dcabdSAndy Whitcroft			$in_comment = 0;
2412773647a0SAndy Whitcroft
2413773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2414773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2415773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2416773647a0SAndy Whitcroft			# at context start.
2417773647a0SAndy Whitcroft			my $edge;
241801fa9147SAndy Whitcroft			my $cnt = $realcnt;
241901fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
242001fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
242101fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
242201fa9147SAndy Whitcroft				$cnt--;
242301fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2424721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2425fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2426fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2427fae17daeSAndy Whitcroft					($edge) = $1;
2428fae17daeSAndy Whitcroft					last;
2429fae17daeSAndy Whitcroft				}
2430773647a0SAndy Whitcroft			}
2431773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2432773647a0SAndy Whitcroft				$in_comment = 1;
2433773647a0SAndy Whitcroft			}
2434773647a0SAndy Whitcroft
2435773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2436773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2437773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2438773647a0SAndy Whitcroft			if (!defined $edge &&
243983242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2440773647a0SAndy Whitcroft			{
2441773647a0SAndy Whitcroft				$in_comment = 1;
2442773647a0SAndy Whitcroft			}
2443773647a0SAndy Whitcroft
2444773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2445773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2446773647a0SAndy Whitcroft
2447171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2448773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2449171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2450773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2451773647a0SAndy Whitcroft		}
2452773647a0SAndy Whitcroft		push(@lines, $line);
2453773647a0SAndy Whitcroft
2454773647a0SAndy Whitcroft		if ($realcnt > 1) {
2455773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2456773647a0SAndy Whitcroft		} else {
2457773647a0SAndy Whitcroft			$realcnt = 0;
2458773647a0SAndy Whitcroft		}
2459773647a0SAndy Whitcroft
2460773647a0SAndy Whitcroft		#print "==>$rawline\n";
2461773647a0SAndy Whitcroft		#print "-->$line\n";
2462de7d4f0eSAndy Whitcroft
2463de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2464de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2465de7d4f0eSAndy Whitcroft		}
2466de7d4f0eSAndy Whitcroft	}
2467de7d4f0eSAndy Whitcroft
24686c72ffaaSAndy Whitcroft	$prefix = '';
24696c72ffaaSAndy Whitcroft
2470773647a0SAndy Whitcroft	$realcnt = 0;
2471773647a0SAndy Whitcroft	$linenr = 0;
2472194f66fcSJoe Perches	$fixlinenr = -1;
24730a920b5bSAndy Whitcroft	foreach my $line (@lines) {
24740a920b5bSAndy Whitcroft		$linenr++;
2475194f66fcSJoe Perches		$fixlinenr++;
24761b5539b1SJoe Perches		my $sline = $line;	#copy of $line
24771b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
24780a920b5bSAndy Whitcroft
2479c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2480f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
24816c72ffaaSAndy Whitcroft
248212c253abSJoe Perches# check if it's a mode change, rename or start of a patch
248312c253abSJoe Perches		if (!$in_commit_log &&
248412c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
248512c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
248612c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
248712c253abSJoe Perches			$is_patch = 1;
248812c253abSJoe Perches		}
248912c253abSJoe Perches
24900a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2491e518e9a5SJoe Perches		if (!$in_commit_log &&
249274fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
249374fd4f34SJoe Perches			my $context = $4;
24940a920b5bSAndy Whitcroft			$is_patch = 1;
24954a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
24960a920b5bSAndy Whitcroft			$realline=$1-1;
24970a920b5bSAndy Whitcroft			if (defined $2) {
24980a920b5bSAndy Whitcroft				$realcnt=$3+1;
24990a920b5bSAndy Whitcroft			} else {
25000a920b5bSAndy Whitcroft				$realcnt=1+1;
25010a920b5bSAndy Whitcroft			}
2502c2fdda0dSAndy Whitcroft			annotate_reset();
250313214adfSAndy Whitcroft			$prev_values = 'E';
250413214adfSAndy Whitcroft
2505773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2506170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
25072b474a1aSAndy Whitcroft			%suppress_export = ();
25083e469cdcSAndy Whitcroft			$suppress_statement = 0;
250974fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
251074fd4f34SJoe Perches				$context_function = $1;
251174fd4f34SJoe Perches			} else {
251274fd4f34SJoe Perches				undef $context_function;
251374fd4f34SJoe Perches			}
25140a920b5bSAndy Whitcroft			next;
25150a920b5bSAndy Whitcroft
25164a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
25174a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
25184a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2519773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
25200a920b5bSAndy Whitcroft			$realline++;
2521d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
25220a920b5bSAndy Whitcroft
25234a0df2efSAndy Whitcroft			# Measure the line length and indent.
2524c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
25250a920b5bSAndy Whitcroft
25260a920b5bSAndy Whitcroft			# Track the previous line.
25270a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
25280a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2529c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2530c2fdda0dSAndy Whitcroft
2531773647a0SAndy Whitcroft			#warn "line<$line>\n";
25326c72ffaaSAndy Whitcroft
2533d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2534d8aaf121SAndy Whitcroft			$realcnt--;
25350a920b5bSAndy Whitcroft		}
25360a920b5bSAndy Whitcroft
2537cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2538cc77cdcaSAndy Whitcroft
25396c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
25406c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2541773647a0SAndy Whitcroft
25422ac73b4fSJoe Perches		my $found_file = 0;
2543773647a0SAndy Whitcroft		# extract the filename as it passes
25443bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
25453bf9a009SRabin Vincent			$realfile = $1;
25462b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2547270c49a0SJoe Perches			$in_commit_log = 0;
25482ac73b4fSJoe Perches			$found_file = 1;
25493bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2550773647a0SAndy Whitcroft			$realfile = $1;
25512b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2552270c49a0SJoe Perches			$in_commit_log = 0;
25531e855726SWolfram Sang
25541e855726SWolfram Sang			$p1_prefix = $1;
2555e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2556e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2557000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2558000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
25591e855726SWolfram Sang			}
2560773647a0SAndy Whitcroft
2561c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2562000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2563000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2564773647a0SAndy Whitcroft			}
25652ac73b4fSJoe Perches			$found_file = 1;
25662ac73b4fSJoe Perches		}
25672ac73b4fSJoe Perches
256834d8815fSJoe Perches#make up the handle for any error we report on this line
256934d8815fSJoe Perches		if ($showfile) {
257034d8815fSJoe Perches			$prefix = "$realfile:$realline: "
257134d8815fSJoe Perches		} elsif ($emacs) {
25727d3a9f67SJoe Perches			if ($file) {
25737d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
25747d3a9f67SJoe Perches			} else {
257534d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
257634d8815fSJoe Perches			}
25777d3a9f67SJoe Perches		}
257834d8815fSJoe Perches
25792ac73b4fSJoe Perches		if ($found_file) {
258085b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
258185b0ee18SJoe Perches				WARN("OBSOLETE",
258285b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
258385b0ee18SJoe Perches			}
25847bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
25852ac73b4fSJoe Perches				$check = 1;
25862ac73b4fSJoe Perches			} else {
25872ac73b4fSJoe Perches				$check = $check_orig;
25882ac73b4fSJoe Perches			}
25899f3a8992SRob Herring			$checklicenseline = 1;
2590133712a2SRob Herring
2591133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2592133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2593133712a2SRob Herring
2594133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2595133712a2SRob Herring
2596133712a2SRob Herring				if (($last_binding_patch != -1) &&
2597133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2598133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2599133712a2SRob Herring					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2600133712a2SRob Herring				}
2601133712a2SRob Herring			}
2602133712a2SRob Herring
2603773647a0SAndy Whitcroft			next;
2604773647a0SAndy Whitcroft		}
2605773647a0SAndy Whitcroft
2606389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
26070a920b5bSAndy Whitcroft
2608c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2609c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2610c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
26110a920b5bSAndy Whitcroft
26126c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
26136c72ffaaSAndy Whitcroft
2614490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2615490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2616490b292cSJoe Perches		if ($in_commit_log) {
2617490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2618490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2619490b292cSJoe Perches			}
2620490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2621490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2622490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2623490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2624490b292cSJoe Perches		}
2625490b292cSJoe Perches
2626e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2627e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2628e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2629e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2630e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2631e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2632e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2633e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2634e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2635e518e9a5SJoe Perches		}
2636e518e9a5SJoe Perches
26373bf9a009SRabin Vincent# Check for incorrect file permissions
26383bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
26393bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
264004db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
264104db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2642000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2643000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
26443bf9a009SRabin Vincent			}
26453bf9a009SRabin Vincent		}
26463bf9a009SRabin Vincent
2647cd261496SGeert Uytterhoeven# Check the patch for a From:
2648cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2649cd261496SGeert Uytterhoeven			$author = $1;
2650cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2651cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2652dfa05c28SJoe Perches			$author = reformat_email($author);
2653cd261496SGeert Uytterhoeven		}
2654cd261496SGeert Uytterhoeven
265520112475SJoe Perches# Check the patch for a signoff:
2656dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
26574a0df2efSAndy Whitcroft			$signoff++;
265815662b3eSJoe Perches			$in_commit_log = 0;
2659cd261496SGeert Uytterhoeven			if ($author ne '') {
2660dfa05c28SJoe Perches				if (same_email_addresses($1, $author)) {
2661cd261496SGeert Uytterhoeven					$authorsignoff = 1;
2662cd261496SGeert Uytterhoeven				}
2663cd261496SGeert Uytterhoeven			}
26640a920b5bSAndy Whitcroft		}
266520112475SJoe Perches
266644d303ebSJoe Perches# Check for patch separator
266744d303ebSJoe Perches		if ($line =~ /^---$/) {
266844d303ebSJoe Perches			$has_patch_separator = 1;
266944d303ebSJoe Perches			$in_commit_log = 0;
267044d303ebSJoe Perches		}
267144d303ebSJoe Perches
2672e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2673e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2674e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2675e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2676e0d975b1SJoe Perches		}
2677e0d975b1SJoe Perches
267820112475SJoe Perches# Check signature styles
2679270c49a0SJoe Perches		if (!$in_header_lines &&
2680ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
268120112475SJoe Perches			my $space_before = $1;
268220112475SJoe Perches			my $sign_off = $2;
268320112475SJoe Perches			my $space_after = $3;
268420112475SJoe Perches			my $email = $4;
268520112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
268620112475SJoe Perches
2687ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2688ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2689ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2690ce0338dfSJoe Perches			}
269120112475SJoe Perches			if (defined $space_before && $space_before ne "") {
26923705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
26933705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
26943705ce5bSJoe Perches				    $fix) {
2695194f66fcSJoe Perches					$fixed[$fixlinenr] =
26963705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
26973705ce5bSJoe Perches				}
269820112475SJoe Perches			}
269920112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
27003705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
27013705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
27023705ce5bSJoe Perches				    $fix) {
2703194f66fcSJoe Perches					$fixed[$fixlinenr] =
27043705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
27053705ce5bSJoe Perches				}
27063705ce5bSJoe Perches
270720112475SJoe Perches			}
270820112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
27093705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
27103705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
27113705ce5bSJoe Perches				    $fix) {
2712194f66fcSJoe Perches					$fixed[$fixlinenr] =
27133705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
27143705ce5bSJoe Perches				}
271520112475SJoe Perches			}
271620112475SJoe Perches
2717dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
271820112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
271920112475SJoe Perches			if ($suggested_email eq "") {
2720000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2721000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
272220112475SJoe Perches			} else {
272320112475SJoe Perches				my $dequoted = $suggested_email;
272420112475SJoe Perches				$dequoted =~ s/^"//;
272520112475SJoe Perches				$dequoted =~ s/" </ </;
272620112475SJoe Perches				# Don't force email to have quotes
272720112475SJoe Perches				# Allow just an angle bracketed address
2728dfa05c28SJoe Perches				if (!same_email_addresses($email, $suggested_email)) {
2729000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2730000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
273120112475SJoe Perches				}
27320a920b5bSAndy Whitcroft			}
27337e51f197SJoe Perches
27347e51f197SJoe Perches# Check for duplicate signatures
27357e51f197SJoe Perches			my $sig_nospace = $line;
27367e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
27377e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
27387e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
27397e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
27407e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
27417e51f197SJoe Perches			} else {
27427e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
27437e51f197SJoe Perches			}
27446c5d24eeSSean Christopherson
27456c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
27466c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
27476c5d24eeSSean Christopherson				if ($email eq $author) {
27486c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27496c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
27506c5d24eeSSean Christopherson				}
27516c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
27526c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27536c5d24eeSSean Christopherson                                             "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
27546c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
27556c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27566c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27576c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
27586c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27596c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27606c5d24eeSSean Christopherson				}
27616c5d24eeSSean Christopherson			}
27620a920b5bSAndy Whitcroft		}
27630a920b5bSAndy Whitcroft
2764a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2765a2fe16b9SJoe Perches		if ($in_header_lines &&
2766a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2767a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2768a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2769a2fe16b9SJoe Perches		}
2770a2fe16b9SJoe Perches
277144d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
277244d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
27737ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
277444d303ebSJoe Perches			      "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
27757ebd05efSChristopher Covington		}
27767ebd05efSChristopher Covington
2777369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2778369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2779369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2780369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2781369c8dd3SJoe Perches					# timestamp
2782634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2783634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2784634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2785634cffccSJoe Perches					# stack dump address styles
2786369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2787369c8dd3SJoe Perches		}
2788369c8dd3SJoe Perches
27892a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
27902a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2791bf4daf12SJoe Perches		    length($line) > 75 &&
2792bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2793bf4daf12SJoe Perches					# file delta changes
2794bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2795bf4daf12SJoe Perches					# filename then :
2796bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2797bf4daf12SJoe Perches					# A Fixes: or Link: line
2798bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
27992a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
28002a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
28012a076f40SJoe Perches			$commit_log_long_line = 1;
28022a076f40SJoe Perches		}
28032a076f40SJoe Perches
2804bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2805bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2806bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2807bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2808bf4daf12SJoe Perches		}
2809bf4daf12SJoe Perches
28100d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2811369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2812a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
2813e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2814fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2815aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2816369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2817bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2818fe043ea1SJoe Perches			my $init_char = "c";
2819fe043ea1SJoe Perches			my $orig_commit = "";
28200d7835fcSJoe Perches			my $short = 1;
28210d7835fcSJoe Perches			my $long = 0;
28220d7835fcSJoe Perches			my $case = 1;
28230d7835fcSJoe Perches			my $space = 1;
28240d7835fcSJoe Perches			my $hasdesc = 0;
282519c146a6SJoe Perches			my $hasparens = 0;
28260d7835fcSJoe Perches			my $id = '0123456789ab';
28270d7835fcSJoe Perches			my $orig_desc = "commit description";
28280d7835fcSJoe Perches			my $description = "";
28290d7835fcSJoe Perches
2830fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2831fe043ea1SJoe Perches				$init_char = $1;
2832fe043ea1SJoe Perches				$orig_commit = lc($2);
2833fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2834fe043ea1SJoe Perches				$orig_commit = lc($1);
2835fe043ea1SJoe Perches			}
2836fe043ea1SJoe Perches
28370d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
28380d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
28390d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
28400d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
28410d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
28420d7835fcSJoe Perches				$orig_desc = $1;
284319c146a6SJoe Perches				$hasparens = 1;
28440d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
28450d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
28460d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
28470d7835fcSJoe Perches				$orig_desc = $1;
284819c146a6SJoe Perches				$hasparens = 1;
2849b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2850b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2851b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2852b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2853b671fde0SJoe Perches				$orig_desc = $1;
2854b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2855b671fde0SJoe Perches				$orig_desc .= " " . $1;
285619c146a6SJoe Perches				$hasparens = 1;
28570d7835fcSJoe Perches			}
28580d7835fcSJoe Perches
28590d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
28600d7835fcSJoe Perches							      $id, $orig_desc);
28610d7835fcSJoe Perches
2862948b133aSHeinrich Schuchardt			if (defined($id) &&
2863948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2864d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
28650d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
28660d7835fcSJoe Perches			}
2867d311cd44SJoe Perches		}
2868d311cd44SJoe Perches
286913f1937eSJoe Perches# Check for added, moved or deleted files
287013f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
287113f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
287213f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
287313f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
287413f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2875a82603a8SAndrew Jeffery			$is_patch = 1;
287613f1937eSJoe Perches			$reported_maintainer_file = 1;
287713f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
287813f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
287913f1937eSJoe Perches		}
288013f1937eSJoe Perches
2881e400edb1SRob Herring# Check for adding new DT bindings not in schema format
2882e400edb1SRob Herring		if (!$in_commit_log &&
2883e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
2884e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
2885e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
2886e400edb1SRob Herring			     "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
2887e400edb1SRob Herring		}
2888e400edb1SRob Herring
288900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
28908905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2891000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2892000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
28936c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2894de7d4f0eSAndy Whitcroft		}
2895de7d4f0eSAndy Whitcroft
2896de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2897de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2898171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2899171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2900171ae1a4SAndy Whitcroft
2901171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2902171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2903171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2904171ae1a4SAndy Whitcroft
290534d99219SJoe Perches			CHK("INVALID_UTF8",
2906000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
290700df344fSAndy Whitcroft		}
29080a920b5bSAndy Whitcroft
290915662b3eSJoe Perches# Check if it's the start of a commit log
291015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
291115662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2912eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2913eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
291415662b3eSJoe Perches			$in_header_lines = 0;
291515662b3eSJoe Perches			$in_commit_log = 1;
2916ed43c4e5SAllen Hubbe			$has_commit_log = 1;
291715662b3eSJoe Perches		}
291815662b3eSJoe Perches
2919fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2920fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2921fa64205dSPasi Savanainen		if ($in_header_lines &&
2922fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2923fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2924fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2925fa64205dSPasi Savanainen		}
2926fa64205dSPasi Savanainen
2927fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
292815662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2929fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
293015662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
293115662b3eSJoe Perches		}
293215662b3eSJoe Perches
2933d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2934d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2935d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2936d6430f71SJoe Perches				my $file = $1;
2937d6430f71SJoe Perches
2938d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2939d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2940d6430f71SJoe Perches					#
2941d6430f71SJoe Perches				} else {
2942d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2943d6430f71SJoe Perches				}
2944d6430f71SJoe Perches			}
2945d6430f71SJoe Perches		}
2946d6430f71SJoe Perches
294766b47b4aSKees Cook# Check for various typo / spelling mistakes
294866d7a382SJoe Perches		if (defined($misspellings) &&
294966d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2950ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
295166b47b4aSKees Cook				my $typo = $1;
295266b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
295366b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
295466b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
29550675a8fbSJean Delvare				my $msg_level = \&WARN;
29560675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
29570675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
295866b47b4aSKees Cook						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
295966b47b4aSKees Cook				    $fix) {
296066b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
296166b47b4aSKees Cook				}
296266b47b4aSKees Cook			}
296366b47b4aSKees Cook		}
296466b47b4aSKees Cook
2965a8dd86bfSMatteo Croce# check for invalid commit id
2966a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
2967a8dd86bfSMatteo Croce			my $id;
2968a8dd86bfSMatteo Croce			my $description;
2969a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
2970a8dd86bfSMatteo Croce			if (!defined($id)) {
2971a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
2972a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
2973a8dd86bfSMatteo Croce			}
2974a8dd86bfSMatteo Croce		}
2975a8dd86bfSMatteo Croce
297630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
297730670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
297800df344fSAndy Whitcroft
29790a920b5bSAndy Whitcroft#trailing whitespace
29809c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2981c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2982d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2983d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2984d5e616fcSJoe Perches			    $fix) {
2985194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2986d5e616fcSJoe Perches			}
2987c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2988c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29893705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
29903705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
29913705ce5bSJoe Perches			    $fix) {
2992194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
29933705ce5bSJoe Perches			}
29943705ce5bSJoe Perches
2995d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29960a920b5bSAndy Whitcroft		}
29975368df20SAndy Whitcroft
29984783f894SJosh Triplett# Check for FSF mailing addresses.
2999109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
30001bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
30013e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
30023e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
30034783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
30040675a8fbSJean Delvare			my $msg_level = \&ERROR;
30050675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
30060675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
30074783f894SJosh 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)
30084783f894SJosh Triplett		}
30094783f894SJosh Triplett
30103354957aSAndi Kleen# check for Kconfig help text having a real description
30119fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
30129fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
30133354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3014678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3015678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3016678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3017678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
30183354957aSAndi Kleen			my $length = 0;
30199fe287d7SAndy Whitcroft			my $cnt = $realcnt;
30209fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
30219fe287d7SAndy Whitcroft			my $f;
3022a1385803SAndy Whitcroft			my $is_start = 0;
30239fe287d7SAndy Whitcroft			my $is_end = 0;
3024a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
30259fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
30269fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
30279fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
30289fe287d7SAndy Whitcroft
30299fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
30308d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3031a1385803SAndy Whitcroft
303286adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3033a1385803SAndy Whitcroft					$is_start = 1;
303484af7a61SUlf Magnusson				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
303584af7a61SUlf Magnusson					if ($lines[$ln - 1] =~ "---help---") {
303684af7a61SUlf Magnusson						WARN("CONFIG_DESCRIPTION",
303784af7a61SUlf Magnusson						     "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
303884af7a61SUlf Magnusson					}
3039a1385803SAndy Whitcroft					$length = -1;
3040a1385803SAndy Whitcroft				}
3041a1385803SAndy Whitcroft
30429fe287d7SAndy Whitcroft				$f =~ s/^.//;
30433354957aSAndi Kleen				$f =~ s/#.*//;
30443354957aSAndi Kleen				$f =~ s/^\s+//;
30453354957aSAndi Kleen				next if ($f =~ /^$/);
3046678ae162SUlf Magnusson
3047678ae162SUlf Magnusson				# This only checks context lines in the patch
3048678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3049678ae162SUlf Magnusson				# positives, even though some of these are
3050678ae162SUlf Magnusson				# common words in help texts
3051678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3052678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
30539fe287d7SAndy Whitcroft					$is_end = 1;
30549fe287d7SAndy Whitcroft					last;
30559fe287d7SAndy Whitcroft				}
30563354957aSAndi Kleen				$length++;
30573354957aSAndi Kleen			}
305856193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3059000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
306056193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
306156193274SVadim Bendebury			}
3062a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
30633354957aSAndi Kleen		}
30643354957aSAndi Kleen
3065628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form
3066628f91a2SJoe Perches		if ($realfile =~ /^MAINTAINERS$/ &&
3067628f91a2SJoe Perches		    $rawline =~ /^\+[A-Z]:/ &&
3068628f91a2SJoe Perches		    $rawline !~ /^\+[A-Z]:\t\S/) {
3069628f91a2SJoe Perches			if (WARN("MAINTAINERS_STYLE",
3070628f91a2SJoe Perches				 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3071628f91a2SJoe Perches			    $fix) {
3072628f91a2SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3073628f91a2SJoe Perches			}
3074628f91a2SJoe Perches		}
3075628f91a2SJoe Perches
3076327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
3077327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
3078327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
3079327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
3080327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
3081327953e9SChristoph Jaeger		}
3082327953e9SChristoph Jaeger
3083c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3084c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3085c68e5878SArnaud Lacombe			my $flag = $1;
3086c68e5878SArnaud Lacombe			my $replacement = {
3087c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3088c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3089c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3090c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3091c68e5878SArnaud Lacombe			};
3092c68e5878SArnaud Lacombe
3093c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3094c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3095c68e5878SArnaud Lacombe		}
3096c68e5878SArnaud Lacombe
3097bff5da43SRob Herring# check for DT compatible documentation
30987dd05b38SFlorian Vaussard		if (defined $root &&
30997dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
31007dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
31017dd05b38SFlorian Vaussard
3102bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3103bff5da43SRob Herring
3104cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3105852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3106cc93319bSFlorian Vaussard
3107bff5da43SRob Herring			foreach my $compat (@compats) {
3108bff5da43SRob Herring				my $compat2 = $compat;
3109185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3110185d566bSRob Herring				my $compat3 = $compat;
3111185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3112185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3113bff5da43SRob Herring				if ( $? >> 8 ) {
3114bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3115bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3116bff5da43SRob Herring				}
3117bff5da43SRob Herring
31184fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
31194fbf32a6SFlorian Vaussard				my $vendor = $1;
3120852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3121bff5da43SRob Herring				if ( $? >> 8 ) {
3122bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3123cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3124bff5da43SRob Herring				}
3125bff5da43SRob Herring			}
3126bff5da43SRob Herring		}
3127bff5da43SRob Herring
31289f3a8992SRob Herring# check for using SPDX license tag at beginning of files
31299f3a8992SRob Herring		if ($realline == $checklicenseline) {
31309f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
31319f3a8992SRob Herring				$checklicenseline = 2;
31329f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
31339f3a8992SRob Herring				my $comment = "";
31349f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
31359f3a8992SRob Herring					$comment = '/*';
31369f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
31379f3a8992SRob Herring					$comment = '//';
3138c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
31399f3a8992SRob Herring					$comment = '#';
31409f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
31419f3a8992SRob Herring					$comment = '..';
31429f3a8992SRob Herring				}
31439f3a8992SRob Herring
3144fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3145fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3146fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3147ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3148fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3149fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3150fdf13693SJoe Perches				}
3151fdf13693SJoe Perches
31529f3a8992SRob Herring				if ($comment !~ /^$/ &&
3153ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
31549f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
31559f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
31563b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
31573b6e8ac9SJoe Perches					my $spdx_license = $1;
31583b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
31593b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
31603b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
31613b6e8ac9SJoe Perches					}
316250c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
316350c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
316450c92900SLubomir Rintel						my $msg_level = \&WARN;
316550c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
316650c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
316750c92900SLubomir Rintel
316850c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
316950c92900SLubomir Rintel						    $fix) {
317050c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
317150c92900SLubomir Rintel						}
317250c92900SLubomir Rintel					}
31739f3a8992SRob Herring				}
31749f3a8992SRob Herring			}
31759f3a8992SRob Herring		}
31769f3a8992SRob Herring
31775368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3178d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
31795368df20SAndy Whitcroft
3180a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3181a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3182a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3183a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3184a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3185a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3186a8da38a9SJoe Perches		}
3187a8da38a9SJoe Perches
318847e0c88bSJoe Perches# line length limit (with some exclusions)
318947e0c88bSJoe Perches#
319047e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
319147e0c88bSJoe Perches#	logging functions like pr_info that end in a string
319247e0c88bSJoe Perches#	lines with a single string
319347e0c88bSJoe Perches#	#defines that are a single string
31942e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
319547e0c88bSJoe Perches#
319647e0c88bSJoe Perches# There are 3 different line length message types:
3197ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
319847e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
319947e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
320047e0c88bSJoe Perches#
320147e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
320247e0c88bSJoe Perches#
320347e0c88bSJoe Perches
3204b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
320547e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
320647e0c88bSJoe Perches
320747e0c88bSJoe Perches			# Check the allowed long line types first
320847e0c88bSJoe Perches
320947e0c88bSJoe Perches			# logging functions that end in a string that starts
321047e0c88bSJoe Perches			# before $max_line_length
321147e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
321247e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
321347e0c88bSJoe Perches				$msg_type = "";
321447e0c88bSJoe Perches
321547e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
321647e0c88bSJoe Perches			# #defines with only strings
321747e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
321847e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
321947e0c88bSJoe Perches				$msg_type = "";
322047e0c88bSJoe Perches
3221cc147506SJoe Perches			# More special cases
3222cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3223cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3224d560a5f8SJoe Perches				$msg_type = "";
3225d560a5f8SJoe Perches
32262e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
32272e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
32282e4bbbc5SAndreas Brauchli				$msg_type = "";
32292e4bbbc5SAndreas Brauchli
323047e0c88bSJoe Perches			# Otherwise set the alternate message types
323147e0c88bSJoe Perches
323247e0c88bSJoe Perches			# a comment starts before $max_line_length
323347e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
323447e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
323547e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
323647e0c88bSJoe Perches
323747e0c88bSJoe Perches			# a quoted string starts before $max_line_length
323847e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
323947e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
324047e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
324147e0c88bSJoe Perches			}
324247e0c88bSJoe Perches
324347e0c88bSJoe Perches			if ($msg_type ne "" &&
324447e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3245*bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3246*bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3247*bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3248*bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
32490a920b5bSAndy Whitcroft			}
325047e0c88bSJoe Perches		}
32510a920b5bSAndy Whitcroft
32528905a67cSAndy Whitcroft# check for adding lines without a newline.
32538905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3254000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
3255000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
32568905a67cSAndy Whitcroft		}
32578905a67cSAndy Whitcroft
3258b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3259de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
32600a920b5bSAndy Whitcroft
32610a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3262713a09deSAntonio Borneo# more than $tabsize must use tabs.
3263c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3264c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3265c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3266d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
32673705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
32683705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
32693705ce5bSJoe Perches			    $fix) {
3270194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
32713705ce5bSJoe Perches			}
32720a920b5bSAndy Whitcroft		}
32730a920b5bSAndy Whitcroft
327408e44365SAlberto Panizzo# check for space before tabs.
327508e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
327608e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
32773705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
32783705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
32793705ce5bSJoe Perches			    $fix) {
3280194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3281713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3282194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3283c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
32843705ce5bSJoe Perches			}
328508e44365SAlberto Panizzo		}
328608e44365SAlberto Panizzo
32876a487211SJoe Perches# check for assignments on the start of a line
32886a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
32896a487211SJoe Perches			CHK("ASSIGNMENT_CONTINUATIONS",
32906a487211SJoe Perches			    "Assignment operator '$1' should be on the previous line\n" . $hereprev);
32916a487211SJoe Perches		}
32926a487211SJoe Perches
3293d1fe9c09SJoe Perches# check for && or || at the start of a line
3294d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3295d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
3296d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
3297d1fe9c09SJoe Perches		}
3298d1fe9c09SJoe Perches
3299a91e8994SJoe Perches# check indentation starts on a tab stop
33005b57980dSJoe Perches		if ($perl_version_ok &&
3301bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3302a91e8994SJoe Perches			my $indent = length($1);
3303713a09deSAntonio Borneo			if ($indent % $tabsize) {
3304a91e8994SJoe Perches				if (WARN("TABSTOP",
3305a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3306a91e8994SJoe Perches				    $fix) {
3307713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3308a91e8994SJoe Perches				}
3309a91e8994SJoe Perches			}
3310a91e8994SJoe Perches		}
3311a91e8994SJoe Perches
3312d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
33135b57980dSJoe Perches		if ($perl_version_ok &&
3314fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3315d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3316d1fe9c09SJoe Perches			my $oldindent = $1;
3317d1fe9c09SJoe Perches			my $rest = $2;
3318d1fe9c09SJoe Perches
3319d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3320d1fe9c09SJoe Perches			if ($pos >= 0) {
3321b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3322b34a26f3SJoe Perches				my $newindent = $2;
3323d1fe9c09SJoe Perches
3324d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3325713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3326713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3327d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3328d1fe9c09SJoe Perches
3329d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3330d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
33313705ce5bSJoe Perches
33323705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
33333705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
33343705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3335194f66fcSJoe Perches						$fixed[$fixlinenr] =~
33363705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
33373705ce5bSJoe Perches					}
3338d1fe9c09SJoe Perches				}
3339d1fe9c09SJoe Perches			}
3340d1fe9c09SJoe Perches		}
3341d1fe9c09SJoe Perches
33426ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
33436ab3a970SJoe Perches# avoid checking a few false positives:
33446ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
33456ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
33466ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
33476ab3a970SJoe Perches#   multiline macros that define functions
33486ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
33496ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
33506ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
33513705ce5bSJoe Perches			if (CHK("SPACING",
3352f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
33533705ce5bSJoe Perches			    $fix) {
3354194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3355f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
33563705ce5bSJoe Perches			}
3357aad4f614SJoe Perches		}
3358aad4f614SJoe Perches
335986406b1cSJoe Perches# Block comment styles
336086406b1cSJoe Perches# Networking with an initial /*
336105880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3362fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
336385ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
336485ad978cSJoe Perches		    $realline > 2) {
336505880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
336605880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
336705880600SJoe Perches		}
336805880600SJoe Perches
336986406b1cSJoe Perches# Block comments use * on subsequent lines
337086406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
337186406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3372a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
337361135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3374a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
337586406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
337686406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3377a605e32eSJoe Perches		}
3378a605e32eSJoe Perches
337986406b1cSJoe Perches# Block comments use */ on trailing lines
338086406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3381c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3382c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3383c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
338486406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
338586406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
338605880600SJoe Perches		}
338705880600SJoe Perches
338808eb9b80SJoe Perches# Block comment * alignment
338908eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3390af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3391af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3392af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
339308eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3394af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3395af207524SJoe Perches			my $oldindent;
339608eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3397af207524SJoe Perches			if (defined($1)) {
3398af207524SJoe Perches				$oldindent = expand_tabs($1);
3399af207524SJoe Perches			} else {
3400af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3401af207524SJoe Perches				$oldindent = expand_tabs($1);
3402af207524SJoe Perches			}
340308eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
340408eb9b80SJoe Perches			my $newindent = $1;
340508eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3406af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
340708eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
340808eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
340908eb9b80SJoe Perches			}
341008eb9b80SJoe Perches		}
341108eb9b80SJoe Perches
34127f619191SJoe Perches# check for missing blank lines after struct/union declarations
34137f619191SJoe Perches# with exceptions for various attributes and macros
34147f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
34157f619191SJoe Perches		    $line =~ /^\+/ &&
34167f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
34177f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
34187f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
34197f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
34207f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
34217f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
34227f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
34230bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
34247f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3425d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3426d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3427d752fcc8SJoe Perches			    $fix) {
3428f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3429d752fcc8SJoe Perches			}
34307f619191SJoe Perches		}
34317f619191SJoe Perches
3432365dd4eaSJoe Perches# check for multiple consecutive blank lines
3433365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3434365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3435365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3436d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3437d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3438d752fcc8SJoe Perches			    $fix) {
3439f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3440d752fcc8SJoe Perches			}
3441d752fcc8SJoe Perches
3442365dd4eaSJoe Perches			$last_blank_line = $linenr;
3443365dd4eaSJoe Perches		}
3444365dd4eaSJoe Perches
34453b617e3bSJoe Perches# check for missing blank lines after declarations
34463f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
34473f7bac03SJoe Perches			# actual declarations
34483f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
34495a4e1fd3SJoe Perches			# function pointer declarations
34505a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
34513f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
34523f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
34533f7bac03SJoe Perches			# known declaration macros
34543f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
34553f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
34563f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
34573f7bac03SJoe Perches			# other possible extensions of declaration lines
34583f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
34593f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
34603f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
34613f7bac03SJoe Perches			# looks like a declaration
34623f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
34635a4e1fd3SJoe Perches			# function pointer declarations
34645a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
34653f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
34663f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
34673f7bac03SJoe Perches			# known declaration macros
34683f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
34693f7bac03SJoe Perches			# start of struct or union or enum
3470328b5f41SJoe Perches		      $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
34713f7bac03SJoe Perches			# start or end of block or continuation of declaration
34723f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
34733f7bac03SJoe Perches			# bitfield continuation
34743f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
34753f7bac03SJoe Perches			# other possible extensions of declaration lines
34763f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
34773f7bac03SJoe Perches			# indentation of previous and current line are the same
34783f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3479d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3480d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3481d752fcc8SJoe Perches			    $fix) {
3482f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3483d752fcc8SJoe Perches			}
34843b617e3bSJoe Perches		}
34853b617e3bSJoe Perches
34865f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
34876b4c5bebSAndy Whitcroft# Exceptions:
34886b4c5bebSAndy Whitcroft#  1) within comments
34896b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
34906b4c5bebSAndy Whitcroft#  3) hanging labels
34913705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
34925f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34933705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
34943705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
34953705ce5bSJoe Perches			    $fix) {
3496194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
34973705ce5bSJoe Perches			}
34985f7ddae6SRaffaele Recalcati		}
34995f7ddae6SRaffaele Recalcati
3500b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3501b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3502b9ea10d6SAndy Whitcroft
35035751a24eSJoe Perches# check for unusual line ending [ or (
35045751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
35055751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
35065751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
35075751a24eSJoe Perches		}
35085751a24eSJoe Perches
35094dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
35104dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
35114dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
35124dbed76fSJoe Perches			$context_function = $1;
35134dbed76fSJoe Perches		}
35144dbed76fSJoe Perches
35154dbed76fSJoe Perches# check if this appears to be the end of function declaration
35164dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
35174dbed76fSJoe Perches			undef $context_function;
35184dbed76fSJoe Perches		}
35194dbed76fSJoe Perches
3520032a4c0fSJoe Perches# check indentation of any line with a bare else
3521840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3522032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3523032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3524032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3525840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3526840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3527840080a0SJoe Perches			     defined $lines[$linenr] &&
3528840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3529032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3530032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3531032a4c0fSJoe Perches			}
3532032a4c0fSJoe Perches		}
3533032a4c0fSJoe Perches
3534c00df19aSJoe Perches# check indentation of a line with a break;
3535c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3536c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3537c00df19aSJoe Perches			my $tabs = $1;
3538c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3539c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3540c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3541c00df19aSJoe Perches			}
3542c00df19aSJoe Perches		}
3543c00df19aSJoe Perches
3544c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3545cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3546000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3547000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3548c2fdda0dSAndy Whitcroft		}
354922f2a2efSAndy Whitcroft
355056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
355156e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
355256e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
355356e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
355456e77d70SJoe Perches		}
355556e77d70SJoe Perches
35569c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
35572b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
35582b474a1aSAndy Whitcroft		    $realline_next);
35593e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3560ca819864SJoe Perches		if ($linenr > $suppress_statement &&
35611b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3562170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3563f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3564171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3565171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3566171ae1a4SAndy Whitcroft
35673e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
35683e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
35693e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
35703e469cdcSAndy Whitcroft			# until we hit end of it.
35713e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
35723e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
35733e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
35743e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
35753e469cdcSAndy Whitcroft			}
3576f74bd194SAndy Whitcroft
35772b474a1aSAndy Whitcroft			# Find the real next line.
35782b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
35792b474a1aSAndy Whitcroft			if (defined $realline_next &&
35802b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
35812b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
35822b474a1aSAndy Whitcroft				$realline_next++;
35832b474a1aSAndy Whitcroft			}
35842b474a1aSAndy Whitcroft
3585171ae1a4SAndy Whitcroft			my $s = $stat;
3586171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3587cf655043SAndy Whitcroft
3588c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3589171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3590c2fdda0dSAndy Whitcroft
3591c2fdda0dSAndy Whitcroft			# Ignore functions being called
3592171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3593c2fdda0dSAndy Whitcroft
3594463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3595463f2864SAndy Whitcroft
3596c45dcabdSAndy Whitcroft			# declarations always start with types
3597d2506586SAndy 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) {
3598c45dcabdSAndy Whitcroft				my $type = $1;
3599c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3600c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3601c45dcabdSAndy Whitcroft
36026c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3603a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3604c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3605c2fdda0dSAndy Whitcroft			}
36068905a67cSAndy Whitcroft
36076c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
360865863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3609c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
36109c0ca6f9SAndy Whitcroft			}
36118905a67cSAndy Whitcroft
36128905a67cSAndy Whitcroft			# Check for any sort of function declaration.
36138905a67cSAndy Whitcroft			# int foo(something bar, other baz);
36148905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3615171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
36168905a67cSAndy Whitcroft				my ($name_len) = length($1);
36178905a67cSAndy Whitcroft
3618cf655043SAndy Whitcroft				my $ctx = $s;
3619773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
36208905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3621cf655043SAndy Whitcroft
36228905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3623c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
36248905a67cSAndy Whitcroft
3625c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
36268905a67cSAndy Whitcroft					}
36278905a67cSAndy Whitcroft				}
36288905a67cSAndy Whitcroft			}
36298905a67cSAndy Whitcroft
36309c0ca6f9SAndy Whitcroft		}
36319c0ca6f9SAndy Whitcroft
363200df344fSAndy Whitcroft#
363300df344fSAndy Whitcroft# Checks which may be anchored in the context.
363400df344fSAndy Whitcroft#
363500df344fSAndy Whitcroft
363600df344fSAndy Whitcroft# Check for switch () and associated case and default
363700df344fSAndy Whitcroft# statements should be at the same indent.
363800df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
363900df344fSAndy Whitcroft			my $err = '';
364000df344fSAndy Whitcroft			my $sep = '';
364100df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
364200df344fSAndy Whitcroft			shift(@ctx);
364300df344fSAndy Whitcroft			for my $ctx (@ctx) {
364400df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
364500df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
364600df344fSAndy Whitcroft							$indent != $cindent) {
364700df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
364800df344fSAndy Whitcroft					$sep = '';
364900df344fSAndy Whitcroft				} else {
365000df344fSAndy Whitcroft					$sep = "[...]\n";
365100df344fSAndy Whitcroft				}
365200df344fSAndy Whitcroft			}
365300df344fSAndy Whitcroft			if ($err ne '') {
3654000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3655000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3656de7d4f0eSAndy Whitcroft			}
3657de7d4f0eSAndy Whitcroft		}
3658de7d4f0eSAndy Whitcroft
3659de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3660de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
36610fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3662773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3663773647a0SAndy Whitcroft
36649c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
36658eef05ddSJoe Perches
36668eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
36678eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
36688eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
36698eef05ddSJoe Perches			}
36708eef05ddSJoe Perches
3671de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3672de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3673de7d4f0eSAndy Whitcroft
3674548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3675548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3676de7d4f0eSAndy Whitcroft
3677548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3678548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3679548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3680548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3681548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3682773647a0SAndy Whitcroft				$ctx_ln++;
3683773647a0SAndy Whitcroft			}
3684548596d5SAndy Whitcroft
368553210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
368653210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3687773647a0SAndy Whitcroft
3688773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3689000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3690000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
369101464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
369200df344fSAndy Whitcroft			}
3693773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3694773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3695773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3696773647a0SAndy Whitcroft			{
36979c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
36989c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3699000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3700000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
370101464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
37029c0ca6f9SAndy Whitcroft				}
37039c0ca6f9SAndy Whitcroft			}
370400df344fSAndy Whitcroft		}
370500df344fSAndy Whitcroft
37064d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
3707f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
37083e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
37093e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
37103e469cdcSAndy Whitcroft					if (!defined $stat);
37114d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
37124d001e4dSAndy Whitcroft
37134d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
37144d001e4dSAndy Whitcroft
37159f5af480SJoe Perches			# remove inline comments
37169f5af480SJoe Perches			$s =~ s/$;/ /g;
37179f5af480SJoe Perches			$c =~ s/$;/ /g;
37184d001e4dSAndy Whitcroft
37194d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
37206f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
37216f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
37224d001e4dSAndy Whitcroft
37239f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
37249f5af480SJoe Perches			# none on the first line, and are going to readd them
37259f5af480SJoe Perches			# where necessary.
37269f5af480SJoe Perches			$s =~ s/\n./\n/gs;
37279f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
37289f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
37299f5af480SJoe Perches			}
37309f5af480SJoe Perches
37314d001e4dSAndy Whitcroft			# We want to check the first line inside the block
37324d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
37334d001e4dSAndy Whitcroft			#  1) any blank line termination
37344d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
37354d001e4dSAndy Whitcroft			#  3) any do (...) {
37364d001e4dSAndy Whitcroft			my $continuation = 0;
37374d001e4dSAndy Whitcroft			my $check = 0;
37384d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
37394d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
37404d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
37414d001e4dSAndy Whitcroft				$continuation = 1;
37424d001e4dSAndy Whitcroft			}
37439bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
37444d001e4dSAndy Whitcroft				$check = 1;
37454d001e4dSAndy Whitcroft				$cond_lines++;
37464d001e4dSAndy Whitcroft			}
37474d001e4dSAndy Whitcroft
37484d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
37494d001e4dSAndy Whitcroft			# preprocessor statement.
37504d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
37514d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
37524d001e4dSAndy Whitcroft				$check = 0;
37534d001e4dSAndy Whitcroft			}
37544d001e4dSAndy Whitcroft
37559bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3756740504c6SAndy Whitcroft			$continuation = 0;
37579bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
37589bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
37594d001e4dSAndy Whitcroft
3760f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3761f16fa28fSAndy Whitcroft				# is not linear.
3762f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3763f16fa28fSAndy Whitcroft					$check = 0;
3764f16fa28fSAndy Whitcroft				}
3765f16fa28fSAndy Whitcroft
37669bd49efeSAndy Whitcroft				# Ignore:
37679bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
37689bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
37699bd49efeSAndy Whitcroft				#  3) labels.
3770740504c6SAndy Whitcroft				if ($continuation ||
3771740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
37729bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
37739bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3774740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
377530dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
37769bd49efeSAndy Whitcroft						$cond_lines++;
37779bd49efeSAndy Whitcroft					}
37784d001e4dSAndy Whitcroft				}
377930dad6ebSAndy Whitcroft			}
37804d001e4dSAndy Whitcroft
37814d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
37824d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
37834d001e4dSAndy Whitcroft
37844d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
37854d001e4dSAndy Whitcroft			# this is not this patch's fault.
37864d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
37874d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
37884d001e4dSAndy Whitcroft				$check = 0;
37894d001e4dSAndy Whitcroft			}
37904d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
37914d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
37924d001e4dSAndy Whitcroft			}
37934d001e4dSAndy Whitcroft
37949bd49efeSAndy 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";
37954d001e4dSAndy Whitcroft
37969f5af480SJoe Perches			if ($check && $s ne '' &&
3797713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
37989f5af480SJoe Perches			     ($sindent < $indent) ||
3799f6950a73SJoe Perches			     ($sindent == $indent &&
3800f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
3801713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
3802000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3803000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
38044d001e4dSAndy Whitcroft			}
38054d001e4dSAndy Whitcroft		}
38064d001e4dSAndy Whitcroft
38076c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
38086c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
38091f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
38101f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
38116c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3812c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3813c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3814cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3815cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
38161f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3817c2fdda0dSAndy Whitcroft		}
38186c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
38196c72ffaaSAndy Whitcroft
382000df344fSAndy Whitcroft#ignore lines not being added
38213705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
382200df344fSAndy Whitcroft
382311ca40a0SJoe Perches# check for dereferences that span multiple lines
382411ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
382511ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
382611ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
382711ca40a0SJoe Perches			my $ref = $1;
382811ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
382911ca40a0SJoe Perches			$ref .= $1;
383011ca40a0SJoe Perches			$ref =~ s/\s//g;
383111ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
383211ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
383311ca40a0SJoe Perches		}
383411ca40a0SJoe Perches
3835a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3836c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3837a1ce18e4SJoe Perches			my $type = $1;
3838a1ce18e4SJoe Perches			my $var = $2;
3839207a8e84SJoe Perches			$var = "" if (!defined $var);
3840207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3841a1ce18e4SJoe Perches				my $sign = $1;
3842a1ce18e4SJoe Perches				my $pointer = $2;
3843a1ce18e4SJoe Perches
3844a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3845a1ce18e4SJoe Perches
3846a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3847a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3848a1ce18e4SJoe Perches				    $fix) {
3849a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3850207a8e84SJoe Perches					my $comp_pointer = $pointer;
3851207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3852207a8e84SJoe Perches					$decl .= $comp_pointer;
3853207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3854207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3855a1ce18e4SJoe Perches				}
3856a1ce18e4SJoe Perches			}
3857a1ce18e4SJoe Perches		}
3858a1ce18e4SJoe Perches
3859653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
38607429c690SAndy Whitcroft		if ($dbg_type) {
38617429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3862000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3863000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
38647429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3865000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3866000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
38677429c690SAndy Whitcroft			}
3868653d4876SAndy Whitcroft			next;
3869653d4876SAndy Whitcroft		}
3870a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3871a1ef277eSAndy Whitcroft		if ($dbg_attr) {
38729360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3873000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3874000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
38759360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3876000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3877000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3878a1ef277eSAndy Whitcroft			}
3879a1ef277eSAndy Whitcroft			next;
3880a1ef277eSAndy Whitcroft		}
3881653d4876SAndy Whitcroft
3882f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
388399423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
388499423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3885d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3886d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3887f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3888f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3889f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3890d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3891d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3892f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3893d752fcc8SJoe Perches				$fixedline = $line;
38948d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
3895f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3896d752fcc8SJoe Perches			}
3897f0a594c1SAndy Whitcroft		}
3898f0a594c1SAndy Whitcroft
389900df344fSAndy Whitcroft#
390000df344fSAndy Whitcroft# Checks which are anchored on the added line.
390100df344fSAndy Whitcroft#
390200df344fSAndy Whitcroft
3903653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3904c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3905653d4876SAndy Whitcroft			my $path = $1;
3906653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3907000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3908495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3909495e9d84SJoe Perches			}
3910495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3911495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3912495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3913653d4876SAndy Whitcroft			}
3914653d4876SAndy Whitcroft		}
3915653d4876SAndy Whitcroft
391600df344fSAndy Whitcroft# no C99 // comments
391700df344fSAndy Whitcroft		if ($line =~ m{//}) {
39183705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
39193705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
39203705ce5bSJoe Perches			    $fix) {
3921194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
39223705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
39233705ce5bSJoe Perches					my $comment = trim($1);
3924194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
39253705ce5bSJoe Perches				}
39263705ce5bSJoe Perches			}
392700df344fSAndy Whitcroft		}
392800df344fSAndy Whitcroft		# Remove C99 comments.
39290a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
39306c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
39310a920b5bSAndy Whitcroft
39322b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
39332b474a1aSAndy Whitcroft# the whole statement.
39342b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
39352b474a1aSAndy Whitcroft		if (defined $realline_next &&
39362b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
39372b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
39382b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
39392b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
39403cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
39413cbf62dfSAndy Whitcroft			# a prefix:
39423cbf62dfSAndy Whitcroft			#   XXX(foo);
39433cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3944653d4876SAndy Whitcroft			my $name = $1;
394587a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
39463cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
39473cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
39483cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
39493cbf62dfSAndy Whitcroft
39503cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
39512b474a1aSAndy Whitcroft				\n.}\s*$|
395248012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
395348012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
395448012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
39552b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
39562b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
395748012058SAndy Whitcroft			    )/x) {
39582b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
39592b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
39602b474a1aSAndy Whitcroft			} else {
39612b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
39620a920b5bSAndy Whitcroft			}
39630a920b5bSAndy Whitcroft		}
39642b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
39652b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
39662b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
39672b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
39682b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
39692b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
39702b474a1aSAndy Whitcroft		}
39712b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
39722b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3973000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3974000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
39752b474a1aSAndy Whitcroft		}
39760a920b5bSAndy Whitcroft
39775150bda4SJoe Eloff# check for global initialisers.
39786d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3979d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
39806d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3981d5e616fcSJoe Perches			    $fix) {
39826d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3983d5e616fcSJoe Perches			}
3984f0a594c1SAndy Whitcroft		}
39850a920b5bSAndy Whitcroft# check for static initialisers.
39866d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3987d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
39886d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3989d5e616fcSJoe Perches				      $herecurr) &&
3990d5e616fcSJoe Perches			    $fix) {
39916d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3992d5e616fcSJoe Perches			}
39930a920b5bSAndy Whitcroft		}
39940a920b5bSAndy Whitcroft
39951813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
39961813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
39971813087dSJoe Perches			my $tmp = trim($1);
39981813087dSJoe Perches			WARN("MISORDERED_TYPE",
39991813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
40001813087dSJoe Perches		}
40011813087dSJoe Perches
4002809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4003809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4004809e082eSJoe Perches			my $type = trim($1);
4005809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4006809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4007809e082eSJoe Perches			my $new_type = $type;
4008809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4009809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4010809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4011809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4012809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4013809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4014809e082eSJoe Perches			$new_type = trim($new_type);
4015809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4016809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4017809e082eSJoe Perches			    $fix) {
4018809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4019809e082eSJoe Perches			}
4020809e082eSJoe Perches		}
4021809e082eSJoe Perches
4022cb710ecaSJoe Perches# check for static const char * arrays.
4023cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4024000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4025000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4026cb710ecaSJoe Perches				$herecurr);
4027cb710ecaSJoe Perches		}
4028cb710ecaSJoe Perches
402977b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
403077b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
403177b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
403277b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
403377b8c0a8SJoe Perches			    $fix) {
403477b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
403577b8c0a8SJoe Perches			}
403677b8c0a8SJoe Perches		}
403777b8c0a8SJoe Perches
4038cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4039cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4040000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4041000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4042cb710ecaSJoe Perches				$herecurr);
4043cb710ecaSJoe Perches		}
4044cb710ecaSJoe Perches
4045ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4046ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4047ab7e23f3SJoe Perches			my $found = $1;
4048ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4049ab7e23f3SJoe Perches				WARN("CONST_CONST",
4050ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4051ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4052ab7e23f3SJoe Perches				WARN("CONST_CONST",
4053ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4054ab7e23f3SJoe Perches			}
4055ab7e23f3SJoe Perches		}
4056ab7e23f3SJoe Perches
40579b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
40589b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
40599b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
40609b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
40619b0fa60dSJoe Perches				$herecurr);
40629b0fa60dSJoe Perches               }
40639b0fa60dSJoe Perches
4064b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4065b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4066b598b670SJoe Perches			my $array = $1;
4067b598b670SJoe 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*\))@) {
4068b598b670SJoe Perches				my $array_div = $1;
4069b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4070b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4071b598b670SJoe Perches				    $fix) {
4072b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4073b598b670SJoe Perches				}
4074b598b670SJoe Perches			}
4075b598b670SJoe Perches		}
4076b598b670SJoe Perches
4077b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
407816b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4079b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4080b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4081b36190c5SJoe Perches			    $fix) {
4082194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4083b36190c5SJoe Perches			}
4084b36190c5SJoe Perches		}
4085b36190c5SJoe Perches
4086653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4087653d4876SAndy Whitcroft# make sense.
4088653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
40898054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4090c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
40918ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
409246d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4093000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4094000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
40950a920b5bSAndy Whitcroft		}
40960a920b5bSAndy Whitcroft
40970a920b5bSAndy Whitcroft# * goes on variable not on type
409865863862SAndy Whitcroft		# (char*[ const])
4099bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4100bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
41013705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4102d8aaf121SAndy Whitcroft
410365863862SAndy Whitcroft			# Should start with a space.
410465863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
410565863862SAndy Whitcroft			# Should not end with a space.
410665863862SAndy Whitcroft			$to =~ s/\s+$//;
410765863862SAndy Whitcroft			# '*'s should not have spaces between.
4108f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
410965863862SAndy Whitcroft			}
4110d8aaf121SAndy Whitcroft
41113705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
411265863862SAndy Whitcroft			if ($from ne $to) {
41133705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
41143705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
41153705ce5bSJoe Perches				    $fix) {
41163705ce5bSJoe Perches					my $sub_from = $ident;
41173705ce5bSJoe Perches					my $sub_to = $ident;
41183705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4119194f66fcSJoe Perches					$fixed[$fixlinenr] =~
41203705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
41213705ce5bSJoe Perches				}
412265863862SAndy Whitcroft			}
4123bfcb2cc7SAndy Whitcroft		}
4124bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4125bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
41263705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4127d8aaf121SAndy Whitcroft
412865863862SAndy Whitcroft			# Should start with a space.
412965863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
413065863862SAndy Whitcroft			# Should not end with a space.
413165863862SAndy Whitcroft			$to =~ s/\s+$//;
413265863862SAndy Whitcroft			# '*'s should not have spaces between.
4133f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
413465863862SAndy Whitcroft			}
413565863862SAndy Whitcroft			# Modifiers should have spaces.
413665863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
413765863862SAndy Whitcroft
41383705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4139667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
41403705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
41413705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
41423705ce5bSJoe Perches				    $fix) {
41433705ce5bSJoe Perches
41443705ce5bSJoe Perches					my $sub_from = $match;
41453705ce5bSJoe Perches					my $sub_to = $match;
41463705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4147194f66fcSJoe Perches					$fixed[$fixlinenr] =~
41483705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
41493705ce5bSJoe Perches				}
415065863862SAndy Whitcroft			}
41510a920b5bSAndy Whitcroft		}
41520a920b5bSAndy Whitcroft
41539d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
41549d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
41550675a8fbSJean Delvare			my $msg_level = \&WARN;
41560675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
41570675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
41589d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
41599d3e3c70SJoe Perches		}
41600a920b5bSAndy Whitcroft
41619d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
41628905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4163000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4164000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
41658905a67cSAndy Whitcroft		}
41668905a67cSAndy Whitcroft
416717441227SJoe Perches# check for uses of printk_ratelimit
416817441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4169000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4170000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
417117441227SJoe Perches		}
417217441227SJoe Perches
4173eeef5733SJoe Perches# printk should use KERN_* levels
4174eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4175000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4176eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
417700df344fSAndy Whitcroft		}
41780a920b5bSAndy Whitcroft
4179243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4180243f3803SJoe Perches			my $orig = $1;
4181243f3803SJoe Perches			my $level = lc($orig);
4182243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
41838f26b837SJoe Perches			my $level2 = $level;
41848f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4185243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4186daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
4187243f3803SJoe Perches		}
4188243f3803SJoe Perches
4189dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4190dc139313SJoe Perches			my $orig = $1;
4191dc139313SJoe Perches			my $level = lc($orig);
4192dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4193dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4194dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4195dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4196dc139313SJoe Perches		}
4197dc139313SJoe Perches
419891c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
419991c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
420091c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
420191c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
420291c9afafSAndy Lutomirski			WARN("ENOSYS",
420391c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
420491c9afafSAndy Lutomirski		}
420591c9afafSAndy Lutomirski
4206653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4207653d4876SAndy Whitcroft# or if closed on same line
42085b57980dSJoe Perches		if ($perl_version_ok &&
42092d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
42102d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
42112d453e3bSJoe Perches		    $sline !~ /}/) {
42128d182478SJoe Perches			if (ERROR("OPEN_BRACE",
42132d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
42148d182478SJoe Perches			    $fix) {
42158d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
42168d182478SJoe Perches				my $fixed_line = $rawline;
42178d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
42188d182478SJoe Perches				my $line1 = $1;
42198d182478SJoe Perches				my $line2 = $2;
42208d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
42218d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
42228d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
42238d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
42248d182478SJoe Perches				}
42258d182478SJoe Perches			}
42260a920b5bSAndy Whitcroft		}
4227653d4876SAndy Whitcroft
42288905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
42298905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
42308905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
42318d182478SJoe Perches			if (ERROR("OPEN_BRACE",
42328d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
42338d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
42348d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
42358d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
42368d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
42378d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
42388d182478SJoe Perches				$fixedline = $rawline;
42398d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
42408d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
42418d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
42428d182478SJoe Perches				}
42438d182478SJoe Perches			}
42448905a67cSAndy Whitcroft		}
42458905a67cSAndy Whitcroft
42460c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
42473705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
42483705ce5bSJoe Perches			if (WARN("SPACING",
42493705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
42503705ce5bSJoe Perches			    $fix) {
4251194f66fcSJoe Perches				$fixed[$fixlinenr] =~
42523705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
42533705ce5bSJoe Perches			}
42540c73b4ebSAndy Whitcroft		}
42550c73b4ebSAndy Whitcroft
425631070b5dSJoe Perches# Function pointer declarations
425731070b5dSJoe Perches# check spacing between type, funcptr, and args
425831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
425991f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
426031070b5dSJoe Perches			my $declare = $1;
426131070b5dSJoe Perches			my $pre_pointer_space = $2;
426231070b5dSJoe Perches			my $post_pointer_space = $3;
426331070b5dSJoe Perches			my $funcname = $4;
426431070b5dSJoe Perches			my $post_funcname_space = $5;
426531070b5dSJoe Perches			my $pre_args_space = $6;
426631070b5dSJoe Perches
426791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
426891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
426991f72e9cSJoe Perches# don't need a space so don't warn for those.
427091f72e9cSJoe Perches			my $post_declare_space = "";
427191f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
427291f72e9cSJoe Perches				$post_declare_space = $1;
427391f72e9cSJoe Perches				$declare = rtrim($declare);
427491f72e9cSJoe Perches			}
427591f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
427631070b5dSJoe Perches				WARN("SPACING",
427731070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
427891f72e9cSJoe Perches				$post_declare_space = " ";
427931070b5dSJoe Perches			}
428031070b5dSJoe Perches
428131070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
428291f72e9cSJoe Perches# This test is not currently implemented because these declarations are
428391f72e9cSJoe Perches# equivalent to
428491f72e9cSJoe Perches#	int  foo(int bar, ...)
428591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
428691f72e9cSJoe Perches#
428791f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
428891f72e9cSJoe Perches#				WARN("SPACING",
428991f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
429091f72e9cSJoe Perches#			}
429131070b5dSJoe Perches
429231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
429331070b5dSJoe Perches			if (defined $pre_pointer_space &&
429431070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
429531070b5dSJoe Perches				WARN("SPACING",
429631070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
429731070b5dSJoe Perches			}
429831070b5dSJoe Perches
429931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
430031070b5dSJoe Perches			if (defined $post_pointer_space &&
430131070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
430231070b5dSJoe Perches				WARN("SPACING",
430331070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
430431070b5dSJoe Perches			}
430531070b5dSJoe Perches
430631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
430731070b5dSJoe Perches			if (defined $post_funcname_space &&
430831070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
430931070b5dSJoe Perches				WARN("SPACING",
431031070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
431131070b5dSJoe Perches			}
431231070b5dSJoe Perches
431331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
431431070b5dSJoe Perches			if (defined $pre_args_space &&
431531070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
431631070b5dSJoe Perches				WARN("SPACING",
431731070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
431831070b5dSJoe Perches			}
431931070b5dSJoe Perches
432031070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4321194f66fcSJoe Perches				$fixed[$fixlinenr] =~
432291f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
432331070b5dSJoe Perches			}
432431070b5dSJoe Perches		}
432531070b5dSJoe Perches
43268d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
43278d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4328fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4329fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
43308d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
43318d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
43328d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4333fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
433438dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
43353705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
43363705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
43373705ce5bSJoe Perches				    $fix) {
4338194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
43393705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
43403705ce5bSJoe Perches				}
43418d31cfceSAndy Whitcroft			}
43428d31cfceSAndy Whitcroft		}
43438d31cfceSAndy Whitcroft
4344f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
43456c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4346c2fdda0dSAndy Whitcroft			my $name = $1;
4347773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4348773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4349c2fdda0dSAndy Whitcroft
4350c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4351773647a0SAndy Whitcroft			if ($name =~ /^(?:
4352773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4353773647a0SAndy Whitcroft				volatile|__volatile__|
4354773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4355773647a0SAndy Whitcroft				asm|__asm__)$/x)
4356773647a0SAndy Whitcroft			{
4357c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4358c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4359c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4360c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4361773647a0SAndy Whitcroft
4362773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4363c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4364c2fdda0dSAndy Whitcroft
4365c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4366c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4367773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4368c2fdda0dSAndy Whitcroft
4369c2fdda0dSAndy Whitcroft			} else {
43703705ce5bSJoe Perches				if (WARN("SPACING",
43713705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
43723705ce5bSJoe Perches					     $fix) {
4373194f66fcSJoe Perches					$fixed[$fixlinenr] =~
43743705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
43753705ce5bSJoe Perches				}
4376f0a594c1SAndy Whitcroft			}
43776c72ffaaSAndy Whitcroft		}
43789a4cad4eSEric Nelson
4379653d4876SAndy Whitcroft# Check operator spacing.
43800a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
43813705ce5bSJoe Perches			my $fixed_line = "";
43823705ce5bSJoe Perches			my $line_fixed = 0;
43833705ce5bSJoe Perches
43849c0ca6f9SAndy Whitcroft			my $ops = qr{
43859c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
43869c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
43879c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
43881f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
438984731623SJoe Perches				\?:|\?|:
43909c0ca6f9SAndy Whitcroft			}x;
4391cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
43923705ce5bSJoe Perches
43933705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
43943705ce5bSJoe Perches##			foreach my $el (@elements) {
43953705ce5bSJoe Perches##				print("el: <$el>\n");
43963705ce5bSJoe Perches##			}
43973705ce5bSJoe Perches
43983705ce5bSJoe Perches			my @fix_elements = ();
439900df344fSAndy Whitcroft			my $off = 0;
44006c72ffaaSAndy Whitcroft
44013705ce5bSJoe Perches			foreach my $el (@elements) {
44023705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
44033705ce5bSJoe Perches				$off += length($el);
44043705ce5bSJoe Perches			}
44053705ce5bSJoe Perches
44063705ce5bSJoe Perches			$off = 0;
44073705ce5bSJoe Perches
44086c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4409b34c648bSJoe Perches			my $last_after = -1;
44106c72ffaaSAndy Whitcroft
44110a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
44123705ce5bSJoe Perches
44133705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
44143705ce5bSJoe Perches
44153705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
44163705ce5bSJoe Perches
44174a0df2efSAndy Whitcroft				$off += length($elements[$n]);
44184a0df2efSAndy Whitcroft
441925985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4420773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4421773647a0SAndy Whitcroft				my $cc = '';
4422773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4423773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4424773647a0SAndy Whitcroft				}
4425773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4426773647a0SAndy Whitcroft
44274a0df2efSAndy Whitcroft				my $a = '';
44284a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
44294a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4430cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
44314a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
44324a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4433773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
44344a0df2efSAndy Whitcroft
44350a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
44364a0df2efSAndy Whitcroft
44374a0df2efSAndy Whitcroft				my $c = '';
44380a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
44394a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
44404a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4441cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
44424a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
44434a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
44448b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
44454a0df2efSAndy Whitcroft				} else {
44464a0df2efSAndy Whitcroft					$c = 'E';
44470a920b5bSAndy Whitcroft				}
44480a920b5bSAndy Whitcroft
44494a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
44504a0df2efSAndy Whitcroft
44514a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
44524a0df2efSAndy Whitcroft
44536c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4454de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
44550a920b5bSAndy Whitcroft
445674048ed8SAndy Whitcroft				# Pull out the value of this operator.
44576c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
44580a920b5bSAndy Whitcroft
44591f65f947SAndy Whitcroft				# Get the full operator variant.
44601f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
44611f65f947SAndy Whitcroft
446213214adfSAndy Whitcroft				# Ignore operators passed as parameters.
446313214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4464d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
446513214adfSAndy Whitcroft
4466cf655043SAndy Whitcroft#				# Ignore comments
4467cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
446813214adfSAndy Whitcroft
4469d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
447013214adfSAndy Whitcroft				} elsif ($op eq ';') {
4471cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4472cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
44733705ce5bSJoe Perches						if (ERROR("SPACING",
44743705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4475b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
44763705ce5bSJoe Perches							$line_fixed = 1;
44773705ce5bSJoe Perches						}
4478d8aaf121SAndy Whitcroft					}
4479d8aaf121SAndy Whitcroft
4480d8aaf121SAndy Whitcroft				# // is a comment
4481d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
44820a920b5bSAndy Whitcroft
4483b00e4814SJoe Perches				#   :   when part of a bitfield
4484b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4485b00e4814SJoe Perches					# skip the bitfield test for now
4486b00e4814SJoe Perches
44871f65f947SAndy Whitcroft				# No spaces for:
44881f65f947SAndy Whitcroft				#   ->
4489b00e4814SJoe Perches				} elsif ($op eq '->') {
44904a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
44913705ce5bSJoe Perches						if (ERROR("SPACING",
44923705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4493b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
44943705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
44953705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
44963705ce5bSJoe Perches							}
4497b34c648bSJoe Perches							$line_fixed = 1;
44983705ce5bSJoe Perches						}
44990a920b5bSAndy Whitcroft					}
45000a920b5bSAndy Whitcroft
45012381097bSJoe Perches				# , must not have a space before and must have a space on the right.
45020a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
45032381097bSJoe Perches					my $rtrim_before = 0;
45042381097bSJoe Perches					my $space_after = 0;
45052381097bSJoe Perches					if ($ctx =~ /Wx./) {
45062381097bSJoe Perches						if (ERROR("SPACING",
45072381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
45082381097bSJoe Perches							$line_fixed = 1;
45092381097bSJoe Perches							$rtrim_before = 1;
45102381097bSJoe Perches						}
45112381097bSJoe Perches					}
4512cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
45133705ce5bSJoe Perches						if (ERROR("SPACING",
45143705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
45153705ce5bSJoe Perches							$line_fixed = 1;
4516b34c648bSJoe Perches							$last_after = $n;
45172381097bSJoe Perches							$space_after = 1;
45182381097bSJoe Perches						}
45192381097bSJoe Perches					}
45202381097bSJoe Perches					if ($rtrim_before || $space_after) {
45212381097bSJoe Perches						if ($rtrim_before) {
45222381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45232381097bSJoe Perches						} else {
45242381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
45252381097bSJoe Perches						}
45262381097bSJoe Perches						if ($space_after) {
45272381097bSJoe Perches							$good .= " ";
45283705ce5bSJoe Perches						}
45290a920b5bSAndy Whitcroft					}
45300a920b5bSAndy Whitcroft
45319c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
453274048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
45339c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
45349c0ca6f9SAndy Whitcroft
45359c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
45369c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
45379c0ca6f9SAndy Whitcroft				# unary operator, or a cast
45389c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
453974048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
45400d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4541cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
45423705ce5bSJoe Perches						if (ERROR("SPACING",
45433705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4544b34c648bSJoe Perches							if ($n != $last_after + 2) {
4545b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
45463705ce5bSJoe Perches								$line_fixed = 1;
45473705ce5bSJoe Perches							}
45480a920b5bSAndy Whitcroft						}
4549b34c648bSJoe Perches					}
4550a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4551171ae1a4SAndy Whitcroft						# A unary '*' may be const
4552171ae1a4SAndy Whitcroft
4553171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
45543705ce5bSJoe Perches						if (ERROR("SPACING",
45553705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4556b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
45573705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
45583705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
45593705ce5bSJoe Perches							}
4560b34c648bSJoe Perches							$line_fixed = 1;
45613705ce5bSJoe Perches						}
45620a920b5bSAndy Whitcroft					}
45630a920b5bSAndy Whitcroft
45640a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
45650a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4566773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
45673705ce5bSJoe Perches						if (ERROR("SPACING",
45683705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4569b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
45703705ce5bSJoe Perches							$line_fixed = 1;
45713705ce5bSJoe Perches						}
45720a920b5bSAndy Whitcroft					}
4573773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4574773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
45753705ce5bSJoe Perches						if (ERROR("SPACING",
45763705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4577b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45783705ce5bSJoe Perches							$line_fixed = 1;
45793705ce5bSJoe Perches						}
4580653d4876SAndy Whitcroft					}
4581773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
45823705ce5bSJoe Perches						if (ERROR("SPACING",
45833705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4584b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
45853705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
45863705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4587773647a0SAndy Whitcroft							}
4588b34c648bSJoe Perches							$line_fixed = 1;
45893705ce5bSJoe Perches						}
45903705ce5bSJoe Perches					}
45910a920b5bSAndy Whitcroft
45920a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
45939c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
45949c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
45959c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4596c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4597c2fdda0dSAndy Whitcroft					 $op eq '%')
45980a920b5bSAndy Whitcroft				{
4599d2e025f3SJoe Perches					if ($check) {
4600d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4601d2e025f3SJoe Perches							if (CHK("SPACING",
4602d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4603d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4604d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4605d2e025f3SJoe Perches								$line_fixed = 1;
4606d2e025f3SJoe Perches							}
4607d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4608d2e025f3SJoe Perches							if (CHK("SPACING",
4609d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4610d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4611d2e025f3SJoe Perches								$line_fixed = 1;
4612d2e025f3SJoe Perches							}
4613d2e025f3SJoe Perches						}
4614d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
46153705ce5bSJoe Perches						if (ERROR("SPACING",
46163705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4617b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4618b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4619b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4620b34c648bSJoe Perches							}
46213705ce5bSJoe Perches							$line_fixed = 1;
46223705ce5bSJoe Perches						}
46230a920b5bSAndy Whitcroft					}
46240a920b5bSAndy Whitcroft
46251f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
46261f65f947SAndy Whitcroft				# terminating a case value or a label.
46271f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
46281f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
46293705ce5bSJoe Perches						if (ERROR("SPACING",
46303705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4631b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
46323705ce5bSJoe Perches							$line_fixed = 1;
46333705ce5bSJoe Perches						}
46341f65f947SAndy Whitcroft					}
46351f65f947SAndy Whitcroft
46360a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4637cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
46381f65f947SAndy Whitcroft					my $ok = 0;
46391f65f947SAndy Whitcroft
464022f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
46411f65f947SAndy Whitcroft					if (($op eq '<' &&
46421f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
46431f65f947SAndy Whitcroft					    ($op eq '>' &&
46441f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
46451f65f947SAndy Whitcroft					{
46461f65f947SAndy Whitcroft						$ok = 1;
46471f65f947SAndy Whitcroft					}
46481f65f947SAndy Whitcroft
4649e0df7e1fSJoe Perches					# for asm volatile statements
4650e0df7e1fSJoe Perches					# ignore a colon with another
4651e0df7e1fSJoe Perches					# colon immediately before or after
4652e0df7e1fSJoe Perches					if (($op eq ':') &&
4653e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4654e0df7e1fSJoe Perches						$ok = 1;
4655e0df7e1fSJoe Perches					}
4656e0df7e1fSJoe Perches
465784731623SJoe Perches					# messages are ERROR, but ?: are CHK
46581f65f947SAndy Whitcroft					if ($ok == 0) {
46590675a8fbSJean Delvare						my $msg_level = \&ERROR;
46600675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
466184731623SJoe Perches
46620675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
46633705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
4664b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4665b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4666b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4667b34c648bSJoe Perches							}
46683705ce5bSJoe Perches							$line_fixed = 1;
46693705ce5bSJoe Perches						}
46700a920b5bSAndy Whitcroft					}
467122f2a2efSAndy Whitcroft				}
46724a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
46733705ce5bSJoe Perches
46743705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
46753705ce5bSJoe Perches
46763705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
46770a920b5bSAndy Whitcroft			}
46783705ce5bSJoe Perches
46793705ce5bSJoe Perches			if (($#elements % 2) == 0) {
46803705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
46813705ce5bSJoe Perches			}
46823705ce5bSJoe Perches
4683194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4684194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
46853705ce5bSJoe Perches			}
46863705ce5bSJoe Perches
46873705ce5bSJoe Perches
46880a920b5bSAndy Whitcroft		}
46890a920b5bSAndy Whitcroft
4690786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4691d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4692786b6326SJoe Perches			if (WARN("SPACING",
4693786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4694786b6326SJoe Perches			    $fix) {
4695194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4696786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4697786b6326SJoe Perches			}
4698786b6326SJoe Perches		}
4699786b6326SJoe Perches
4700f0a594c1SAndy Whitcroft# check for multiple assignments
4701f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4702000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4703000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4704f0a594c1SAndy Whitcroft		}
4705f0a594c1SAndy Whitcroft
470622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
470722f2a2efSAndy Whitcroft## # continuation.
470822f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
470922f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
471022f2a2efSAndy Whitcroft##
471122f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
471222f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
471322f2a2efSAndy Whitcroft## 			my $ln = $line;
471422f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
471522f2a2efSAndy Whitcroft## 			}
471622f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4717000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4718000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
471922f2a2efSAndy Whitcroft## 			}
472022f2a2efSAndy Whitcroft## 		}
4721f0a594c1SAndy Whitcroft
47220a920b5bSAndy Whitcroft#need space before brace following if, while, etc
47236b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
47246ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
47253705ce5bSJoe Perches			if (ERROR("SPACING",
47263705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
47273705ce5bSJoe Perches			    $fix) {
47286ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
47293705ce5bSJoe Perches			}
4730de7d4f0eSAndy Whitcroft		}
4731de7d4f0eSAndy Whitcroft
4732c4a62ef9SJoe Perches## # check for blank lines before declarations
4733c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4734c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4735c4a62ef9SJoe Perches##			WARN("SPACING",
4736c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4737c4a62ef9SJoe Perches##		}
4738c4a62ef9SJoe Perches##
4739c4a62ef9SJoe Perches
4740de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4741de7d4f0eSAndy Whitcroft# on the line
474294fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
4743d5e616fcSJoe Perches			if (ERROR("SPACING",
4744d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4745d5e616fcSJoe Perches			    $fix) {
4746194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4747d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4748d5e616fcSJoe Perches			}
47490a920b5bSAndy Whitcroft		}
47500a920b5bSAndy Whitcroft
475122f2a2efSAndy Whitcroft# check spacing on square brackets
475222f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
47533705ce5bSJoe Perches			if (ERROR("SPACING",
47543705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
47553705ce5bSJoe Perches			    $fix) {
4756194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47573705ce5bSJoe Perches				    s/\[\s+/\[/;
47583705ce5bSJoe Perches			}
475922f2a2efSAndy Whitcroft		}
476022f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
47613705ce5bSJoe Perches			if (ERROR("SPACING",
47623705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
47633705ce5bSJoe Perches			    $fix) {
4764194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47653705ce5bSJoe Perches				    s/\s+\]/\]/;
47663705ce5bSJoe Perches			}
476722f2a2efSAndy Whitcroft		}
476822f2a2efSAndy Whitcroft
4769c45dcabdSAndy Whitcroft# check spacing on parentheses
47709c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
47719c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
47723705ce5bSJoe Perches			if (ERROR("SPACING",
47733705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
47743705ce5bSJoe Perches			    $fix) {
4775194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47763705ce5bSJoe Perches				    s/\(\s+/\(/;
47773705ce5bSJoe Perches			}
477822f2a2efSAndy Whitcroft		}
477913214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4780c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4781c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
47823705ce5bSJoe Perches			if (ERROR("SPACING",
47833705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
47843705ce5bSJoe Perches			    $fix) {
4785194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47863705ce5bSJoe Perches				    s/\s+\)/\)/;
47873705ce5bSJoe Perches			}
478822f2a2efSAndy Whitcroft		}
478922f2a2efSAndy Whitcroft
4790e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4791e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4792e2826fd0SJoe Perches
4793e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4794ea4acbb1SJoe Perches			my $var = $1;
4795ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4796ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4797ea4acbb1SJoe Perches			    $fix) {
4798ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4799ea4acbb1SJoe Perches			}
4800ea4acbb1SJoe Perches		}
4801ea4acbb1SJoe Perches
4802ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4803ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4804ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4805ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4806ea4acbb1SJoe Perches			my $var = $2;
4807ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4808ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4809ea4acbb1SJoe Perches			    $fix) {
4810ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4811ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4812ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4813ea4acbb1SJoe Perches			}
4814e2826fd0SJoe Perches		}
4815e2826fd0SJoe Perches
481663b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
4817a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
4818a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
48195b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
482063b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
482163b7c73eSJoe Perches			my $if_stat = $1;
482263b7c73eSJoe Perches			my $test = substr($2, 1, -1);
482363b7c73eSJoe Perches			my $herectx;
482463b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
482563b7c73eSJoe Perches				my $match = $1;
482663b7c73eSJoe Perches				# avoid parentheses around potential macro args
482763b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
482863b7c73eSJoe Perches				if (!defined($herectx)) {
482963b7c73eSJoe Perches					$herectx = $here . "\n";
483063b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
483163b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
483263b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
483363b7c73eSJoe Perches						$herectx .=  $rl . "\n";
483463b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
483563b7c73eSJoe Perches					}
483663b7c73eSJoe Perches				}
483763b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
483863b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
483963b7c73eSJoe Perches			}
484063b7c73eSJoe Perches		}
484163b7c73eSJoe Perches
48420a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
48434a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
48440a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
48453705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
48463705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
48473705ce5bSJoe Perches			    $fix) {
4848194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48493705ce5bSJoe Perches				    s/^(.)\s+/$1/;
48503705ce5bSJoe Perches			}
48510a920b5bSAndy Whitcroft		}
48520a920b5bSAndy Whitcroft
48535b9553abSJoe Perches# return is not a function
4854507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4855c45dcabdSAndy Whitcroft			my $spacing = $1;
48565b57980dSJoe Perches			if ($perl_version_ok &&
48575b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
48585b9553abSJoe Perches				my $value = $1;
48595b9553abSJoe Perches				$value = deparenthesize($value);
48605b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4861000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4862000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
48635b9553abSJoe Perches				}
4864c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4865000d1cc1SJoe Perches				ERROR("SPACING",
4866000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4867c45dcabdSAndy Whitcroft			}
4868c45dcabdSAndy Whitcroft		}
4869507e5141SJoe Perches
4870b43ae21bSJoe Perches# unnecessary return in a void function
4871b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4872b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4873b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4874b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4875b43ae21bSJoe Perches		    $linenr >= 3 &&
4876b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4877b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
48789819cf25SJoe Perches			WARN("RETURN_VOID",
4879b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
48809819cf25SJoe Perches               }
48819819cf25SJoe Perches
4882189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
48835b57980dSJoe Perches		if ($perl_version_ok &&
4884189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4885189248d8SJoe Perches			my $openparens = $1;
4886189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4887189248d8SJoe Perches			my $msg = "";
4888189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4889189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4890189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4891189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4892189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4893189248d8SJoe Perches			}
4894189248d8SJoe Perches		}
4895189248d8SJoe Perches
4896c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4897c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4898c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4899c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
49005b57980dSJoe Perches		if ($perl_version_ok &&
4901c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4902c5595fa2SJoe Perches			my $lead = $1;
4903c5595fa2SJoe Perches			my $const = $2;
4904c5595fa2SJoe Perches			my $comp = $3;
4905c5595fa2SJoe Perches			my $to = $4;
4906c5595fa2SJoe Perches			my $newcomp = $comp;
4907f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4908c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4909c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4910c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4911c5595fa2SJoe Perches			    $fix) {
4912c5595fa2SJoe Perches				if ($comp eq "<") {
4913c5595fa2SJoe Perches					$newcomp = ">";
4914c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4915c5595fa2SJoe Perches					$newcomp = ">=";
4916c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4917c5595fa2SJoe Perches					$newcomp = "<";
4918c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4919c5595fa2SJoe Perches					$newcomp = "<=";
4920c5595fa2SJoe Perches				}
4921c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4922c5595fa2SJoe Perches			}
4923c5595fa2SJoe Perches		}
4924c5595fa2SJoe Perches
4925f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4926f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
492753a3c448SAndy Whitcroft			my $name = $1;
492853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4929000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4930f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
493153a3c448SAndy Whitcroft			}
493253a3c448SAndy Whitcroft		}
4933c45dcabdSAndy Whitcroft
49340a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
49354a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
49363705ce5bSJoe Perches			if (ERROR("SPACING",
49373705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
49383705ce5bSJoe Perches			    $fix) {
4939194f66fcSJoe Perches				$fixed[$fixlinenr] =~
49403705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
49413705ce5bSJoe Perches			}
49420a920b5bSAndy Whitcroft		}
49430a920b5bSAndy Whitcroft
4944f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4945f5fe35ddSAndy Whitcroft# statements after the conditional.
4946170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
49473e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
49483e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
49493e469cdcSAndy Whitcroft					if (!defined $stat);
4950170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4951170d3a22SAndy Whitcroft						$remain_next, $off_next);
4952170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4953170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4954170d3a22SAndy Whitcroft
4955170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4956170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4957170d3a22SAndy Whitcroft				# then count those as offsets.
4958170d3a22SAndy Whitcroft				my ($whitespace) =
4959170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4960170d3a22SAndy Whitcroft				my $offset =
4961170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4962170d3a22SAndy Whitcroft
4963170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4964170d3a22SAndy Whitcroft								$offset} = 1;
4965170d3a22SAndy Whitcroft			}
4966170d3a22SAndy Whitcroft		}
4967170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4968c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4969170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4970171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
49718905a67cSAndy Whitcroft
4972b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4973000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4974000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
49758905a67cSAndy Whitcroft			}
49768905a67cSAndy Whitcroft
49778905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
49788905a67cSAndy Whitcroft			# conditional.
4979773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
49808905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
498113214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
498253210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
498353210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4984773647a0SAndy Whitcroft			{
4985bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4986bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4987bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
498842bdf74cSHidetoshi Seto				my $stat_real = '';
4989bb44ad39SAndy Whitcroft
499042bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
499142bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4992bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4993bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4994bb44ad39SAndy Whitcroft				}
4995bb44ad39SAndy Whitcroft
4996000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4997000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
49988905a67cSAndy Whitcroft			}
49998905a67cSAndy Whitcroft		}
50008905a67cSAndy Whitcroft
500113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
500213214adfSAndy Whitcroft		if ($line =~ /
500313214adfSAndy Whitcroft			(?:
500413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
500513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
500613214adfSAndy Whitcroft				(?:\&\&|\|\|)
500713214adfSAndy Whitcroft			|
500813214adfSAndy Whitcroft				(?:\&\&|\|\|)
500913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
501013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
501113214adfSAndy Whitcroft			)/x)
501213214adfSAndy Whitcroft		{
5013000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5014000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
501513214adfSAndy Whitcroft		}
501613214adfSAndy Whitcroft
50178905a67cSAndy Whitcroft# if and else should not have general statements after it
501813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
501913214adfSAndy Whitcroft			my $s = $1;
502013214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
502113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5022000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5023000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
50240a920b5bSAndy Whitcroft			}
502513214adfSAndy Whitcroft		}
502639667782SAndy Whitcroft# if should not continue a brace
502739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5028000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5029048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
503039667782SAndy Whitcroft				$herecurr);
503139667782SAndy Whitcroft		}
5032a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5033a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5034a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
50353fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5036a1080bf8SAndy Whitcroft			\s*return\s+
5037a1080bf8SAndy Whitcroft		    )/xg)
5038a1080bf8SAndy Whitcroft		{
5039000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5040000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5041a1080bf8SAndy Whitcroft		}
50420a920b5bSAndy Whitcroft
50430a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
50440a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
50458b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
50460a920b5bSAndy Whitcroft		    $previndent == $indent) {
50478b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
50488b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
50498b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
50508b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
50518b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
50528b8856f4SJoe Perches				my $fixedline = $prevrawline;
50538b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
50548b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
50558b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
50568b8856f4SJoe Perches				}
50578b8856f4SJoe Perches				$fixedline = $rawline;
50588b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
50598b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
50608b8856f4SJoe Perches			}
50610a920b5bSAndy Whitcroft		}
50620a920b5bSAndy Whitcroft
50638b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5064c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5065c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5066c2fdda0dSAndy Whitcroft
5067c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5068c2fdda0dSAndy Whitcroft			# conditional.
5069773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5070c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5071c2fdda0dSAndy Whitcroft
5072c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
50738b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
50748b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
50758b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
50768b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
50778b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
50788b8856f4SJoe Perches					my $fixedline = $prevrawline;
50798b8856f4SJoe Perches					my $trailing = $rawline;
50808b8856f4SJoe Perches					$trailing =~ s/^\+//;
50818b8856f4SJoe Perches					$trailing = trim($trailing);
50828b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
50838b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
50848b8856f4SJoe Perches				}
5085c2fdda0dSAndy Whitcroft			}
5086c2fdda0dSAndy Whitcroft		}
5087c2fdda0dSAndy Whitcroft
508895e2c602SJoe Perches#Specific variable tests
5089323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5090323c1260SJoe Perches			my $var = $1;
509195e2c602SJoe Perches
509295e2c602SJoe Perches#CamelCase
5093807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5094be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
509522735ce8SJoe Perches#Ignore Page<foo> variants
5096807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5097d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5098d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5099d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5100f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5101f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
51027e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
51037e781f67SJoe Perches					my $word = $1;
51047e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5105d8b07710SJoe Perches					if ($check) {
5106d8b07710SJoe Perches						seed_camelcase_includes();
5107d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5108d8b07710SJoe Perches							seed_camelcase_file($realfile);
5109d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5110d8b07710SJoe Perches						}
5111d8b07710SJoe Perches					}
51127e781f67SJoe Perches					if (!defined $camelcase{$word}) {
51137e781f67SJoe Perches						$camelcase{$word} = 1;
5114be79794bSJoe Perches						CHK("CAMELCASE",
51157e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
51167e781f67SJoe Perches					}
5117323c1260SJoe Perches				}
5118323c1260SJoe Perches			}
51193445686aSJoe Perches		}
51200a920b5bSAndy Whitcroft
51210a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5122d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5123d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5124d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5125d5e616fcSJoe Perches			    $fix) {
5126194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5127d5e616fcSJoe Perches			}
51280a920b5bSAndy Whitcroft		}
51290a920b5bSAndy Whitcroft
51300e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
51310e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5132c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5133e09dec48SAndy Whitcroft			my $file = "$1.h";
5134e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5135e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5136e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
51377840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5138c45dcabdSAndy Whitcroft			{
51390e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
51400e212e0aSFabian Frederick				if ($asminclude > 0) {
5141e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5142000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5143000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5144e09dec48SAndy Whitcroft					} else {
5145000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5146000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5147e09dec48SAndy Whitcroft					}
51480a920b5bSAndy Whitcroft				}
51490a920b5bSAndy Whitcroft			}
51500e212e0aSFabian Frederick		}
51510a920b5bSAndy Whitcroft
5152653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5153653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5154cf655043SAndy Whitcroft# in a known good container
5155b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5156b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5157d8aaf121SAndy Whitcroft			my $ln = $linenr;
5158d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5159c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5160c45dcabdSAndy Whitcroft			my $ctx = '';
516108a2843eSJoe Perches			my $has_flow_statement = 0;
516208a2843eSJoe Perches			my $has_arg_concat = 0;
5163c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5164f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5165f74bd194SAndy Whitcroft			$ctx = $dstat;
5166c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5167a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5168c45dcabdSAndy Whitcroft
516908a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
517062e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
517108a2843eSJoe Perches
5172f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5173f59b64bfSJoe Perches			my $define_args = $1;
5174f59b64bfSJoe Perches			my $define_stmt = $dstat;
5175f59b64bfSJoe Perches			my @def_args = ();
5176f59b64bfSJoe Perches
5177f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5178f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5179f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
51808c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5181f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5182f59b64bfSJoe Perches			}
5183f59b64bfSJoe Perches
5184292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5185c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5186c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5187c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5188c45dcabdSAndy Whitcroft
5189c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
5190bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5191bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
51926b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
5193bf30d6edSAndy Whitcroft			{
5194c45dcabdSAndy Whitcroft			}
5195c45dcabdSAndy Whitcroft
5196342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
519733acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
519833acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5199e45bab8eSAndy Whitcroft			{
5200e45bab8eSAndy Whitcroft			}
5201e45bab8eSAndy Whitcroft
520242e15293SJoe Perches			# Make asm volatile uses seem like a generic function
520342e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
520442e15293SJoe Perches
5205c45dcabdSAndy Whitcroft			my $exceptions = qr{
5206c45dcabdSAndy Whitcroft				$Declare|
5207c45dcabdSAndy Whitcroft				module_param_named|
5208a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5209c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5210c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5211383099fdSAndy Whitcroft				__typeof__\(|
521222fd2d3eSStefani Seibold				union|
521322fd2d3eSStefani Seibold				struct|
5214ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
52156b10df42SVladimir Zapolskiy				^\"|\"$|
52166b10df42SVladimir Zapolskiy				^\[
5217c45dcabdSAndy Whitcroft			}x;
52185eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5219f59b64bfSJoe Perches
5220f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5221f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5222e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5223f59b64bfSJoe Perches
5224f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5225f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5226f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
52273cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5228356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5229f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5230f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5231e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
523272f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
5233f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5234f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5235f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
52364e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5237f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5238c45dcabdSAndy Whitcroft			{
5239e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5240e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5241e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5242e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5243f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5244f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5245f74bd194SAndy Whitcroft				} else {
5246000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5247388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5248d8aaf121SAndy Whitcroft				}
5249f59b64bfSJoe Perches
5250f59b64bfSJoe Perches			}
52515207649bSJoe Perches
52525207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
52535207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
52545207649bSJoe Perches			my $first = 1;
52555207649bSJoe Perches			$define_stmt = "";
52565207649bSJoe Perches			foreach my $l (@stmt_array) {
52575207649bSJoe Perches				$l =~ s/\\$//;
52585207649bSJoe Perches				if ($first) {
52595207649bSJoe Perches					$define_stmt = $l;
52605207649bSJoe Perches					$first = 0;
52615207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
52625207649bSJoe Perches					$define_stmt .= substr($l, 1);
52635207649bSJoe Perches				}
52645207649bSJoe Perches			}
52655207649bSJoe Perches			$define_stmt =~ s/$;//g;
52665207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
52675207649bSJoe Perches			$define_stmt = trim($define_stmt);
52685207649bSJoe Perches
5269f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5270f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5271f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
52729192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
52737fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
52746dba824eSBrendan Jackman				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
52757fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
52767fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5277d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5278f59b64bfSJoe Perches				if ($use_cnt > 1) {
5279f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5280f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5281f59b64bfSJoe Perches				    }
52829192d41aSJoe Perches# check if any macro arguments may have other precedence issues
52837fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
52849192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
52859192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
52869192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
52879192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
52889192d41aSJoe Perches				}
52890a920b5bSAndy Whitcroft			}
52905023d347SJoe Perches
529108a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
529208a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
529308a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
529408a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5295e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
529608a2843eSJoe Perches
529708a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
529808a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
529908a2843eSJoe Perches			}
530008a2843eSJoe Perches
5301481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
53025023d347SJoe Perches
53035023d347SJoe Perches		} else {
53045023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5305481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5306481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
53075023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
53085023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
53095023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
53105023d347SJoe Perches			}
5311653d4876SAndy Whitcroft		}
53120a920b5bSAndy Whitcroft
5313b13edf7fSJoe Perches# do {} while (0) macro tests:
5314b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5315b13edf7fSJoe Perches# macro should not end with a semicolon
53165b57980dSJoe Perches		if ($perl_version_ok &&
5317b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5318b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5319b13edf7fSJoe Perches			my $ln = $linenr;
5320b13edf7fSJoe Perches			my $cnt = $realcnt;
5321b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5322b13edf7fSJoe Perches			my $ctx = '';
5323b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5324b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5325b13edf7fSJoe Perches			$ctx = $dstat;
5326b13edf7fSJoe Perches
5327b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
53281b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5329b13edf7fSJoe Perches
5330b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5331b13edf7fSJoe Perches				my $stmts = $2;
5332b13edf7fSJoe Perches				my $semis = $3;
5333b13edf7fSJoe Perches
5334b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5335b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5336e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5337b13edf7fSJoe Perches
5338ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5339ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5340b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5341b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5342b13edf7fSJoe Perches				}
5343b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5344b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5345b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5346b13edf7fSJoe Perches				}
5347f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5348f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5349f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5350e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5351f5ef95b1SJoe Perches
5352f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5353f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5354b13edf7fSJoe Perches			}
5355b13edf7fSJoe Perches		}
5356b13edf7fSJoe Perches
5357f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
535813214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
535913214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5360cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
536113214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5362cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5363cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5364aad4f614SJoe Perches				my @allowed = ();
5365aad4f614SJoe Perches				my $allow = 0;
536613214adfSAndy Whitcroft				my $seen = 0;
5367773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5368cf655043SAndy Whitcroft				my $ln = $linenr - 1;
536913214adfSAndy Whitcroft				for my $chunk (@chunks) {
537013214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
537113214adfSAndy Whitcroft
5372773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5373773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5374773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5375773647a0SAndy Whitcroft
5376aad4f614SJoe Perches					$allowed[$allow] = 0;
5377773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5378773647a0SAndy Whitcroft
5379773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5380773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5381773647a0SAndy Whitcroft
5382773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5383cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5384cf655043SAndy Whitcroft
5385773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
538613214adfSAndy Whitcroft
538713214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
538813214adfSAndy Whitcroft
5389aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5390cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5391cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5392aad4f614SJoe Perches						$allowed[$allow] = 1;
539313214adfSAndy Whitcroft					}
539413214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5395cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5396aad4f614SJoe Perches						$allowed[$allow] = 1;
539713214adfSAndy Whitcroft					}
5398cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5399cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5400aad4f614SJoe Perches						$allowed[$allow] = 1;
540113214adfSAndy Whitcroft					}
5402aad4f614SJoe Perches					$allow++;
540313214adfSAndy Whitcroft				}
5404aad4f614SJoe Perches				if ($seen) {
5405aad4f614SJoe Perches					my $sum_allowed = 0;
5406aad4f614SJoe Perches					foreach (@allowed) {
5407aad4f614SJoe Perches						$sum_allowed += $_;
5408aad4f614SJoe Perches					}
5409aad4f614SJoe Perches					if ($sum_allowed == 0) {
5410000d1cc1SJoe Perches						WARN("BRACES",
5411000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5412aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5413aad4f614SJoe Perches						 $seen != $allow) {
5414aad4f614SJoe Perches						CHK("BRACES",
5415aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5416aad4f614SJoe Perches					}
541713214adfSAndy Whitcroft				}
541813214adfSAndy Whitcroft			}
541913214adfSAndy Whitcroft		}
5420773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
542113214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5422cf655043SAndy Whitcroft			my $allowed = 0;
5423f0a594c1SAndy Whitcroft
5424cf655043SAndy Whitcroft			# Check the pre-context.
5425cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5426cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5427cf655043SAndy Whitcroft				$allowed = 1;
5428f0a594c1SAndy Whitcroft			}
5429773647a0SAndy Whitcroft
5430773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5431773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5432773647a0SAndy Whitcroft
5433cf655043SAndy Whitcroft			# Check the condition.
5434cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5435773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5436cf655043SAndy Whitcroft			if (defined $cond) {
5437773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5438cf655043SAndy Whitcroft			}
5439cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5440cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5441cf655043SAndy Whitcroft				$allowed = 1;
5442cf655043SAndy Whitcroft			}
5443cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5444cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5445cf655043SAndy Whitcroft				$allowed = 1;
5446cf655043SAndy Whitcroft			}
5447cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5448cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5449cf655043SAndy Whitcroft				$allowed = 1;
5450cf655043SAndy Whitcroft			}
5451cf655043SAndy Whitcroft			# Check the post-context.
5452cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5453cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5454cf655043SAndy Whitcroft				if (defined $cond) {
5455773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5456cf655043SAndy Whitcroft				}
5457cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5458cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5459cf655043SAndy Whitcroft					$allowed = 1;
5460cf655043SAndy Whitcroft				}
5461cf655043SAndy Whitcroft			}
5462cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5463f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5464e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5465cf655043SAndy Whitcroft
5466000d1cc1SJoe Perches				WARN("BRACES",
5467000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5468f0a594c1SAndy Whitcroft			}
5469f0a594c1SAndy Whitcroft		}
5470f0a594c1SAndy Whitcroft
5471e4c5babdSJoe Perches# check for single line unbalanced braces
547295330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
547395330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5474e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5475e4c5babdSJoe Perches		}
5476e4c5babdSJoe Perches
54770979ae66SJoe Perches# check for unnecessary blank lines around braces
547877b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5479f8e58219SJoe Perches			if (CHK("BRACES",
5480f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5481f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5482f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5483f8e58219SJoe Perches			}
54840979ae66SJoe Perches		}
548577b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5486f8e58219SJoe Perches			if (CHK("BRACES",
5487f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5488f8e58219SJoe Perches			    $fix) {
5489f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5490f8e58219SJoe Perches			}
54910979ae66SJoe Perches		}
54920979ae66SJoe Perches
54934a0df2efSAndy Whitcroft# no volatiles please
54946c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
54956c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5496000d1cc1SJoe Perches			WARN("VOLATILE",
54978c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
54984a0df2efSAndy Whitcroft		}
54994a0df2efSAndy Whitcroft
55005e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
55015e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
55025e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
55035e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
550433acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
55055e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
55065e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
55075e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
55085e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
55095e4f6ba5SJoe Perches				     $fix &&
55105e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
55115e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
55125e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
55135e4f6ba5SJoe Perches				my $comma_close = "";
55145e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
55155e4f6ba5SJoe Perches					$comma_close = $1;
55165e4f6ba5SJoe Perches				}
55175e4f6ba5SJoe Perches
55185e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
55195e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
55205e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
55215e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
55225e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
55235e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
55245e4f6ba5SJoe Perches				$fixedline = $rawline;
55255e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
55265e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
55275e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55285e4f6ba5SJoe Perches				}
55295e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
55305e4f6ba5SJoe Perches			}
55315e4f6ba5SJoe Perches		}
55325e4f6ba5SJoe Perches
55335e4f6ba5SJoe Perches# check for missing a space in a string concatenation
55345e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
55355e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
55365e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
55375e4f6ba5SJoe Perches		}
55385e4f6ba5SJoe Perches
553977cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5540e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5541e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5542e4b7d309SJoe Perches# function declarations
554377cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
554477cb8546SJoe Perches		    defined($context_function) &&
5545e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5546e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
554777cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5548e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
554977cb8546SJoe Perches		}
555077cb8546SJoe Perches
55515e4f6ba5SJoe Perches# check for spaces before a quoted newline
55525e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
55535e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
55545e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
55555e4f6ba5SJoe Perches			    $fix) {
55565e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
55575e4f6ba5SJoe Perches			}
55585e4f6ba5SJoe Perches
55595e4f6ba5SJoe Perches		}
55605e4f6ba5SJoe Perches
5561f17dba4fSJoe Perches# concatenated string without spaces between elements
556279682c0cSJoe Perches		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
556379682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
556479682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
556579682c0cSJoe Perches			    $fix) {
556679682c0cSJoe Perches				while ($line =~ /($String)/g) {
556779682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
556879682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
556979682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
557079682c0cSJoe Perches				}
557179682c0cSJoe Perches			}
5572f17dba4fSJoe Perches		}
5573f17dba4fSJoe Perches
557490ad30e5SJoe Perches# uncoalesced string fragments
557533acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
557679682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
557779682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
557879682c0cSJoe Perches			    $fix) {
557979682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
558079682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
558179682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
558279682c0cSJoe Perches				}
558379682c0cSJoe Perches			}
558490ad30e5SJoe Perches		}
558590ad30e5SJoe Perches
5586522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5587522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5588522b837cSAlexey Dobriyan		my $show_Z = 1;
55895e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5590522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
55915e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5592522b837cSAlexey Dobriyan			# check for %L
5593522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
55945e4f6ba5SJoe Perches				WARN("PRINTF_L",
5595522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5596522b837cSAlexey Dobriyan				$show_L = 0;
55975e4f6ba5SJoe Perches			}
5598522b837cSAlexey Dobriyan			# check for %Z
5599522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5600522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5601522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5602522b837cSAlexey Dobriyan				$show_Z = 0;
5603522b837cSAlexey Dobriyan			}
5604522b837cSAlexey Dobriyan			# check for 0x<decimal>
5605522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5606522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
56076e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
56086e300757SJoe Perches			}
56095e4f6ba5SJoe Perches		}
56105e4f6ba5SJoe Perches
56115e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
56123f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
56135e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
56145e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
56155e4f6ba5SJoe Perches		}
56165e4f6ba5SJoe Perches
561700df344fSAndy Whitcroft# warn about #if 0
5618c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
561960f89010SPrakruthi Deepak Heragu			WARN("IF_0",
562060f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
562160f89010SPrakruthi Deepak Heragu		}
562260f89010SPrakruthi Deepak Heragu
562360f89010SPrakruthi Deepak Heragu# warn about #if 1
562460f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
562560f89010SPrakruthi Deepak Heragu			WARN("IF_1",
562660f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
56274a0df2efSAndy Whitcroft		}
56284a0df2efSAndy Whitcroft
562903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
563003df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5631100425deSJoe Perches			my $tested = quotemeta($1);
5632100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5633100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5634100425deSJoe Perches				my $func = $1;
5635100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5636100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5637100425deSJoe Perches				    $fix) {
5638100425deSJoe Perches					my $do_fix = 1;
5639100425deSJoe Perches					my $leading_tabs = "";
5640100425deSJoe Perches					my $new_leading_tabs = "";
5641100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5642100425deSJoe Perches						$leading_tabs = $1;
5643100425deSJoe Perches					} else {
5644100425deSJoe Perches						$do_fix = 0;
5645100425deSJoe Perches					}
5646100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5647100425deSJoe Perches						$new_leading_tabs = $1;
5648100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5649100425deSJoe Perches							$do_fix = 0;
5650100425deSJoe Perches						}
5651100425deSJoe Perches					} else {
5652100425deSJoe Perches						$do_fix = 0;
5653100425deSJoe Perches					}
5654100425deSJoe Perches					if ($do_fix) {
5655100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5656100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5657100425deSJoe Perches					}
5658100425deSJoe Perches				}
56594c432a8fSGreg Kroah-Hartman			}
56604c432a8fSGreg Kroah-Hartman		}
5661f0a594c1SAndy Whitcroft
5662ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5663ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5664ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5665ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5666ebfdc409SJoe Perches		    $linenr > 3) {
5667ebfdc409SJoe Perches			my $testval = $2;
5668ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5669ebfdc409SJoe Perches
5670ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5671ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5672ebfdc409SJoe Perches
5673e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5674e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
5675ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5676ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5677ebfdc409SJoe Perches			}
5678ebfdc409SJoe Perches		}
5679ebfdc409SJoe Perches
5680f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5681dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5682f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5683f78d98f6SJoe Perches			my $level = $1;
5684f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5685f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5686f78d98f6SJoe Perches			    $fix) {
5687f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5688f78d98f6SJoe Perches			}
5689f78d98f6SJoe Perches		}
5690f78d98f6SJoe Perches
569145c55e92SJoe Perches# check for logging continuations
569245c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
569345c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
569445c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
569545c55e92SJoe Perches		}
569645c55e92SJoe Perches
5697abb08a53SJoe Perches# check for mask then right shift without a parentheses
56985b57980dSJoe Perches		if ($perl_version_ok &&
5699abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5700abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5701abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5702abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5703abb08a53SJoe Perches		}
5704abb08a53SJoe Perches
5705b75ac618SJoe Perches# check for pointer comparisons to NULL
57065b57980dSJoe Perches		if ($perl_version_ok) {
5707b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5708b75ac618SJoe Perches				my $val = $1;
5709b75ac618SJoe Perches				my $equal = "!";
5710b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5711b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5712b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5713b75ac618SJoe Perches					    $fix) {
5714b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5715b75ac618SJoe Perches				}
5716b75ac618SJoe Perches			}
5717b75ac618SJoe Perches		}
5718b75ac618SJoe Perches
57198716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
57208716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
57218716de38SJoe Perches			my $attr = $1;
57228716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
57238716de38SJoe Perches				my $ptr = $1;
57248716de38SJoe Perches				my $var = $2;
57258716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
57268716de38SJoe Perches				      ERROR("MISPLACED_INIT",
57278716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
57288716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
57298716de38SJoe Perches				      WARN("MISPLACED_INIT",
57308716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
57318716de38SJoe Perches				    $fix) {
5732194f66fcSJoe 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;
57338716de38SJoe Perches				}
57348716de38SJoe Perches			}
57358716de38SJoe Perches		}
57368716de38SJoe Perches
5737e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5738e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5739e970b884SJoe Perches			my $attr = $1;
5740e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5741e970b884SJoe Perches			my $attr_prefix = $1;
5742e970b884SJoe Perches			my $attr_type = $2;
5743e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5744e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5745e970b884SJoe Perches			    $fix) {
5746194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5747e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5748e970b884SJoe Perches			}
5749e970b884SJoe Perches		}
5750e970b884SJoe Perches
5751e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5752e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5753e970b884SJoe Perches			my $attr = $1;
5754e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5755e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5756e970b884SJoe Perches			    $fix) {
5757194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5758e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5759e970b884SJoe Perches				$lead = rtrim($1);
5760e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5761e970b884SJoe Perches				$lead = "${lead}const ";
5762194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5763e970b884SJoe Perches			}
5764e970b884SJoe Perches		}
5765e970b884SJoe Perches
5766c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5767c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5768c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5769c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5770c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5771c17893c7SJoe Perches			    $fix) {
5772c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5773c17893c7SJoe Perches			}
5774c17893c7SJoe Perches		}
5775c17893c7SJoe Perches
5776fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5777fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5778fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5779fbdb8138SJoe Perches			my $constant_func = $1;
5780fbdb8138SJoe Perches			my $func = $constant_func;
5781fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5782fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5783fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5784fbdb8138SJoe Perches			    $fix) {
5785194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5786fbdb8138SJoe Perches			}
5787fbdb8138SJoe Perches		}
5788fbdb8138SJoe Perches
57891a15a250SPatrick Pannuto# prefer usleep_range over udelay
579037581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
579143c1d77cSJoe Perches			my $delay = $1;
57921a15a250SPatrick Pannuto			# ignore udelay's < 10, however
579343c1d77cSJoe Perches			if (! ($delay < 10) ) {
5794000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
5795458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
579643c1d77cSJoe Perches			}
579743c1d77cSJoe Perches			if ($delay > 2000) {
579843c1d77cSJoe Perches				WARN("LONG_UDELAY",
579943c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
58001a15a250SPatrick Pannuto			}
58011a15a250SPatrick Pannuto		}
58021a15a250SPatrick Pannuto
580309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
580409ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
580509ef8725SPatrick Pannuto			if ($1 < 20) {
5806000d1cc1SJoe Perches				WARN("MSLEEP",
5807458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
580809ef8725SPatrick Pannuto			}
580909ef8725SPatrick Pannuto		}
581009ef8725SPatrick Pannuto
581136ec1939SJoe Perches# check for comparisons of jiffies
581236ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
581336ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
581436ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
581536ec1939SJoe Perches		}
581636ec1939SJoe Perches
58179d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
58189d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
58199d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
58209d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
58219d7a34a5SJoe Perches		}
58229d7a34a5SJoe Perches
582300df344fSAndy Whitcroft# warn about #ifdefs in C files
5824c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
582500df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
582600df344fSAndy Whitcroft#			print "$herecurr";
582700df344fSAndy Whitcroft#			$clean = 0;
582800df344fSAndy Whitcroft#		}
582900df344fSAndy Whitcroft
583022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5831c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
58323705ce5bSJoe Perches			if (ERROR("SPACING",
58333705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
58343705ce5bSJoe Perches			    $fix) {
5835194f66fcSJoe Perches				$fixed[$fixlinenr] =~
58363705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
58373705ce5bSJoe Perches			}
58383705ce5bSJoe Perches
583922f2a2efSAndy Whitcroft		}
584022f2a2efSAndy Whitcroft
58414a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5842171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5843171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
58444a0df2efSAndy Whitcroft			my $which = $1;
58454a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5846000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5847000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
58484a0df2efSAndy Whitcroft			}
58494a0df2efSAndy Whitcroft		}
58504a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5851402c2553SMichael S. Tsirkin
5852402c2553SMichael S. Tsirkin		my $barriers = qr{
5853402c2553SMichael S. Tsirkin			mb|
5854402c2553SMichael S. Tsirkin			rmb|
5855402c2553SMichael S. Tsirkin			wmb|
5856402c2553SMichael S. Tsirkin			read_barrier_depends
5857402c2553SMichael S. Tsirkin		}x;
5858402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5859402c2553SMichael S. Tsirkin			mb__before_atomic|
5860402c2553SMichael S. Tsirkin			mb__after_atomic|
5861402c2553SMichael S. Tsirkin			store_release|
5862402c2553SMichael S. Tsirkin			load_acquire|
5863402c2553SMichael S. Tsirkin			store_mb|
5864402c2553SMichael S. Tsirkin			(?:$barriers)
5865402c2553SMichael S. Tsirkin		}x;
5866402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5867402c2553SMichael S. Tsirkin			(?:$barriers)|
586843e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
586943e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5870402c2553SMichael S. Tsirkin		}x;
5871402c2553SMichael S. Tsirkin
5872402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
58734a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5874c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5875000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
58764a0df2efSAndy Whitcroft			}
58774a0df2efSAndy Whitcroft		}
58783ad81779SPaul E. McKenney
5879f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5880f4073b0fSMichael S. Tsirkin
5881f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5882f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5883f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5884f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5885f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5886f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5887f4073b0fSMichael S. Tsirkin		}
5888f4073b0fSMichael S. Tsirkin
5889cb426e99SJoe Perches# check for waitqueue_active without a comment.
5890cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5891cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5892cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5893cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5894cb426e99SJoe Perches			}
5895cb426e99SJoe Perches		}
58963ad81779SPaul E. McKenney
589791db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends
589891db2592SPaul E. McKenney		if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
589991db2592SPaul E. McKenney			WARN("READ_BARRIER_DEPENDS",
590091db2592SPaul E. McKenney			     "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
590191db2592SPaul E. McKenney		}
590291db2592SPaul E. McKenney
59034a0df2efSAndy Whitcroft# check of hardware specific defines
5904c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5905000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5906000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
59070a920b5bSAndy Whitcroft		}
5908653d4876SAndy Whitcroft
5909596ed45bSJoe Perches# check that the storage class is not after a type
5910596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
5911000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5912596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
5913596ed45bSJoe Perches		}
5914596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
5915596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
5916596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
5917596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
5918596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
5919596ed45bSJoe Perches			WARN("STORAGE_CLASS",
5920596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
5921d4977c78STobias Klauser		}
5922d4977c78STobias Klauser
5923de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5924de7d4f0eSAndy Whitcroft# storage class and type.
59259c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
59269c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5927000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5928000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5929de7d4f0eSAndy Whitcroft		}
5930de7d4f0eSAndy Whitcroft
59318905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
59322b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59332b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5934d5e616fcSJoe Perches			if (WARN("INLINE",
5935d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5936d5e616fcSJoe Perches			    $fix) {
5937194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5938d5e616fcSJoe Perches
5939d5e616fcSJoe Perches			}
59408905a67cSAndy Whitcroft		}
59418905a67cSAndy Whitcroft
59423d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
59432b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59442b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5945000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5946000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
59473d130fd0SJoe Perches		}
59483d130fd0SJoe Perches
594939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
59502b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59512b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5952000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5953000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
595439b7e287SJoe Perches		}
595539b7e287SJoe Perches
5956462811d9SJoe Perches# Check for __attribute__ section, prefer __section
5957462811d9SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5958462811d9SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
5959462811d9SJoe Perches			my $old = substr($rawline, $-[1], $+[1] - $-[1]);
5960462811d9SJoe Perches			my $new = substr($old, 1, -1);
5961462811d9SJoe Perches			if (WARN("PREFER_SECTION",
5962462811d9SJoe Perches				 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
5963462811d9SJoe Perches			    $fix) {
5964462811d9SJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
5965462811d9SJoe Perches			}
5966462811d9SJoe Perches		}
5967462811d9SJoe Perches
59685f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
59692b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59702b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5971d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5972d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5973d5e616fcSJoe Perches			    $fix) {
5974194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5975d5e616fcSJoe Perches
5976d5e616fcSJoe Perches			}
59775f14d3bdSJoe Perches		}
59785f14d3bdSJoe Perches
59796061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
59802b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59812b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5982d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5983d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5984d5e616fcSJoe Perches			    $fix) {
5985194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5986d5e616fcSJoe Perches			}
59876061d949SJoe Perches		}
59886061d949SJoe Perches
5989619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
59905b57980dSJoe Perches		if ($perl_version_ok &&
5991619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5992619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5993619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5994619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5995619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5996619a908aSJoe Perches		}
5997619a908aSJoe Perches
5998fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5999e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6000fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6001e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6002e6176fa4SJoe Perches			my $type = $1;
6003e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6004e6176fa4SJoe Perches				$type = $1;
6005e6176fa4SJoe Perches				my $kernel_type = 'u';
6006e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6007e6176fa4SJoe Perches				$type =~ /(\d+)/;
6008e6176fa4SJoe Perches				$kernel_type .= $1;
6009e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6010e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6011e6176fa4SJoe Perches				    $fix) {
6012e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6013e6176fa4SJoe Perches				}
6014e6176fa4SJoe Perches			}
6015e6176fa4SJoe Perches		}
6016e6176fa4SJoe Perches
6017938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6018938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6019938224b5SJoe Perches			my $cast = $1;
6020938224b5SJoe Perches			my $const = $2;
6021938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
6022938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
6023938224b5SJoe Perches			    $fix) {
6024938224b5SJoe Perches				my $suffix = "";
6025938224b5SJoe Perches				my $newconst = $const;
6026938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
6027938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6028938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
6029938224b5SJoe Perches					$suffix .= 'LL';
6030938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
6031938224b5SJoe Perches					$suffix .= 'L';
6032938224b5SJoe Perches				}
6033938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6034938224b5SJoe Perches			}
6035938224b5SJoe Perches		}
6036938224b5SJoe Perches
60378f53a9b8SJoe Perches# check for sizeof(&)
60388f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6039000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6040000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
60418f53a9b8SJoe Perches		}
60428f53a9b8SJoe Perches
604366c80b60SJoe Perches# check for sizeof without parenthesis
604466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6045d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6046d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6047d5e616fcSJoe Perches			    $fix) {
6048194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6049d5e616fcSJoe Perches			}
605066c80b60SJoe Perches		}
605166c80b60SJoe Perches
605288982feaSJoe Perches# check for struct spinlock declarations
605388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
605488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
605588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
605688982feaSJoe Perches		}
605788982feaSJoe Perches
6058a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
605906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6060a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6061caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6062caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6063d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6064d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6065d5e616fcSJoe Perches				    $fix) {
6066194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6067d5e616fcSJoe Perches				}
6068a6962d72SJoe Perches			}
6069a6962d72SJoe Perches		}
6070a6962d72SJoe Perches
60710b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
60725b57980dSJoe Perches		if ($perl_version_ok &&
60730b523769SJoe Perches		    defined $stat &&
60740b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
60750b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6076e3c6bc95STobin C. Harding			my $stat_real;
6077e3c6bc95STobin C. Harding
60780b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
60790b523769SJoe Perches			$lc = $lc + $linenr;
60800b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6081ffe07513SJoe Perches				my $specifier;
6082ffe07513SJoe Perches				my $extension;
60833bd32d6aSSakari Ailus				my $qualifier;
6084ffe07513SJoe Perches				my $bad_specifier = "";
60850b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
60860b523769SJoe Perches				$fmt =~ s/%%//g;
6087e3c6bc95STobin C. Harding
60883bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6089e3c6bc95STobin C. Harding					$specifier = $1;
6090e3c6bc95STobin C. Harding					$extension = $2;
60913bd32d6aSSakari Ailus					$qualifier = $3;
6092361b0d28SLinus Torvalds					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
60933bd32d6aSSakari Ailus					    ($extension eq "f" &&
60943bd32d6aSSakari Ailus					     defined $qualifier && $qualifier !~ /^w/)) {
6095e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
60960b523769SJoe Perches						last;
60970b523769SJoe Perches					}
6098e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6099e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6100e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
61010b523769SJoe Perches						}
6102e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6103e3c6bc95STobin C. Harding						     "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
6104e3c6bc95STobin C. Harding					}
6105e3c6bc95STobin C. Harding				}
6106e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
61072a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
61081df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
61091df7338aSSergey Senozhatsky					my $use = "";
6110e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
61111df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6112e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
61131df7338aSSergey Senozhatsky					}
61142a9f9d85STobin C. Harding
61150b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6116e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6117e3c6bc95STobin C. Harding				}
61180b523769SJoe Perches			}
61190b523769SJoe Perches		}
61200b523769SJoe Perches
6121554e165cSAndy Whitcroft# Check for misused memsets
61225b57980dSJoe Perches		if ($perl_version_ok &&
6123d1fe9c09SJoe Perches		    defined $stat &&
61249e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6125554e165cSAndy Whitcroft
6126d7c76ba7SJoe Perches			my $ms_addr = $2;
6127d1fe9c09SJoe Perches			my $ms_val = $7;
6128d1fe9c09SJoe Perches			my $ms_size = $12;
6129d7c76ba7SJoe Perches
6130554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6131554e165cSAndy Whitcroft				ERROR("MEMSET",
6132d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6133554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6134554e165cSAndy Whitcroft				WARN("MEMSET",
6135d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6136d7c76ba7SJoe Perches			}
6137d7c76ba7SJoe Perches		}
6138d7c76ba7SJoe Perches
613998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
61405b57980dSJoe Perches#		if ($perl_version_ok &&
6141f333195dSJoe Perches#		    defined $stat &&
6142f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6143f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6144f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6145f333195dSJoe Perches#			    $fix) {
6146f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6147f333195dSJoe Perches#			}
6148f333195dSJoe Perches#		}
614998a9bba5SJoe Perches
6150b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
61515b57980dSJoe Perches#		if ($perl_version_ok &&
6152f333195dSJoe Perches#		    defined $stat &&
6153f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6154f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6155f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6156f333195dSJoe Perches#		}
6157b6117d17SMateusz Kulikowski
61588617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
61598617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
61605b57980dSJoe Perches#		if ($perl_version_ok &&
6161f333195dSJoe Perches#		    defined $stat &&
6162f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6163f333195dSJoe Perches#
6164f333195dSJoe Perches#			my $ms_val = $7;
6165f333195dSJoe Perches#
6166f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6167f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6168f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6169f333195dSJoe Perches#				    $fix) {
6170f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6171f333195dSJoe Perches#				}
6172f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6173f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6174f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6175f333195dSJoe Perches#				    $fix) {
6176f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6177f333195dSJoe Perches#				}
6178f333195dSJoe Perches#			}
6179f333195dSJoe Perches#		}
61808617cd09SMateusz Kulikowski
6181d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
61825b57980dSJoe Perches		if ($perl_version_ok &&
6183d1fe9c09SJoe Perches		    defined $stat &&
6184d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6185d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6186d7c76ba7SJoe Perches				my $call = $1;
6187d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6188d7c76ba7SJoe Perches				my $arg1 = $3;
6189d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6190d1fe9c09SJoe Perches				my $arg2 = $8;
6191d7c76ba7SJoe Perches				my $cast;
6192d7c76ba7SJoe Perches
6193d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6194d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6195d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6196d7c76ba7SJoe Perches					$cast = $cast1;
6197d7c76ba7SJoe Perches				} else {
6198d7c76ba7SJoe Perches					$cast = $cast2;
6199d7c76ba7SJoe Perches				}
6200d7c76ba7SJoe Perches				WARN("MINMAX",
6201d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6202554e165cSAndy Whitcroft			}
6203554e165cSAndy Whitcroft		}
6204554e165cSAndy Whitcroft
62054a273195SJoe Perches# check usleep_range arguments
62065b57980dSJoe Perches		if ($perl_version_ok &&
62074a273195SJoe Perches		    defined $stat &&
62084a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
62094a273195SJoe Perches			my $min = $1;
62104a273195SJoe Perches			my $max = $7;
62114a273195SJoe Perches			if ($min eq $max) {
62124a273195SJoe Perches				WARN("USLEEP_RANGE",
6213458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
62144a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
62154a273195SJoe Perches				 $min > $max) {
62164a273195SJoe Perches				WARN("USLEEP_RANGE",
6217458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
62184a273195SJoe Perches			}
62194a273195SJoe Perches		}
62204a273195SJoe Perches
6221823b794cSJoe Perches# check for naked sscanf
62225b57980dSJoe Perches		if ($perl_version_ok &&
6223823b794cSJoe Perches		    defined $stat &&
62246c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6225823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6226823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6227823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6228823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6229823b794cSJoe Perches			$lc = $lc + $linenr;
62302a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6231823b794cSJoe Perches			WARN("NAKED_SSCANF",
6232823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6233823b794cSJoe Perches		}
6234823b794cSJoe Perches
6235afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
62365b57980dSJoe Perches		if ($perl_version_ok &&
6237afc819abSJoe Perches		    defined $stat &&
6238afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6239afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6240afc819abSJoe Perches			$lc = $lc + $linenr;
62412a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6242afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6243afc819abSJoe Perches				my $format = $6;
6244afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6245afc819abSJoe Perches				if ($count == 1 &&
6246afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6247afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6248afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6249afc819abSJoe Perches				}
6250afc819abSJoe Perches			}
6251afc819abSJoe Perches		}
6252afc819abSJoe Perches
625370dc8a48SJoe Perches# check for new externs in .h files.
625470dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
625570dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6256d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
625770dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
625870dc8a48SJoe Perches			    $fix) {
6259194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
626070dc8a48SJoe Perches			}
626170dc8a48SJoe Perches		}
626270dc8a48SJoe Perches
6263de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6264171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6265c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6266171ae1a4SAndy Whitcroft		{
6267c45dcabdSAndy Whitcroft			my $function_name = $1;
6268c45dcabdSAndy Whitcroft			my $paren_space = $2;
6269171ae1a4SAndy Whitcroft
6270171ae1a4SAndy Whitcroft			my $s = $stat;
6271171ae1a4SAndy Whitcroft			if (defined $cond) {
6272171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6273171ae1a4SAndy Whitcroft			}
6274c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
6275c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
6276c45dcabdSAndy Whitcroft			{
6277000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6278000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6279de7d4f0eSAndy Whitcroft			}
6280de7d4f0eSAndy Whitcroft
6281171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6282000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6283000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6284171ae1a4SAndy Whitcroft			}
62859c9ba34eSAndy Whitcroft
62869c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
62879c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
62889c9ba34eSAndy Whitcroft		{
6289000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6290000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6291171ae1a4SAndy Whitcroft		}
6292171ae1a4SAndy Whitcroft
6293a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
629416b7f3c8SJoe Perches# while avoiding uninitialized_var(x)
6295a0ad7596SJoe Perches		if (defined $stat &&
629616b7f3c8SJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
629716b7f3c8SJoe Perches		    (!defined($1) ||
629816b7f3c8SJoe Perches		     (defined($1) && $1 ne "uninitialized_var")) &&
629916b7f3c8SJoe Perches		     $2 ne "void") {
630016b7f3c8SJoe Perches			my $args = trim($2);
6301ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6302ca0d8929SJoe Perches				my $arg = trim($1);
630316b7f3c8SJoe Perches				if ($arg =~ /^$Type$/ &&
630416b7f3c8SJoe Perches					$arg !~ /enum\s+$Ident$/) {
6305ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6306ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6307ca0d8929SJoe Perches				}
6308ca0d8929SJoe Perches			}
6309ca0d8929SJoe Perches		}
6310ca0d8929SJoe Perches
6311a0ad7596SJoe Perches# check for function definitions
63125b57980dSJoe Perches		if ($perl_version_ok &&
6313a0ad7596SJoe Perches		    defined $stat &&
6314a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6315a0ad7596SJoe Perches			$context_function = $1;
6316a0ad7596SJoe Perches
6317a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6318a0ad7596SJoe Perches			my $ok = 0;
6319a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6320a0ad7596SJoe Perches			my $herectx = $here . "\n";
6321a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6322a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6323a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6324a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6325a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6326a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6327a0ad7596SJoe Perches			}
6328a0ad7596SJoe Perches			if (!$ok) {
6329a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6330a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6331a0ad7596SJoe Perches			}
6332a0ad7596SJoe Perches		}
6333a0ad7596SJoe Perches
6334de7d4f0eSAndy Whitcroft# checks for new __setup's
6335de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6336de7d4f0eSAndy Whitcroft			my $name = $1;
6337de7d4f0eSAndy Whitcroft
6338de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6339000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
63408c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
6341de7d4f0eSAndy Whitcroft			}
6342653d4876SAndy Whitcroft		}
63439c0ca6f9SAndy Whitcroft
6344e29a70f1SJoe Perches# check for pointless casting of alloc functions
6345e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6346000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6347000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
63489c0ca6f9SAndy Whitcroft		}
634913214adfSAndy Whitcroft
6350a640d25cSJoe Perches# alloc style
6351a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
63525b57980dSJoe Perches		if ($perl_version_ok &&
6353e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6354a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6355a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6356a640d25cSJoe Perches		}
6357a640d25cSJoe Perches
635860a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
63595b57980dSJoe Perches		if ($perl_version_ok &&
63601b4a2ed4SJoe Perches		    defined $stat &&
63611b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
636260a55369SJoe Perches			my $oldfunc = $3;
636360a55369SJoe Perches			my $a1 = $4;
636460a55369SJoe Perches			my $a2 = $10;
636560a55369SJoe Perches			my $newfunc = "kmalloc_array";
636660a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
636760a55369SJoe Perches			my $r1 = $a1;
636860a55369SJoe Perches			my $r2 = $a2;
636960a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
637060a55369SJoe Perches				$r1 = $a2;
637160a55369SJoe Perches				$r2 = $a1;
637260a55369SJoe Perches			}
6373e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6374e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
63751b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6376e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6377e3d95a2aSTobin C. Harding
6378e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
63791b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
63801b4a2ed4SJoe Perches				    $cnt == 1 &&
6381e367455aSJoe Perches				    $fix) {
6382194f66fcSJoe 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;
638360a55369SJoe Perches				}
638460a55369SJoe Perches			}
638560a55369SJoe Perches		}
638660a55369SJoe Perches
6387972fdea2SJoe Perches# check for krealloc arg reuse
63885b57980dSJoe Perches		if ($perl_version_ok &&
63894cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
63904cab63ceSJoe Perches		    $1 eq $3) {
6391972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
6392972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6393972fdea2SJoe Perches		}
6394972fdea2SJoe Perches
63955ce59ae0SJoe Perches# check for alloc argument mismatch
63965ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
63975ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
63985ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
63995ce59ae0SJoe Perches		}
64005ce59ae0SJoe Perches
6401caf2a54fSJoe Perches# check for multiple semicolons
6402caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6403d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6404d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6405d5e616fcSJoe Perches			    $fix) {
6406194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6407d5e616fcSJoe Perches			}
6408d1e2ad07SJoe Perches		}
6409d1e2ad07SJoe Perches
6410cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6411cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6412cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
64130ab90191SJoe Perches			my $ull = "";
64140ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
64150ab90191SJoe Perches			if (CHK("BIT_MACRO",
64160ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
64170ab90191SJoe Perches			    $fix) {
64180ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
64190ab90191SJoe Perches			}
64200ab90191SJoe Perches		}
64210ab90191SJoe Perches
64222d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
64232d632745SJoe 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*$/) {
64242d632745SJoe Perches			my $config = $1;
64252d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
64262d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
64272d632745SJoe Perches			    $fix) {
64282d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
64292d632745SJoe Perches			}
64302d632745SJoe Perches		}
64312d632745SJoe Perches
6432e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6433c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6434c34c09a8SJoe Perches			my $has_break = 0;
6435c34c09a8SJoe Perches			my $has_statement = 0;
6436c34c09a8SJoe Perches			my $count = 0;
6437c34c09a8SJoe Perches			my $prevline = $linenr;
6438e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6439c34c09a8SJoe Perches				$prevline--;
6440c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6441c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6442c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6443c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6444c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6445c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6446c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6447c34c09a8SJoe Perches				$has_statement = 1;
6448c34c09a8SJoe Perches				$count++;
6449258f79d5SHeinrich Schuchardt				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
6450c34c09a8SJoe Perches			}
6451c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6452c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6453224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6454c34c09a8SJoe Perches			}
6455c34c09a8SJoe Perches		}
6456c34c09a8SJoe Perches
6457f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
6458f36d3eb8SJoe Perches		my @fallthroughs = (
6459f36d3eb8SJoe Perches			'fallthrough',
6460f36d3eb8SJoe Perches			'@fallthrough@',
6461f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
6462f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6463f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6464f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6465f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6466f36d3eb8SJoe Perches		    );
6467f36d3eb8SJoe Perches		if ($raw_comment ne '') {
6468f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
6469f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
6470f36d3eb8SJoe Perches					my $msg_level = \&WARN;
6471f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
6472f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
6473f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6474f36d3eb8SJoe Perches					last;
6475f36d3eb8SJoe Perches				}
6476f36d3eb8SJoe Perches			}
6477f36d3eb8SJoe Perches		}
6478f36d3eb8SJoe Perches
6479d1e2ad07SJoe Perches# check for switch/default statements without a break;
64805b57980dSJoe Perches		if ($perl_version_ok &&
6481d1e2ad07SJoe Perches		    defined $stat &&
6482d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6483d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6484e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
6485e3d95a2aSTobin C. Harding
6486d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6487d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6488caf2a54fSJoe Perches		}
6489caf2a54fSJoe Perches
649013214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6491d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6492d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6493d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6494d5e616fcSJoe Perches			    $fix) {
6495194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6496d5e616fcSJoe Perches			}
649713214adfSAndy Whitcroft		}
6498773647a0SAndy Whitcroft
649962ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
650062ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
650162ec818fSJoe Perches			ERROR("DATE_TIME",
650262ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
650362ec818fSJoe Perches		}
650462ec818fSJoe Perches
65052c92488aSJoe Perches# check for use of yield()
65062c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
65072c92488aSJoe Perches			WARN("YIELD",
65082c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
65092c92488aSJoe Perches		}
65102c92488aSJoe Perches
6511179f8f40SJoe Perches# check for comparisons against true and false
6512179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6513179f8f40SJoe Perches			my $lead = $1;
6514179f8f40SJoe Perches			my $arg = $2;
6515179f8f40SJoe Perches			my $test = $3;
6516179f8f40SJoe Perches			my $otype = $4;
6517179f8f40SJoe Perches			my $trail = $5;
6518179f8f40SJoe Perches			my $op = "!";
6519179f8f40SJoe Perches
6520179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6521179f8f40SJoe Perches
6522179f8f40SJoe Perches			my $type = lc($otype);
6523179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6524179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6525179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6526179f8f40SJoe Perches					$op = "";
6527179f8f40SJoe Perches				}
6528179f8f40SJoe Perches
6529179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6530179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6531179f8f40SJoe Perches
6532179f8f40SJoe Perches## maybe suggesting a correct construct would better
6533179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6534179f8f40SJoe Perches
6535179f8f40SJoe Perches			}
6536179f8f40SJoe Perches		}
6537179f8f40SJoe Perches
65384882720bSThomas Gleixner# check for semaphores initialized locked
65394882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6540000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6541000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6542773647a0SAndy Whitcroft		}
65436712d858SJoe Perches
654467d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
654567d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6546000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
654767d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6548773647a0SAndy Whitcroft		}
65496712d858SJoe Perches
6550ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6551f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6552000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6553ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6554f3db6639SMichael Ellerman		}
65556712d858SJoe Perches
65563d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
65573d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
65583d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
65593d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
65603d709ab5SPaul E. McKenney		}
65613d709ab5SPaul E. McKenney
65629189c7e7SJoe Perches# check for deprecated apis
65639189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
65649189c7e7SJoe Perches			my $deprecated_api = $1;
65659189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
65669189c7e7SJoe Perches			WARN("DEPRECATED_API",
65679189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
65689189c7e7SJoe Perches		}
65699189c7e7SJoe Perches
65700f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6571d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
65726903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6573d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6574000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6575d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
65762b6db5cbSAndy Whitcroft		}
6577773647a0SAndy Whitcroft
6578773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6579773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6580773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6581c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6582c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6583171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6584171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6585171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6586773647a0SAndy Whitcroft		{
6587000d1cc1SJoe Perches			WARN("NR_CPUS",
6588000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6589773647a0SAndy Whitcroft		}
65909c9ba34eSAndy Whitcroft
659152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
659252ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
659352ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
659452ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
659552ea8506SJoe Perches		}
659652ea8506SJoe Perches
6597acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
65985b57980dSJoe Perches		if ($perl_version_ok &&
6599acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6600acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6601acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6602acd9362cSJoe Perches		}
6603acd9362cSJoe Perches
6604de3f186fSDenis Efremov# nested likely/unlikely calls
6605de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
6606de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
6607de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
6608de3f186fSDenis Efremov		}
6609de3f186fSDenis Efremov
6610691d77b6SAndy Whitcroft# whine mightly about in_atomic
6611691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6612691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6613000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6614000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6615f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6616000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6617000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6618691d77b6SAndy Whitcroft			}
6619691d77b6SAndy Whitcroft		}
66201704f47bSPeter Zijlstra
66210f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
66220f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
66230f5225b0SPeter Zijlstra			ERROR("LOCKING",
66240f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
66250f5225b0SPeter Zijlstra		}
66260f5225b0SPeter Zijlstra
66271704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
66281704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
66291704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
66301704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
66311704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
66321704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6633000d1cc1SJoe Perches				ERROR("LOCKDEP",
6634000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
66351704f47bSPeter Zijlstra			}
66361704f47bSPeter Zijlstra		}
663788f8831cSDave Jones
6638b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6639b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6640000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6641000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
664288f8831cSDave Jones		}
66432435880fSJoe Perches
664400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
664500180468SJoe Perches# and whether or not function naming is typical and if
664600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
66475b57980dSJoe Perches		if ($perl_version_ok &&
664800180468SJoe Perches		    defined $stat &&
664900180468SJoe Perches		    $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
665000180468SJoe Perches			my $var = $1;
665100180468SJoe Perches			my $perms = $2;
665200180468SJoe Perches			my $show = $3;
665300180468SJoe Perches			my $store = $4;
665400180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
665500180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
665600180468SJoe Perches			    $store =~ /^${var}_store$/ &&
665700180468SJoe Perches			    $octal_perms eq "0644") {
665800180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
665900180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
666000180468SJoe Perches				    $fix) {
666100180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
666200180468SJoe Perches				}
666300180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
666400180468SJoe Perches				 $store =~ /^NULL$/ &&
666500180468SJoe Perches				 $octal_perms eq "0444") {
666600180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
666700180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
666800180468SJoe Perches				    $fix) {
666900180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
667000180468SJoe Perches				}
667100180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
667200180468SJoe Perches				 $store =~ /^${var}_store$/ &&
667300180468SJoe Perches				 $octal_perms eq "0200") {
667400180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
667500180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
667600180468SJoe Perches				    $fix) {
667700180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
667800180468SJoe Perches				}
667900180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
668000180468SJoe Perches				 $octal_perms eq "0444" ||
668100180468SJoe Perches				 $octal_perms eq "0200") {
668200180468SJoe Perches				my $newshow = "$show";
668300180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
668400180468SJoe Perches				my $newstore = $store;
668500180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
668600180468SJoe Perches				my $rename = "";
668700180468SJoe Perches				if ($show ne $newshow) {
668800180468SJoe Perches					$rename .= " '$show' to '$newshow'";
668900180468SJoe Perches				}
669000180468SJoe Perches				if ($store ne $newstore) {
669100180468SJoe Perches					$rename .= " '$store' to '$newstore'";
669200180468SJoe Perches				}
669300180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
669400180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
669500180468SJoe Perches			} else {
669600180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
669700180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
669800180468SJoe Perches			}
669900180468SJoe Perches		}
670000180468SJoe Perches
6701515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6702515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
670373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
670473121534SJoe Perches#   specific definition of not visible in sysfs.
670573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
670673121534SJoe Perches#   use the default permissions
67075b57980dSJoe Perches		if ($perl_version_ok &&
6708459cf0aeSJoe Perches		    defined $stat &&
6709515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
67102435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
67112435880fSJoe Perches				my $func = $entry->[0];
67122435880fSJoe Perches				my $arg_pos = $entry->[1];
67132435880fSJoe Perches
6714459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6715459cf0aeSJoe Perches				$lc = $lc + $linenr;
67162a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
6717459cf0aeSJoe Perches
67182435880fSJoe Perches				my $skip_args = "";
67192435880fSJoe Perches				if ($arg_pos > 1) {
67202435880fSJoe Perches					$arg_pos--;
67212435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
67222435880fSJoe Perches				}
6723f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6724459cf0aeSJoe Perches				if ($stat =~ /$test/) {
67252435880fSJoe Perches					my $val = $1;
67262435880fSJoe Perches					$val = $6 if ($skip_args ne "");
672773121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
672873121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
672973121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
67302435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6731459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6732f90774e1SJoe Perches					}
6733f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6734c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6735459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
67362435880fSJoe Perches					}
6737459cf0aeSJoe Perches				}
6738459cf0aeSJoe Perches			}
6739459cf0aeSJoe Perches		}
6740459cf0aeSJoe Perches
6741459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6742bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
674300180468SJoe Perches			my $oval = $1;
674400180468SJoe Perches			my $octal = perms_to_octal($oval);
6745f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6746459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6747f90774e1SJoe Perches			    $fix) {
674800180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
67492435880fSJoe Perches			}
675013214adfSAndy Whitcroft		}
67515a6d20ceSBjorn Andersson
67525a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
67535a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
67545a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
67555a6d20ceSBjorn Andersson			my $valid_licenses = qr{
67565a6d20ceSBjorn Andersson						GPL|
67575a6d20ceSBjorn Andersson						GPL\ v2|
67585a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
67595a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
67605a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
67615a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
67625a6d20ceSBjorn Andersson						Proprietary
67635a6d20ceSBjorn Andersson					}x;
67645a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
67655a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
67665a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
67675a6d20ceSBjorn Andersson			}
67685a6d20ceSBjorn Andersson		}
67696a8d76cbSMatteo Croce
67706a8d76cbSMatteo Croce# check for sysctl duplicate constants
67716a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
67726a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
67736a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
67746a8d76cbSMatteo Croce		}
6775515a235eSJoe Perches	}
677613214adfSAndy Whitcroft
677713214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
677813214adfSAndy Whitcroft	# so just keep quiet.
677913214adfSAndy Whitcroft	if ($#rawlines == -1) {
678013214adfSAndy Whitcroft		exit(0);
67810a920b5bSAndy Whitcroft	}
67820a920b5bSAndy Whitcroft
67838905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
67848905a67cSAndy Whitcroft	# things that appear to be patches.
67858905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
67868905a67cSAndy Whitcroft		exit(0);
67878905a67cSAndy Whitcroft	}
67888905a67cSAndy Whitcroft
67898905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
67908905a67cSAndy Whitcroft	# just keep quiet.
67918905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
67928905a67cSAndy Whitcroft		exit(0);
67938905a67cSAndy Whitcroft	}
67948905a67cSAndy Whitcroft
6795a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
6796000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6797000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
67980a920b5bSAndy Whitcroft	}
6799cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
6800cd261496SGeert Uytterhoeven		if ($signoff == 0) {
6801000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
6802000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
6803cd261496SGeert Uytterhoeven		} elsif (!$authorsignoff) {
6804cd261496SGeert Uytterhoeven			WARN("NO_AUTHOR_SIGN_OFF",
6805cd261496SGeert Uytterhoeven			     "Missing Signed-off-by: line by nominal patch author '$author'\n");
6806cd261496SGeert Uytterhoeven		}
68070a920b5bSAndy Whitcroft	}
68080a920b5bSAndy Whitcroft
6809f0a594c1SAndy Whitcroft	print report_dump();
681013214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
681113214adfSAndy Whitcroft		print "$filename " if ($summary_file);
68126c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
68136c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
68146c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
68156c72ffaaSAndy Whitcroft	}
68168905a67cSAndy Whitcroft
6817d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6818ef212196SJoe Perches		# If there were any defects found and not already fixing them
6819ef212196SJoe Perches		if (!$clean and !$fix) {
6820ef212196SJoe Perches			print << "EOM"
6821ef212196SJoe Perches
6822ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6823ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6824ef212196SJoe PerchesEOM
6825ef212196SJoe Perches		}
6826d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6827d2c0a235SAndy Whitcroft		# then suggest that.
6828d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6829b0781216SMike Frysinger			$rpt_cleaners = 0;
6830d8469f16SJoe Perches			print << "EOM"
6831d8469f16SJoe Perches
6832d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6833d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6834d8469f16SJoe PerchesEOM
6835d2c0a235SAndy Whitcroft		}
6836d2c0a235SAndy Whitcroft	}
6837d2c0a235SAndy Whitcroft
6838d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6839d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6840d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
68419624b8d6SJoe Perches		my $newfile = $filename;
68429624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
68433705ce5bSJoe Perches		my $linecount = 0;
68443705ce5bSJoe Perches		my $f;
68453705ce5bSJoe Perches
6846d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6847d752fcc8SJoe Perches
68483705ce5bSJoe Perches		open($f, '>', $newfile)
68493705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
68503705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
68513705ce5bSJoe Perches			$linecount++;
68523705ce5bSJoe Perches			if ($file) {
68533705ce5bSJoe Perches				if ($linecount > 3) {
68543705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
68553705ce5bSJoe Perches					print $f $fixed_line . "\n";
68563705ce5bSJoe Perches				}
68573705ce5bSJoe Perches			} else {
68583705ce5bSJoe Perches				print $f $fixed_line . "\n";
68593705ce5bSJoe Perches			}
68603705ce5bSJoe Perches		}
68613705ce5bSJoe Perches		close($f);
68623705ce5bSJoe Perches
68633705ce5bSJoe Perches		if (!$quiet) {
68643705ce5bSJoe Perches			print << "EOM";
6865d8469f16SJoe Perches
68663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
68673705ce5bSJoe Perches
68683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
68693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
68703705ce5bSJoe Perches
68713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
68723705ce5bSJoe PerchesNo warranties, expressed or implied...
68733705ce5bSJoe PerchesEOM
68743705ce5bSJoe Perches		}
68753705ce5bSJoe Perches	}
68763705ce5bSJoe Perches
6877d8469f16SJoe Perches	if ($quiet == 0) {
6878d8469f16SJoe Perches		print "\n";
6879d8469f16SJoe Perches		if ($clean == 1) {
6880d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6881d8469f16SJoe Perches		} else {
6882d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
68830a920b5bSAndy Whitcroft		}
68840a920b5bSAndy Whitcroft	}
68850a920b5bSAndy Whitcroft	return $clean;
68860a920b5bSAndy Whitcroft}
6887