xref: /linux-6.15/scripts/checkpatch.pl (revision adb2da82)
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;
460f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'};
470f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot);
48c2fdda0dSAndy Whitcroftmy %debug;
493445686aSJoe Perchesmy %camelcase = ();
5091bfe484SJoe Perchesmy %use_type = ();
5191bfe484SJoe Perchesmy @use = ();
5291bfe484SJoe Perchesmy %ignore_type = ();
53000d1cc1SJoe Perchesmy @ignore = ();
5477f5b10aSHannes Edermy $help = 0;
55000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
56bdc48fa1SJoe Perchesmy $max_line_length = 100;
57d62a201fSDave Hansenmy $ignore_perl_version = 0;
58d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5956193274SVadim Bendeburymy $min_conf_desc_length = 4;
6066b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
61ebfd7d62SJoe Perchesmy $codespell = 0;
62f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
63bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
64ced69da1SQuentin Monnetmy $typedefsfile;
65737c0767SJohn Brooksmy $color = "auto";
6698005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
67dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
68dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
69713a09deSAntonio Borneomy $tabsize = 8;
703e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_";
7177f5b10aSHannes Eder
7277f5b10aSHannes Edersub help {
7377f5b10aSHannes Eder	my ($exitcode) = @_;
7477f5b10aSHannes Eder
7577f5b10aSHannes Eder	print << "EOM";
7677f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
7777f5b10aSHannes EderVersion: $V
7877f5b10aSHannes Eder
7977f5b10aSHannes EderOptions:
8077f5b10aSHannes Eder  -q, --quiet                quiet
8177f5b10aSHannes Eder  --no-tree                  run without a kernel tree
8277f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
8377f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
8477f5b10aSHannes Eder  --emacs                    emacs compile window format
8577f5b10aSHannes Eder  --terse                    one line per report
8634d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
874a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
884a593c34SDu, Changbin                             single git commit with:
894a593c34SDu, Changbin                               <rev>
904a593c34SDu, Changbin                               <rev>^
914a593c34SDu, Changbin                               <rev>~n
924a593c34SDu, Changbin                             multiple git commits with:
934a593c34SDu, Changbin                               <rev1>..<rev2>
944a593c34SDu, Changbin                               <rev1>...<rev2>
954a593c34SDu, Changbin                               <rev>-<count>
964a593c34SDu, Changbin                             git merges are ignored
9777f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
9877f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
993beb42ecSJoe Perches  --list-types               list the possible message types
10091bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
101000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1023beb42ecSJoe Perches  --show-types               show the specific message type in the output
103bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
104bdc48fa1SJoe Perches                             if exceeded, warn on patches
105bdc48fa1SJoe Perches                             requires --strict for use with --file
10656193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
107bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
10877f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
10977f5b10aSHannes Eder  --no-summary               suppress the per-file summary
11077f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
11177f5b10aSHannes Eder  --summary-file             include the filename in summary
11277f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
11377f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
11477f5b10aSHannes Eder                             is all off)
11577f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
11677f5b10aSHannes Eder                             literally
1173705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1183705ce5bSJoe Perches                             If correctable single-line errors exist, create
1193705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1203705ce5bSJoe Perches                             with potential errors corrected to the preferred
1213705ce5bSJoe Perches                             checkpatch style
1229624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1239624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1249624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
125d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
126d62a201fSDave Hansen                             runtime errors.
127ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
128f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
129ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
13075ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
131737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
132737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
1333e89ad85SJerome Forissier  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1343e89ad85SJerome Forissier                             ${CONFIG_})
13577f5b10aSHannes Eder  -h, --help, --version      display this help and exit
13677f5b10aSHannes Eder
13777f5b10aSHannes EderWhen FILE is - read standard input.
13877f5b10aSHannes EderEOM
13977f5b10aSHannes Eder
14077f5b10aSHannes Eder	exit($exitcode);
14177f5b10aSHannes Eder}
14277f5b10aSHannes Eder
1433beb42ecSJoe Perchessub uniq {
1443beb42ecSJoe Perches	my %seen;
1453beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1463beb42ecSJoe Perches}
1473beb42ecSJoe Perches
1483beb42ecSJoe Perchessub list_types {
1493beb42ecSJoe Perches	my ($exitcode) = @_;
1503beb42ecSJoe Perches
1513beb42ecSJoe Perches	my $count = 0;
1523beb42ecSJoe Perches
1533beb42ecSJoe Perches	local $/ = undef;
1543beb42ecSJoe Perches
1553beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1563beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1573beb42ecSJoe Perches
1583beb42ecSJoe Perches	my $text = <$script>;
1593beb42ecSJoe Perches	close($script);
1603beb42ecSJoe Perches
1613beb42ecSJoe Perches	my @types = ();
1620547fa58SJean Delvare	# Also catch when type or level is passed through a variable
1630547fa58SJean Delvare	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
1643beb42ecSJoe Perches		push (@types, $_);
1653beb42ecSJoe Perches	}
1663beb42ecSJoe Perches	@types = sort(uniq(@types));
1673beb42ecSJoe Perches	print("#\tMessage type\n\n");
1683beb42ecSJoe Perches	foreach my $type (@types) {
1693beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1703beb42ecSJoe Perches	}
1713beb42ecSJoe Perches
1723beb42ecSJoe Perches	exit($exitcode);
1733beb42ecSJoe Perches}
1743beb42ecSJoe Perches
175000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
176000d1cc1SJoe Perchesif (-f $conf) {
177000d1cc1SJoe Perches	my @conf_args;
178000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
179000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
180000d1cc1SJoe Perches
181000d1cc1SJoe Perches	while (<$conffile>) {
182000d1cc1SJoe Perches		my $line = $_;
183000d1cc1SJoe Perches
184000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
185000d1cc1SJoe Perches		$line =~ s/^\s*//g;
186000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
187000d1cc1SJoe Perches
188000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
189000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
190000d1cc1SJoe Perches
191000d1cc1SJoe Perches		my @words = split(" ", $line);
192000d1cc1SJoe Perches		foreach my $word (@words) {
193000d1cc1SJoe Perches			last if ($word =~ m/^#/);
194000d1cc1SJoe Perches			push (@conf_args, $word);
195000d1cc1SJoe Perches		}
196000d1cc1SJoe Perches	}
197000d1cc1SJoe Perches	close($conffile);
198000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
199000d1cc1SJoe Perches}
200000d1cc1SJoe Perches
201737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
202737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
203737c0767SJohn Brooksforeach (@ARGV) {
204737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
205737c0767SJohn Brooks		$_ = "--color=$color";
206737c0767SJohn Brooks	}
207737c0767SJohn Brooks}
208737c0767SJohn Brooks
2090a920b5bSAndy WhitcroftGetOptions(
2106c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
2110a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2120a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2130a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2146c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2158905a67cSAndy Whitcroft	'terse!'	=> \$terse,
21634d8815fSJoe Perches	'showfile!'	=> \$showfile,
21777f5b10aSHannes Eder	'f|file!'	=> \$file,
2184a593c34SDu, Changbin	'g|git!'	=> \$git,
2196c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
2206c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
221000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
22291bfe484SJoe Perches	'types=s'	=> \@use,
223000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2243beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2256cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
22656193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
227713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
2286c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2298905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2308905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
23113214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2323705ce5bSJoe Perches	'fix!'		=> \$fix,
2339624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
234d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
235c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
236773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
237ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
238ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
23975ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
240737c0767SJohn Brooks	'color=s'	=> \$color,
241737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
242737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
2433e89ad85SJerome Forissier	'kconfig-prefix=s'	=> \${CONFIG_},
24477f5b10aSHannes Eder	'h|help'	=> \$help,
24577f5b10aSHannes Eder	'version'	=> \$help
24677f5b10aSHannes Eder) or help(1);
24777f5b10aSHannes Eder
24877f5b10aSHannes Ederhelp(0) if ($help);
2490a920b5bSAndy Whitcroft
2503beb42ecSJoe Percheslist_types(0) if ($list_types);
2513beb42ecSJoe Perches
2529624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2532ac73b4fSJoe Perches$check_orig = $check;
2549624b8d6SJoe Perches
25532f30ca9SJoe Perchesdie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
25632f30ca9SJoe Perches
2570a920b5bSAndy Whitcroftmy $exit = 0;
2580a920b5bSAndy Whitcroft
2595b57980dSJoe Perchesmy $perl_version_ok = 1;
260d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
2615b57980dSJoe Perches	$perl_version_ok = 0;
262d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
2635b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
264d62a201fSDave Hansen}
265d62a201fSDave Hansen
26645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2670a920b5bSAndy Whitcroftif ($#ARGV < 0) {
26845107ff6SAllen Hubbe	push(@ARGV, '-');
2690a920b5bSAndy Whitcroft}
2700a920b5bSAndy Whitcroft
271737c0767SJohn Brooksif ($color =~ /^[01]$/) {
272737c0767SJohn Brooks	$color = !$color;
273737c0767SJohn Brooks} elsif ($color =~ /^always$/i) {
274737c0767SJohn Brooks	$color = 1;
275737c0767SJohn Brooks} elsif ($color =~ /^never$/i) {
276737c0767SJohn Brooks	$color = 0;
277737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) {
278737c0767SJohn Brooks	$color = (-t STDOUT);
279737c0767SJohn Brooks} else {
28032f30ca9SJoe Perches	die "$P: Invalid color mode: $color\n";
281737c0767SJohn Brooks}
282737c0767SJohn Brooks
283713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
28432f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
285713a09deSAntonio Borneo
28691bfe484SJoe Perchessub hash_save_array_words {
28791bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
28891bfe484SJoe Perches
28991bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
29091bfe484SJoe Perches	foreach my $word (@array) {
291000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
292000d1cc1SJoe Perches		$word =~ s/^\s*//g;
293000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
294000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
295000d1cc1SJoe Perches
296000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
297000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
298000d1cc1SJoe Perches
29991bfe484SJoe Perches		$hashRef->{$word}++;
300000d1cc1SJoe Perches	}
30191bfe484SJoe Perches}
30291bfe484SJoe Perches
30391bfe484SJoe Perchessub hash_show_words {
30491bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
30591bfe484SJoe Perches
3063c816e49SJoe Perches	if (keys %$hashRef) {
307d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
30858cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
30991bfe484SJoe Perches			print " $word";
31091bfe484SJoe Perches		}
311d8469f16SJoe Perches		print "\n";
31291bfe484SJoe Perches	}
31391bfe484SJoe Perches}
31491bfe484SJoe Perches
31591bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
31691bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
317000d1cc1SJoe Perches
318c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
319c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
3207429c690SAndy Whitcroftmy $dbg_type = 0;
321a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
322c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
32321caa13cSAndy Whitcroft	## no critic
32421caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
32521caa13cSAndy Whitcroft	die "$@" if ($@);
326c2fdda0dSAndy Whitcroft}
327c2fdda0dSAndy Whitcroft
328d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
329d2c0a235SAndy Whitcroft
3308905a67cSAndy Whitcroftif ($terse) {
3318905a67cSAndy Whitcroft	$emacs = 1;
3328905a67cSAndy Whitcroft	$quiet++;
3338905a67cSAndy Whitcroft}
3348905a67cSAndy Whitcroft
3356c72ffaaSAndy Whitcroftif ($tree) {
3366c72ffaaSAndy Whitcroft	if (defined $root) {
3376c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
3386c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
3396c72ffaaSAndy Whitcroft		}
3406c72ffaaSAndy Whitcroft	} else {
3416c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
3426c72ffaaSAndy Whitcroft			$root = '.';
3436c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
3446c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3456c72ffaaSAndy Whitcroft			$root = $1;
3466c72ffaaSAndy Whitcroft		}
3476c72ffaaSAndy Whitcroft	}
3486c72ffaaSAndy Whitcroft
3496c72ffaaSAndy Whitcroft	if (!defined $root) {
3500a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3510a920b5bSAndy Whitcroft		exit(2);
3520a920b5bSAndy Whitcroft	}
3536c72ffaaSAndy Whitcroft}
3546c72ffaaSAndy Whitcroft
3556c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3566c72ffaaSAndy Whitcroft
3572ceb532bSAndy Whitcroftour $Ident	= qr{
3582ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3592ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3602ceb532bSAndy Whitcroft		}x;
3616c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3626c72ffaaSAndy Whitcroftour $Sparse	= qr{
3636c72ffaaSAndy Whitcroft			__user|
3646c72ffaaSAndy Whitcroft			__kernel|
3656c72ffaaSAndy Whitcroft			__force|
3666c72ffaaSAndy Whitcroft			__iomem|
3676c72ffaaSAndy Whitcroft			__must_check|
368417495edSAndy Whitcroft			__kprobes|
369165e72a6SSven Eckelmann			__ref|
37033aa4597SGeert Uytterhoeven			__refconst|
37133aa4597SGeert Uytterhoeven			__refdata|
372ad315455SBoqun Feng			__rcu|
373ad315455SBoqun Feng			__private
3746c72ffaaSAndy Whitcroft		}x;
375e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
376e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
377e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
378e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
379e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3808716de38SJoe Perches
38152131292SWolfram Sang# Notes to $Attribute:
38252131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3836c72ffaaSAndy Whitcroftour $Attribute	= qr{
3846c72ffaaSAndy Whitcroft			const|
385b5e8736aSJoe Perches			volatile|
38603f1df7dSJoe Perches			__percpu|
38703f1df7dSJoe Perches			__nocast|
38803f1df7dSJoe Perches			__safe|
38946d832f5SMichael S. Tsirkin			__bitwise|
39003f1df7dSJoe Perches			__packed__|
39103f1df7dSJoe Perches			__packed2__|
39203f1df7dSJoe Perches			__naked|
39303f1df7dSJoe Perches			__maybe_unused|
39403f1df7dSJoe Perches			__always_unused|
39503f1df7dSJoe Perches			__noreturn|
39603f1df7dSJoe Perches			__used|
39703f1df7dSJoe Perches			__cold|
398e23ef1f3SJoe Perches			__pure|
39903f1df7dSJoe Perches			__noclone|
40003f1df7dSJoe Perches			__deprecated|
4016c72ffaaSAndy Whitcroft			__read_mostly|
402c5967e98SJoe Perches			__ro_after_init|
4036c72ffaaSAndy Whitcroft			__kprobes|
4048716de38SJoe Perches			$InitAttribute|
40524e1d81aSAndy Whitcroft			____cacheline_aligned|
40624e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
4075fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
4085fe3af11SAndy Whitcroft			__weak
4096c72ffaaSAndy Whitcroft		  }x;
410c45dcabdSAndy Whitcroftour $Modifier;
41191cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
4126c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
4136c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
4146c72ffaaSAndy Whitcroft
41595e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
41695e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
41795e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
41895e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
4192435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
420c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
421326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
422326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
423326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
42474349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
4252435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
426326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
427447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
42823f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
4296c72ffaaSAndy Whitcroftour $Operators	= qr{
4306c72ffaaSAndy Whitcroft			<=|>=|==|!=|
4316c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
43223f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
4336c72ffaaSAndy Whitcroft		  }x;
4346c72ffaaSAndy Whitcroft
43591cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
43691cb5195SJoe Perches
437ab7e23f3SJoe Perchesour $BasicType;
4388905a67cSAndy Whitcroftour $NonptrType;
4391813087dSJoe Perchesour $NonptrTypeMisordered;
4408716de38SJoe Perchesour $NonptrTypeWithAttr;
4418905a67cSAndy Whitcroftour $Type;
4421813087dSJoe Perchesour $TypeMisordered;
4438905a67cSAndy Whitcroftour $Declare;
4441813087dSJoe Perchesour $DeclareMisordered;
4458905a67cSAndy Whitcroft
44615662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
44715662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
448171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
449171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
450171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
451171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
452171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
453171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
454171ae1a4SAndy Whitcroft}x;
455171ae1a4SAndy Whitcroft
45615662b3eSJoe Perchesour $UTF8	= qr{
45715662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
45815662b3eSJoe Perches	| $NON_ASCII_UTF8
45915662b3eSJoe Perches}x;
46015662b3eSJoe Perches
461e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
462021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
463021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
464021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
465021158b4SJoe Perches)};
466e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
467fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4688ed22cadSAndy Whitcroft	atomic_t
4698ed22cadSAndy Whitcroft)};
470e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
471e6176fa4SJoe Perches	$typeC99Typedefs\b|
472e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
473e6176fa4SJoe Perches	$typeKernelTypedefs\b
474e6176fa4SJoe Perches)};
4758ed22cadSAndy Whitcroft
4766d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4776d32f7a3SJoe Perches
478691e669bSJoe Perchesour $logFunctions = qr{(?x:
479758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4807d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
48187bd499aSJoe Perches	TP_printk|
4826e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
483b0531722SJoe Perches	panic|
48406668727SJoe Perches	MODULE_[A-Z_]+|
48506668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
486691e669bSJoe Perches)};
487691e669bSJoe Perches
488e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
489e29a70f1SJoe Perches	(?:(?:devm_)?
490e29a70f1SJoe Perches		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
491e29a70f1SJoe Perches		kstrdup(?:_const)? |
492e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
493461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
494e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
495e29a70f1SJoe Perches	dma_alloc_coherent
496e29a70f1SJoe Perches)};
497e29a70f1SJoe Perches
49820112475SJoe Perchesour $signature_tags = qr{(?xi:
49920112475SJoe Perches	Signed-off-by:|
500d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
50120112475SJoe Perches	Acked-by:|
50220112475SJoe Perches	Tested-by:|
50320112475SJoe Perches	Reviewed-by:|
50420112475SJoe Perches	Reported-by:|
5058543ae12SMugunthan V N	Suggested-by:|
50620112475SJoe Perches	To:|
50720112475SJoe Perches	Cc:
50820112475SJoe Perches)};
50920112475SJoe Perches
510*adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
511*adb2da82SJoe Perches	[=-]*> |
512*adb2da82SJoe Perches	<[=-]* |
513*adb2da82SJoe Perches	\[ |
514*adb2da82SJoe Perches	\] |
515*adb2da82SJoe Perches	start |
516*adb2da82SJoe Perches	called |
517*adb2da82SJoe Perches	entered |
518*adb2da82SJoe Perches	entry |
519*adb2da82SJoe Perches	enter |
520*adb2da82SJoe Perches	in |
521*adb2da82SJoe Perches	inside |
522*adb2da82SJoe Perches	here |
523*adb2da82SJoe Perches	begin |
524*adb2da82SJoe Perches	exit |
525*adb2da82SJoe Perches	end |
526*adb2da82SJoe Perches	done |
527*adb2da82SJoe Perches	leave |
528*adb2da82SJoe Perches	completed |
529*adb2da82SJoe Perches	out |
530*adb2da82SJoe Perches	return |
531*adb2da82SJoe Perches	[\.\!:\s]*
532*adb2da82SJoe Perches)};
533*adb2da82SJoe Perches
534831242abSAditya Srivastavasub edit_distance_min {
535831242abSAditya Srivastava	my (@arr) = @_;
536831242abSAditya Srivastava	my $len = scalar @arr;
537831242abSAditya Srivastava	if ((scalar @arr) < 1) {
538831242abSAditya Srivastava		# if underflow, return
539831242abSAditya Srivastava		return;
540831242abSAditya Srivastava	}
541831242abSAditya Srivastava	my $min = $arr[0];
542831242abSAditya Srivastava	for my $i (0 .. ($len-1)) {
543831242abSAditya Srivastava		if ($arr[$i] < $min) {
544831242abSAditya Srivastava			$min = $arr[$i];
545831242abSAditya Srivastava		}
546831242abSAditya Srivastava	}
547831242abSAditya Srivastava	return $min;
548831242abSAditya Srivastava}
549831242abSAditya Srivastava
550831242abSAditya Srivastavasub get_edit_distance {
551831242abSAditya Srivastava	my ($str1, $str2) = @_;
552831242abSAditya Srivastava	$str1 = lc($str1);
553831242abSAditya Srivastava	$str2 = lc($str2);
554831242abSAditya Srivastava	$str1 =~ s/-//g;
555831242abSAditya Srivastava	$str2 =~ s/-//g;
556831242abSAditya Srivastava	my $len1 = length($str1);
557831242abSAditya Srivastava	my $len2 = length($str2);
558831242abSAditya Srivastava	# two dimensional array storing minimum edit distance
559831242abSAditya Srivastava	my @distance;
560831242abSAditya Srivastava	for my $i (0 .. $len1) {
561831242abSAditya Srivastava		for my $j (0 .. $len2) {
562831242abSAditya Srivastava			if ($i == 0) {
563831242abSAditya Srivastava				$distance[$i][$j] = $j;
564831242abSAditya Srivastava			} elsif ($j == 0) {
565831242abSAditya Srivastava				$distance[$i][$j] = $i;
566831242abSAditya Srivastava			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
567831242abSAditya Srivastava				$distance[$i][$j] = $distance[$i - 1][$j - 1];
568831242abSAditya Srivastava			} else {
569831242abSAditya Srivastava				my $dist1 = $distance[$i][$j - 1]; #insert distance
570831242abSAditya Srivastava				my $dist2 = $distance[$i - 1][$j]; # remove
571831242abSAditya Srivastava				my $dist3 = $distance[$i - 1][$j - 1]; #replace
572831242abSAditya Srivastava				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
573831242abSAditya Srivastava			}
574831242abSAditya Srivastava		}
575831242abSAditya Srivastava	}
576831242abSAditya Srivastava	return $distance[$len1][$len2];
577831242abSAditya Srivastava}
578831242abSAditya Srivastava
579831242abSAditya Srivastavasub find_standard_signature {
580831242abSAditya Srivastava	my ($sign_off) = @_;
581831242abSAditya Srivastava	my @standard_signature_tags = (
582831242abSAditya Srivastava		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
583831242abSAditya Srivastava		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
584831242abSAditya Srivastava	);
585831242abSAditya Srivastava	foreach my $signature (@standard_signature_tags) {
586831242abSAditya Srivastava		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
587831242abSAditya Srivastava	}
588831242abSAditya Srivastava
589831242abSAditya Srivastava	return "";
590831242abSAditya Srivastava}
591831242abSAditya Srivastava
5921813087dSJoe Perchesour @typeListMisordered = (
5931813087dSJoe Perches	qr{char\s+(?:un)?signed},
5941813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
5951813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
5961813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
5971813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
5981813087dSJoe Perches	qr{short\s+(?:un)?signed},
5991813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
6001813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
6011813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
6021813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
6031813087dSJoe Perches	qr{int\s+(?:un)?signed},
6041813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
6051813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
6061813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
6071813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
6081813087dSJoe Perches	qr{long\s+(?:un)?signed},
6091813087dSJoe Perches);
6101813087dSJoe Perches
6118905a67cSAndy Whitcroftour @typeList = (
6128905a67cSAndy Whitcroft	qr{void},
6130c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
6140c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
6150c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
6160c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
6170c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
6180c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
6190c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
6200c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
6210c773d9dSJoe Perches	qr{(?:un)?signed},
6228905a67cSAndy Whitcroft	qr{float},
6238905a67cSAndy Whitcroft	qr{double},
6248905a67cSAndy Whitcroft	qr{bool},
6258905a67cSAndy Whitcroft	qr{struct\s+$Ident},
6268905a67cSAndy Whitcroft	qr{union\s+$Ident},
6278905a67cSAndy Whitcroft	qr{enum\s+$Ident},
6288905a67cSAndy Whitcroft	qr{${Ident}_t},
6298905a67cSAndy Whitcroft	qr{${Ident}_handler},
6308905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
6311813087dSJoe Perches	@typeListMisordered,
6328905a67cSAndy Whitcroft);
633938224b5SJoe Perches
634938224b5SJoe Perchesour $C90_int_types = qr{(?x:
635938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
636938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
637938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
638938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
639938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
640938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
641938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
642938224b5SJoe Perches
643938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
644938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
645938224b5SJoe Perches	long\s+(?:un)?signed|
646938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
647938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
648938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
649938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
650938224b5SJoe Perches
651938224b5SJoe Perches	int\s+(?:un)?signed|
652938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
653938224b5SJoe Perches)};
654938224b5SJoe Perches
655485ff23eSAlex Dowadour @typeListFile = ();
6568716de38SJoe Perchesour @typeListWithAttr = (
6578716de38SJoe Perches	@typeList,
6588716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
6598716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
6608716de38SJoe Perches);
6618716de38SJoe Perches
662c45dcabdSAndy Whitcroftour @modifierList = (
663c45dcabdSAndy Whitcroft	qr{fastcall},
664c45dcabdSAndy Whitcroft);
665485ff23eSAlex Dowadour @modifierListFile = ();
6668905a67cSAndy Whitcroft
6672435880fSJoe Perchesour @mode_permission_funcs = (
6682435880fSJoe Perches	["module_param", 3],
6692435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
6702435880fSJoe Perches	["module_param_array_named", 5],
6712435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
6722435880fSJoe Perches	["proc_create(?:_data|)", 2],
673459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
674459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
675459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
676459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
677459cf0aeSJoe Perches	["__ATTR", 2],
6782435880fSJoe Perches);
6792435880fSJoe Perches
6801a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
6811a3dcf2eSJoe Perches
682515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
683515a235eSJoe Perchesour $mode_perms_search = "";
684515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
685515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
686515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
687515a235eSJoe Perches}
68800180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
689515a235eSJoe Perches
6909189c7e7SJoe Perchesour %deprecated_apis = (
6919189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
6929189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
6939189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
6949189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
6959189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
6969189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
6979189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
6989189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
6999189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
7009189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
7019189c7e7SJoe Perches);
7029189c7e7SJoe Perches
7039189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
7049189c7e7SJoe Perchesour $deprecated_apis_search = "";
7059189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
7069189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
7079189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
7089189c7e7SJoe Perches}
7099189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
7109189c7e7SJoe Perches
711b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
712b392c64fSJoe Perches	S_IWUGO		|
713b392c64fSJoe Perches	S_IWOTH		|
714b392c64fSJoe Perches	S_IRWXUGO	|
715b392c64fSJoe Perches	S_IALLUGO	|
716b392c64fSJoe Perches	0[0-7][0-7][2367]
717b392c64fSJoe Perches}x;
718b392c64fSJoe Perches
719f90774e1SJoe Perchesour %mode_permission_string_types = (
720f90774e1SJoe Perches	"S_IRWXU" => 0700,
721f90774e1SJoe Perches	"S_IRUSR" => 0400,
722f90774e1SJoe Perches	"S_IWUSR" => 0200,
723f90774e1SJoe Perches	"S_IXUSR" => 0100,
724f90774e1SJoe Perches	"S_IRWXG" => 0070,
725f90774e1SJoe Perches	"S_IRGRP" => 0040,
726f90774e1SJoe Perches	"S_IWGRP" => 0020,
727f90774e1SJoe Perches	"S_IXGRP" => 0010,
728f90774e1SJoe Perches	"S_IRWXO" => 0007,
729f90774e1SJoe Perches	"S_IROTH" => 0004,
730f90774e1SJoe Perches	"S_IWOTH" => 0002,
731f90774e1SJoe Perches	"S_IXOTH" => 0001,
732f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
733f90774e1SJoe Perches	"S_IRUGO" => 0444,
734f90774e1SJoe Perches	"S_IWUGO" => 0222,
735f90774e1SJoe Perches	"S_IXUGO" => 0111,
736f90774e1SJoe Perches);
737f90774e1SJoe Perches
738f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
739f90774e1SJoe Perchesour $mode_perms_string_search = "";
740f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
741f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
742f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
743f90774e1SJoe Perches}
74400180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
74500180468SJoe Perchesour $multi_mode_perms_string_search = qr{
74600180468SJoe Perches	${single_mode_perms_string_search}
74700180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
74800180468SJoe Perches}x;
74900180468SJoe Perches
75000180468SJoe Perchessub perms_to_octal {
75100180468SJoe Perches	my ($string) = @_;
75200180468SJoe Perches
75300180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
75400180468SJoe Perches
75500180468SJoe Perches	my $val = "";
75600180468SJoe Perches	my $oval = "";
75700180468SJoe Perches	my $to = 0;
75800180468SJoe Perches	my $curpos = 0;
75900180468SJoe Perches	my $lastpos = 0;
76000180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
76100180468SJoe Perches		$curpos = pos($string);
76200180468SJoe Perches		my $match = $2;
76300180468SJoe Perches		my $omatch = $1;
76400180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
76500180468SJoe Perches		$lastpos = $curpos;
76600180468SJoe Perches		$to |= $mode_permission_string_types{$match};
76700180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
76800180468SJoe Perches		$val .= $match;
76900180468SJoe Perches		$oval .= $omatch;
77000180468SJoe Perches	}
77100180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
77200180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
77300180468SJoe Perches	return sprintf("%04o", $to);
77400180468SJoe Perches}
775f90774e1SJoe Perches
7767840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
7777840a94cSWolfram Sang	irq|
778cdcee686SSergey Ryazanov	memory|
779cdcee686SSergey Ryazanov	time|
780cdcee686SSergey Ryazanov	reboot
7817840a94cSWolfram Sang)};
7827840a94cSWolfram Sang# memory.h: ARM has a custom one
7837840a94cSWolfram Sang
78466b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
78566b47b4aSKees Cookmy $misspellings;
78666b47b4aSKees Cookmy %spelling_fix;
78736061e38SJoe Perches
78836061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
78966b47b4aSKees Cook	while (<$spelling>) {
79066b47b4aSKees Cook		my $line = $_;
79166b47b4aSKees Cook
79266b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
79366b47b4aSKees Cook		$line =~ s/^\s*//g;
79466b47b4aSKees Cook
79566b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
79666b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
79766b47b4aSKees Cook
79866b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
79966b47b4aSKees Cook
80066b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
80166b47b4aSKees Cook	}
80266b47b4aSKees Cook	close($spelling);
80336061e38SJoe Perches} else {
80436061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
80536061e38SJoe Perches}
80666b47b4aSKees Cook
807ebfd7d62SJoe Perchesif ($codespell) {
808ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
809ebfd7d62SJoe Perches		while (<$spelling>) {
810ebfd7d62SJoe Perches			my $line = $_;
811ebfd7d62SJoe Perches
812ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
813ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
814ebfd7d62SJoe Perches
815ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
816ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
817ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
818ebfd7d62SJoe Perches
819ebfd7d62SJoe Perches			$line =~ s/,.*$//;
820ebfd7d62SJoe Perches
821ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
822ebfd7d62SJoe Perches
823ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
824ebfd7d62SJoe Perches		}
825ebfd7d62SJoe Perches		close($spelling);
826ebfd7d62SJoe Perches	} else {
827ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
828ebfd7d62SJoe Perches	}
829ebfd7d62SJoe Perches}
830ebfd7d62SJoe Perches
831ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
832ebfd7d62SJoe Perches
83375ad8c57SJerome Forissiersub read_words {
83475ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
83575ad8c57SJerome Forissier
83675ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
83775ad8c57SJerome Forissier		while (<$words>) {
838bf1fa1daSJoe Perches			my $line = $_;
839bf1fa1daSJoe Perches
840bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
841bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
842bf1fa1daSJoe Perches
843bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
844bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
845bf1fa1daSJoe Perches			if ($line =~ /\s/) {
84675ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
847bf1fa1daSJoe Perches				next;
848bf1fa1daSJoe Perches			}
849bf1fa1daSJoe Perches
850ced69da1SQuentin Monnet			$$wordsRef .= '|' if (defined $$wordsRef);
85175ad8c57SJerome Forissier			$$wordsRef .= $line;
852bf1fa1daSJoe Perches		}
85375ad8c57SJerome Forissier		close($file);
85475ad8c57SJerome Forissier		return 1;
855bf1fa1daSJoe Perches	}
856bf1fa1daSJoe Perches
85775ad8c57SJerome Forissier	return 0;
85875ad8c57SJerome Forissier}
85975ad8c57SJerome Forissier
860ced69da1SQuentin Monnetmy $const_structs;
861ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) {
86275ad8c57SJerome Forissier	read_words(\$const_structs, $conststructsfile)
86375ad8c57SJerome Forissier	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
864ced69da1SQuentin Monnet}
86575ad8c57SJerome Forissier
866ced69da1SQuentin Monnetif (defined($typedefsfile)) {
867ced69da1SQuentin Monnet	my $typeOtherTypedefs;
86875ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
86975ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
870ced69da1SQuentin Monnet	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
87175ad8c57SJerome Forissier}
87275ad8c57SJerome Forissier
8738905a67cSAndy Whitcroftsub build_types {
874485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
875485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
8761813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
8778716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
878c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
879ab7e23f3SJoe Perches	$BasicType	= qr{
880ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
881ab7e23f3SJoe Perches				(?:${all}\b)
882ab7e23f3SJoe Perches		}x;
8838905a67cSAndy Whitcroft	$NonptrType	= qr{
884d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
885cf655043SAndy Whitcroft			(?:
8866b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
8878ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
888c45dcabdSAndy Whitcroft				(?:${all}\b)
889cf655043SAndy Whitcroft			)
890c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
8918905a67cSAndy Whitcroft		  }x;
8921813087dSJoe Perches	$NonptrTypeMisordered	= qr{
8931813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
8941813087dSJoe Perches			(?:
8951813087dSJoe Perches				(?:${Misordered}\b)
8961813087dSJoe Perches			)
8971813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
8981813087dSJoe Perches		  }x;
8998716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
9008716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
9018716de38SJoe Perches			(?:
9028716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
9038716de38SJoe Perches				(?:$typeTypedefs\b)|
9048716de38SJoe Perches				(?:${allWithAttr}\b)
9058716de38SJoe Perches			)
9068716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
9078716de38SJoe Perches		  }x;
9088905a67cSAndy Whitcroft	$Type	= qr{
909c45dcabdSAndy Whitcroft			$NonptrType
9107b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
911c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
9128905a67cSAndy Whitcroft		  }x;
9131813087dSJoe Perches	$TypeMisordered	= qr{
9141813087dSJoe Perches			$NonptrTypeMisordered
9157b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
9161813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
9171813087dSJoe Perches		  }x;
91891cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
9191813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
9208905a67cSAndy Whitcroft}
9218905a67cSAndy Whitcroftbuild_types();
9226c72ffaaSAndy Whitcroft
9237d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
924d1fe9c09SJoe Perches
925d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
926d1fe9c09SJoe Perches# requires at least perl version v5.10.0
927d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
928d1fe9c09SJoe Perches
929d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
9302435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
931c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
9327d2367afSJoe Perches
933f8422308SJoe Perchesour $declaration_macros = qr{(?x:
9343e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
935fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
9363d102fc0SGilad Ben-Yossef	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
937f8422308SJoe Perches)};
938f8422308SJoe Perches
9398d0325ccSAditya Srivastavaour %allow_repeated_words = (
9408d0325ccSAditya Srivastava	add => '',
9418d0325ccSAditya Srivastava	added => '',
9428d0325ccSAditya Srivastava	bad => '',
9438d0325ccSAditya Srivastava	be => '',
9448d0325ccSAditya Srivastava);
9458d0325ccSAditya Srivastava
9467d2367afSJoe Perchessub deparenthesize {
9477d2367afSJoe Perches	my ($string) = @_;
9487d2367afSJoe Perches	return "" if (!defined($string));
9495b9553abSJoe Perches
9505b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
9515b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
9525b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
9535b9553abSJoe Perches	}
9545b9553abSJoe Perches
9557d2367afSJoe Perches	$string =~ s@\s+@ @g;
9565b9553abSJoe Perches
9577d2367afSJoe Perches	return $string;
9587d2367afSJoe Perches}
9597d2367afSJoe Perches
9603445686aSJoe Perchessub seed_camelcase_file {
9613445686aSJoe Perches	my ($file) = @_;
9623445686aSJoe Perches
9633445686aSJoe Perches	return if (!(-f $file));
9643445686aSJoe Perches
9653445686aSJoe Perches	local $/;
9663445686aSJoe Perches
9673445686aSJoe Perches	open(my $include_file, '<', "$file")
9683445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
9693445686aSJoe Perches	my $text = <$include_file>;
9703445686aSJoe Perches	close($include_file);
9713445686aSJoe Perches
9723445686aSJoe Perches	my @lines = split('\n', $text);
9733445686aSJoe Perches
9743445686aSJoe Perches	foreach my $line (@lines) {
9753445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
9763445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
9773445686aSJoe Perches			$camelcase{$1} = 1;
97811ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
97911ea516aSJoe Perches			$camelcase{$1} = 1;
98011ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
9813445686aSJoe Perches			$camelcase{$1} = 1;
9823445686aSJoe Perches		}
9833445686aSJoe Perches	}
9843445686aSJoe Perches}
9853445686aSJoe Perches
986cd28b119SJoe Perchesour %maintained_status = ();
987cd28b119SJoe Perches
98885b0ee18SJoe Perchessub is_maintained_obsolete {
98985b0ee18SJoe Perches	my ($filename) = @_;
99085b0ee18SJoe Perches
991f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
99285b0ee18SJoe Perches
993cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
994cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
995cd28b119SJoe Perches	}
99685b0ee18SJoe Perches
997cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
99885b0ee18SJoe Perches}
99985b0ee18SJoe Perches
10003b6e8ac9SJoe Perchessub is_SPDX_License_valid {
10013b6e8ac9SJoe Perches	my ($license) = @_;
10023b6e8ac9SJoe Perches
10030f7f635bSJoe Perches	return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
10043b6e8ac9SJoe Perches
100556294112SJoe Perches	my $root_path = abs_path($root);
100656294112SJoe Perches	my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
10073b6e8ac9SJoe Perches	return 0 if ($status ne "");
10083b6e8ac9SJoe Perches	return 1;
10093b6e8ac9SJoe Perches}
10103b6e8ac9SJoe Perches
10113445686aSJoe Perchesmy $camelcase_seeded = 0;
10123445686aSJoe Perchessub seed_camelcase_includes {
10133445686aSJoe Perches	return if ($camelcase_seeded);
10143445686aSJoe Perches
10153445686aSJoe Perches	my $files;
1016c707a81dSJoe Perches	my $camelcase_cache = "";
1017c707a81dSJoe Perches	my @include_files = ();
1018c707a81dSJoe Perches
1019c707a81dSJoe Perches	$camelcase_seeded = 1;
1020351b2a1fSJoe Perches
10210f7f635bSJoe Perches	if (-e "$gitroot") {
1022dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1023351b2a1fSJoe Perches		chomp $git_last_include_commit;
1024c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1025c707a81dSJoe Perches	} else {
1026c707a81dSJoe Perches		my $last_mod_date = 0;
1027c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
1028c707a81dSJoe Perches		@include_files = split('\n', $files);
1029c707a81dSJoe Perches		foreach my $file (@include_files) {
1030c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
1031c707a81dSJoe Perches						   localtime((stat $file)[9]));
1032c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
1033c707a81dSJoe Perches		}
1034c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1035c707a81dSJoe Perches	}
1036c707a81dSJoe Perches
1037c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1038c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
1039c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1040351b2a1fSJoe Perches		while (<$camelcase_file>) {
1041351b2a1fSJoe Perches			chomp;
1042351b2a1fSJoe Perches			$camelcase{$_} = 1;
1043351b2a1fSJoe Perches		}
1044351b2a1fSJoe Perches		close($camelcase_file);
1045351b2a1fSJoe Perches
1046351b2a1fSJoe Perches		return;
1047351b2a1fSJoe Perches	}
1048c707a81dSJoe Perches
10490f7f635bSJoe Perches	if (-e "$gitroot") {
1050dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
1051c707a81dSJoe Perches		@include_files = split('\n', $files);
10523445686aSJoe Perches	}
1053c707a81dSJoe Perches
10543445686aSJoe Perches	foreach my $file (@include_files) {
10553445686aSJoe Perches		seed_camelcase_file($file);
10563445686aSJoe Perches	}
1057351b2a1fSJoe Perches
1058c707a81dSJoe Perches	if ($camelcase_cache ne "") {
1059351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
1060c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
1061c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1062351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1063351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
1064351b2a1fSJoe Perches		}
1065351b2a1fSJoe Perches		close($camelcase_file);
1066351b2a1fSJoe Perches	}
10673445686aSJoe Perches}
10683445686aSJoe Perches
1069f5f61325SJoe Perchessub git_is_single_file {
1070f5f61325SJoe Perches	my ($filename) = @_;
1071f5f61325SJoe Perches
1072f5f61325SJoe Perches	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1073f5f61325SJoe Perches
1074f5f61325SJoe Perches	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1075f5f61325SJoe Perches	my $count = $output =~ tr/\n//;
1076f5f61325SJoe Perches	return $count eq 1 && $output =~ m{^${filename}$};
1077f5f61325SJoe Perches}
1078f5f61325SJoe Perches
1079d311cd44SJoe Perchessub git_commit_info {
1080d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
1081d311cd44SJoe Perches
10820f7f635bSJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1083d311cd44SJoe Perches
1084dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1085d311cd44SJoe Perches	$output =~ s/^\s*//gm;
1086d311cd44SJoe Perches	my @lines = split("\n", $output);
1087d311cd44SJoe Perches
10880d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
10890d7835fcSJoe Perches
10905a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1091d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
1092d311cd44SJoe Perches# all matching commit ids, but it's very slow...
1093d311cd44SJoe Perches#
1094d311cd44SJoe Perches#		echo "checking commits $1..."
1095d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
1096d311cd44SJoe Perches#		while read line ; do
1097d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
1098d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
1099d311cd44SJoe Perches#		done
1100d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
1101948b133aSHeinrich Schuchardt		$id = undef;
1102d311cd44SJoe Perches	} else {
1103d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1104d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1105d311cd44SJoe Perches	}
1106d311cd44SJoe Perches
1107d311cd44SJoe Perches	return ($id, $desc);
1108d311cd44SJoe Perches}
1109d311cd44SJoe Perches
11106c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
11110a920b5bSAndy Whitcroft
111200df344fSAndy Whitcroftmy @rawlines = ();
1113c2fdda0dSAndy Whitcroftmy @lines = ();
11143705ce5bSJoe Perchesmy @fixed = ();
1115d752fcc8SJoe Perchesmy @fixed_inserted = ();
1116d752fcc8SJoe Perchesmy @fixed_deleted = ();
1117194f66fcSJoe Perchesmy $fixlinenr = -1;
1118194f66fcSJoe Perches
11194a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
11204a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
11210f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
11224a593c34SDu, Changbin
11234a593c34SDu, Changbinif ($git) {
11244a593c34SDu, Changbin	my @commits = ();
11250dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
11264a593c34SDu, Changbin		my $git_range;
112728898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
112828898fd1SJoe Perches			$git_range = "-$2 $1";
11294a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
11304a593c34SDu, Changbin			$git_range = "$commit_expr";
11314a593c34SDu, Changbin		} else {
11320dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
11330dea9f1eSJoe Perches		}
1134dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
11350dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
113628898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
113728898fd1SJoe Perches			next if (!defined($1) || !defined($2));
11380dea9f1eSJoe Perches			my $sha1 = $1;
11390dea9f1eSJoe Perches			my $subject = $2;
11400dea9f1eSJoe Perches			unshift(@commits, $sha1);
11410dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
11424a593c34SDu, Changbin		}
11434a593c34SDu, Changbin	}
11444a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
11454a593c34SDu, Changbin	@ARGV = @commits;
11464a593c34SDu, Changbin}
11474a593c34SDu, Changbin
1148c2fdda0dSAndy Whitcroftmy $vname;
114998005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
11506c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
115121caa13cSAndy Whitcroft	my $FILE;
1152f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1153f5f61325SJoe Perches	my $oldfile = $file;
1154f5f61325SJoe Perches	$file = 1 if ($is_git_file);
11554a593c34SDu, Changbin	if ($git) {
11564a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
11574a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
11584a593c34SDu, Changbin	} elsif ($file) {
115921caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
11606c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
116121caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
116221caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
11636c72ffaaSAndy Whitcroft	} else {
116421caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
11656c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
11666c72ffaaSAndy Whitcroft	}
1167c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1168c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
11694a593c34SDu, Changbin	} elsif ($git) {
11700dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1171c2fdda0dSAndy Whitcroft	} else {
1172c2fdda0dSAndy Whitcroft		$vname = $filename;
1173c2fdda0dSAndy Whitcroft	}
117421caa13cSAndy Whitcroft	while (<$FILE>) {
11750a920b5bSAndy Whitcroft		chomp;
117600df344fSAndy Whitcroft		push(@rawlines, $_);
1177c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
11786c72ffaaSAndy Whitcroft	}
117921caa13cSAndy Whitcroft	close($FILE);
1180d8469f16SJoe Perches
1181d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1182d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1183d8469f16SJoe Perches		print "$vname\n";
1184d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1185d8469f16SJoe Perches	}
1186d8469f16SJoe Perches
1187c2fdda0dSAndy Whitcroft	if (!process($filename)) {
11880a920b5bSAndy Whitcroft		$exit = 1;
11890a920b5bSAndy Whitcroft	}
119000df344fSAndy Whitcroft	@rawlines = ();
119113214adfSAndy Whitcroft	@lines = ();
11923705ce5bSJoe Perches	@fixed = ();
1193d752fcc8SJoe Perches	@fixed_inserted = ();
1194d752fcc8SJoe Perches	@fixed_deleted = ();
1195194f66fcSJoe Perches	$fixlinenr = -1;
1196485ff23eSAlex Dowad	@modifierListFile = ();
1197485ff23eSAlex Dowad	@typeListFile = ();
1198485ff23eSAlex Dowad	build_types();
1199f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
12000a920b5bSAndy Whitcroft}
12010a920b5bSAndy Whitcroft
1202d8469f16SJoe Perchesif (!$quiet) {
12033c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
12043c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
12053c816e49SJoe Perches
12065b57980dSJoe Perches	if (!$perl_version_ok) {
1207d8469f16SJoe Perches		print << "EOM"
1208d8469f16SJoe Perches
1209d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
12105b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1211d8469f16SJoe PerchesEOM
1212d8469f16SJoe Perches	}
1213d8469f16SJoe Perches	if ($exit) {
1214d8469f16SJoe Perches		print << "EOM"
1215d8469f16SJoe Perches
1216d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1217d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1218d8469f16SJoe PerchesEOM
1219d8469f16SJoe Perches	}
1220d8469f16SJoe Perches}
1221d8469f16SJoe Perches
12220a920b5bSAndy Whitcroftexit($exit);
12230a920b5bSAndy Whitcroft
12240a920b5bSAndy Whitcroftsub top_of_kernel_tree {
12256c72ffaaSAndy Whitcroft	my ($root) = @_;
12266c72ffaaSAndy Whitcroft
12276c72ffaaSAndy Whitcroft	my @tree_check = (
12286c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
12296c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
12306c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
12316c72ffaaSAndy Whitcroft	);
12326c72ffaaSAndy Whitcroft
12336c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
12346c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
12350a920b5bSAndy Whitcroft			return 0;
12360a920b5bSAndy Whitcroft		}
12376c72ffaaSAndy Whitcroft	}
12386c72ffaaSAndy Whitcroft	return 1;
12396c72ffaaSAndy Whitcroft}
12400a920b5bSAndy Whitcroft
124120112475SJoe Perchessub parse_email {
124220112475SJoe Perches	my ($formatted_email) = @_;
124320112475SJoe Perches
124420112475SJoe Perches	my $name = "";
1245fccaebf0SDwaipayan Ray	my $quoted = "";
1246dfa05c28SJoe Perches	my $name_comment = "";
124720112475SJoe Perches	my $address = "";
124820112475SJoe Perches	my $comment = "";
124920112475SJoe Perches
125020112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
125120112475SJoe Perches		$name = $1;
125220112475SJoe Perches		$address = $2;
125320112475SJoe Perches		$comment = $3 if defined $3;
125420112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
125520112475SJoe Perches		$address = $1;
125620112475SJoe Perches		$comment = $2 if defined $2;
125720112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
125820112475SJoe Perches		$address = $1;
125920112475SJoe Perches		$comment = $2 if defined $2;
126085e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
126120112475SJoe Perches		$name = $formatted_email;
12623705ce5bSJoe Perches		$name = trim($name);
126320112475SJoe Perches		$name =~ s/^\"|\"$//g;
126420112475SJoe Perches		# If there's a name left after stripping spaces and
126520112475SJoe Perches		# leading quotes, and the address doesn't have both
126620112475SJoe Perches		# leading and trailing angle brackets, the address
126720112475SJoe Perches		# is invalid. ie:
126820112475SJoe Perches		#   "joe smith [email protected]" bad
126920112475SJoe Perches		#   "joe smith <[email protected]" bad
127020112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
127120112475SJoe Perches			$name = "";
127220112475SJoe Perches			$address = "";
127320112475SJoe Perches			$comment = "";
127420112475SJoe Perches		}
127520112475SJoe Perches	}
127620112475SJoe Perches
1277fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1278fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1279fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1280fccaebf0SDwaipayan Ray		$quoted = $1;
1281dfa05c28SJoe Perches	}
1282fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1283fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1284fccaebf0SDwaipayan Ray	}
1285fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1286fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1287fccaebf0SDwaipayan Ray
12883705ce5bSJoe Perches	$address = trim($address);
128920112475SJoe Perches	$address =~ s/^\<|\>$//g;
1290fccaebf0SDwaipayan Ray	$comment = trim($comment);
129120112475SJoe Perches
129220112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
129320112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
129420112475SJoe Perches		$name = "\"$name\"";
129520112475SJoe Perches	}
129620112475SJoe Perches
1297dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
129820112475SJoe Perches}
129920112475SJoe Perches
130020112475SJoe Perchessub format_email {
130148ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
130220112475SJoe Perches
130320112475SJoe Perches	my $formatted_email;
130420112475SJoe Perches
1305fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
13063705ce5bSJoe Perches	$address = trim($address);
1307fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
130820112475SJoe Perches
130920112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
131020112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
131120112475SJoe Perches		$name = "\"$name\"";
131220112475SJoe Perches	}
131320112475SJoe Perches
1314fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1315fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1316fccaebf0SDwaipayan Ray	$comment = trim($comment);
1317fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1318fccaebf0SDwaipayan Ray
131920112475SJoe Perches	if ("$name" eq "") {
132020112475SJoe Perches		$formatted_email = "$address";
132120112475SJoe Perches	} else {
132248ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
132320112475SJoe Perches	}
132448ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
132520112475SJoe Perches	return $formatted_email;
132620112475SJoe Perches}
132720112475SJoe Perches
1328dfa05c28SJoe Perchessub reformat_email {
1329dfa05c28SJoe Perches	my ($email) = @_;
1330dfa05c28SJoe Perches
1331dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
133248ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1333dfa05c28SJoe Perches}
1334dfa05c28SJoe Perches
1335dfa05c28SJoe Perchessub same_email_addresses {
1336fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1337dfa05c28SJoe Perches
1338dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1339dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1340dfa05c28SJoe Perches
134148ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
134248ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
134348ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
134448ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
134548ca2d8aSDwaipayan Ray}
1346dfa05c28SJoe Perches
1347d311cd44SJoe Perchessub which {
1348d311cd44SJoe Perches	my ($bin) = @_;
1349d311cd44SJoe Perches
1350d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1351d311cd44SJoe Perches		if (-e "$path/$bin") {
1352d311cd44SJoe Perches			return "$path/$bin";
1353d311cd44SJoe Perches		}
1354d311cd44SJoe Perches	}
1355d311cd44SJoe Perches
1356d311cd44SJoe Perches	return "";
1357d311cd44SJoe Perches}
1358d311cd44SJoe Perches
1359000d1cc1SJoe Perchessub which_conf {
1360000d1cc1SJoe Perches	my ($conf) = @_;
1361000d1cc1SJoe Perches
1362000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1363000d1cc1SJoe Perches		if (-e "$path/$conf") {
1364000d1cc1SJoe Perches			return "$path/$conf";
1365000d1cc1SJoe Perches		}
1366000d1cc1SJoe Perches	}
1367000d1cc1SJoe Perches
1368000d1cc1SJoe Perches	return "";
1369000d1cc1SJoe Perches}
1370000d1cc1SJoe Perches
13710a920b5bSAndy Whitcroftsub expand_tabs {
13720a920b5bSAndy Whitcroft	my ($str) = @_;
13730a920b5bSAndy Whitcroft
13740a920b5bSAndy Whitcroft	my $res = '';
13750a920b5bSAndy Whitcroft	my $n = 0;
13760a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
13770a920b5bSAndy Whitcroft		if ($c eq "\t") {
13780a920b5bSAndy Whitcroft			$res .= ' ';
13790a920b5bSAndy Whitcroft			$n++;
1380713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
13810a920b5bSAndy Whitcroft				$res .= ' ';
13820a920b5bSAndy Whitcroft			}
13830a920b5bSAndy Whitcroft			next;
13840a920b5bSAndy Whitcroft		}
13850a920b5bSAndy Whitcroft		$res .= $c;
13860a920b5bSAndy Whitcroft		$n++;
13870a920b5bSAndy Whitcroft	}
13880a920b5bSAndy Whitcroft
13890a920b5bSAndy Whitcroft	return $res;
13900a920b5bSAndy Whitcroft}
13916c72ffaaSAndy Whitcroftsub copy_spacing {
1392773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
13936c72ffaaSAndy Whitcroft	return $res;
13946c72ffaaSAndy Whitcroft}
13950a920b5bSAndy Whitcroft
13964a0df2efSAndy Whitcroftsub line_stats {
13974a0df2efSAndy Whitcroft	my ($line) = @_;
13984a0df2efSAndy Whitcroft
13994a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
14004a0df2efSAndy Whitcroft	$line =~ s/^.//;
14014a0df2efSAndy Whitcroft	$line = expand_tabs($line);
14024a0df2efSAndy Whitcroft
14034a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
14044a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
14054a0df2efSAndy Whitcroft
14064a0df2efSAndy Whitcroft	return (length($line), length($white));
14074a0df2efSAndy Whitcroft}
14084a0df2efSAndy Whitcroft
1409773647a0SAndy Whitcroftmy $sanitise_quote = '';
1410773647a0SAndy Whitcroft
1411773647a0SAndy Whitcroftsub sanitise_line_reset {
1412773647a0SAndy Whitcroft	my ($in_comment) = @_;
1413773647a0SAndy Whitcroft
1414773647a0SAndy Whitcroft	if ($in_comment) {
1415773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1416773647a0SAndy Whitcroft	} else {
1417773647a0SAndy Whitcroft		$sanitise_quote = '';
1418773647a0SAndy Whitcroft	}
1419773647a0SAndy Whitcroft}
142000df344fSAndy Whitcroftsub sanitise_line {
142100df344fSAndy Whitcroft	my ($line) = @_;
142200df344fSAndy Whitcroft
142300df344fSAndy Whitcroft	my $res = '';
142400df344fSAndy Whitcroft	my $l = '';
142500df344fSAndy Whitcroft
1426c2fdda0dSAndy Whitcroft	my $qlen = 0;
1427773647a0SAndy Whitcroft	my $off = 0;
1428773647a0SAndy Whitcroft	my $c;
142900df344fSAndy Whitcroft
1430773647a0SAndy Whitcroft	# Always copy over the diff marker.
1431773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1432773647a0SAndy Whitcroft
1433773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1434773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1435773647a0SAndy Whitcroft
14368d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1437773647a0SAndy Whitcroft		# and end, all to $;.
1438773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1439773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1440773647a0SAndy Whitcroft
1441773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1442773647a0SAndy Whitcroft			$off++;
144300df344fSAndy Whitcroft			next;
1444773647a0SAndy Whitcroft		}
144581bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1446773647a0SAndy Whitcroft			$sanitise_quote = '';
1447773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1448773647a0SAndy Whitcroft			$off++;
1449773647a0SAndy Whitcroft			next;
1450773647a0SAndy Whitcroft		}
1451113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1452113f04a8SDaniel Walker			$sanitise_quote = '//';
1453113f04a8SDaniel Walker
1454113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1455113f04a8SDaniel Walker			$off++;
1456113f04a8SDaniel Walker			next;
1457113f04a8SDaniel Walker		}
1458773647a0SAndy Whitcroft
1459773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1460773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1461773647a0SAndy Whitcroft		    $c eq "\\") {
1462773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1463773647a0SAndy Whitcroft			$off++;
1464773647a0SAndy Whitcroft			next;
1465773647a0SAndy Whitcroft		}
1466773647a0SAndy Whitcroft		# Regular quotes.
1467773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1468773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1469773647a0SAndy Whitcroft				$sanitise_quote = $c;
1470773647a0SAndy Whitcroft
1471773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1472773647a0SAndy Whitcroft				next;
1473773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1474773647a0SAndy Whitcroft				$sanitise_quote = '';
147500df344fSAndy Whitcroft			}
147600df344fSAndy Whitcroft		}
1477773647a0SAndy Whitcroft
1478fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1479773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1480773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1481113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1482113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1483773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1484773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
148500df344fSAndy Whitcroft		} else {
1486773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
148700df344fSAndy Whitcroft		}
1488c2fdda0dSAndy Whitcroft	}
1489c2fdda0dSAndy Whitcroft
1490113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1491113f04a8SDaniel Walker		$sanitise_quote = '';
1492113f04a8SDaniel Walker	}
1493113f04a8SDaniel Walker
1494c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1495c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1496c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1497c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1498c2fdda0dSAndy Whitcroft
1499c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1500c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1501c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1502c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1503c2fdda0dSAndy Whitcroft	}
1504c2fdda0dSAndy Whitcroft
1505dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1506dadf680dSJoe Perches		my $match = $1;
1507dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1508dadf680dSJoe Perches	}
1509dadf680dSJoe Perches
151000df344fSAndy Whitcroft	return $res;
151100df344fSAndy Whitcroft}
151200df344fSAndy Whitcroft
1513a6962d72SJoe Perchessub get_quoted_string {
1514a6962d72SJoe Perches	my ($line, $rawline) = @_;
1515a6962d72SJoe Perches
1516478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
151733acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1518a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1519a6962d72SJoe Perches}
1520a6962d72SJoe Perches
15218905a67cSAndy Whitcroftsub ctx_statement_block {
15228905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
15238905a67cSAndy Whitcroft	my $line = $linenr - 1;
15248905a67cSAndy Whitcroft	my $blk = '';
15258905a67cSAndy Whitcroft	my $soff = $off;
15268905a67cSAndy Whitcroft	my $coff = $off - 1;
1527773647a0SAndy Whitcroft	my $coff_set = 0;
15288905a67cSAndy Whitcroft
152913214adfSAndy Whitcroft	my $loff = 0;
153013214adfSAndy Whitcroft
15318905a67cSAndy Whitcroft	my $type = '';
15328905a67cSAndy Whitcroft	my $level = 0;
1533a2750645SAndy Whitcroft	my @stack = ();
1534cf655043SAndy Whitcroft	my $p;
15358905a67cSAndy Whitcroft	my $c;
15368905a67cSAndy Whitcroft	my $len = 0;
153713214adfSAndy Whitcroft
153813214adfSAndy Whitcroft	my $remainder;
15398905a67cSAndy Whitcroft	while (1) {
1540a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1541a2750645SAndy Whitcroft
1542773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
15438905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
15448905a67cSAndy Whitcroft		# context.
15458905a67cSAndy Whitcroft		if ($off >= $len) {
15468905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1547dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1548c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
15498905a67cSAndy Whitcroft				$remain--;
155013214adfSAndy Whitcroft				$loff = $len;
1551c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
15528905a67cSAndy Whitcroft				$len = length($blk);
15538905a67cSAndy Whitcroft				$line++;
15548905a67cSAndy Whitcroft				last;
15558905a67cSAndy Whitcroft			}
15568905a67cSAndy Whitcroft			# Bail if there is no further context.
15578905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
155813214adfSAndy Whitcroft			if ($off >= $len) {
15598905a67cSAndy Whitcroft				last;
15608905a67cSAndy Whitcroft			}
1561f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1562f74bd194SAndy Whitcroft				$level++;
1563f74bd194SAndy Whitcroft				$type = '#';
1564f74bd194SAndy Whitcroft			}
15658905a67cSAndy Whitcroft		}
1566cf655043SAndy Whitcroft		$p = $c;
15678905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
156813214adfSAndy Whitcroft		$remainder = substr($blk, $off);
15698905a67cSAndy Whitcroft
1570773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
15714635f4fbSAndy Whitcroft
15724635f4fbSAndy Whitcroft		# Handle nested #if/#else.
15734635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
15744635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
15754635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
15764635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
15774635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
15784635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
15794635f4fbSAndy Whitcroft		}
15804635f4fbSAndy Whitcroft
15818905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
15828905a67cSAndy Whitcroft		# outermost level.
15838905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
15848905a67cSAndy Whitcroft			last;
15858905a67cSAndy Whitcroft		}
15868905a67cSAndy Whitcroft
158713214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1588773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1589773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1590773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1591773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1592773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1593773647a0SAndy Whitcroft			$coff_set = 1;
1594773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1595773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
159613214adfSAndy Whitcroft		}
159713214adfSAndy Whitcroft
15988905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
15998905a67cSAndy Whitcroft			$level++;
16008905a67cSAndy Whitcroft			$type = '(';
16018905a67cSAndy Whitcroft		}
16028905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
16038905a67cSAndy Whitcroft			$level--;
16048905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
16058905a67cSAndy Whitcroft
16068905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
16078905a67cSAndy Whitcroft				$coff = $off;
1608773647a0SAndy Whitcroft				$coff_set = 1;
1609773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
16108905a67cSAndy Whitcroft			}
16118905a67cSAndy Whitcroft		}
16128905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
16138905a67cSAndy Whitcroft			$level++;
16148905a67cSAndy Whitcroft			$type = '{';
16158905a67cSAndy Whitcroft		}
16168905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
16178905a67cSAndy Whitcroft			$level--;
16188905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
16198905a67cSAndy Whitcroft
16208905a67cSAndy Whitcroft			if ($level == 0) {
1621b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1622b998e001SPatrick Pannuto					$off++;
1623b998e001SPatrick Pannuto				}
16248905a67cSAndy Whitcroft				last;
16258905a67cSAndy Whitcroft			}
16268905a67cSAndy Whitcroft		}
1627f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1628f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1629f74bd194SAndy Whitcroft			$level--;
1630f74bd194SAndy Whitcroft			$type = '';
1631f74bd194SAndy Whitcroft			$off++;
1632f74bd194SAndy Whitcroft			last;
1633f74bd194SAndy Whitcroft		}
16348905a67cSAndy Whitcroft		$off++;
16358905a67cSAndy Whitcroft	}
1636a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
163713214adfSAndy Whitcroft	if ($off == $len) {
1638a3bb97a7SAndy Whitcroft		$loff = $len + 1;
163913214adfSAndy Whitcroft		$line++;
164013214adfSAndy Whitcroft		$remain--;
164113214adfSAndy Whitcroft	}
16428905a67cSAndy Whitcroft
16438905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
16448905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
16458905a67cSAndy Whitcroft
16468905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
16478905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
16488905a67cSAndy Whitcroft
1649773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
165013214adfSAndy Whitcroft
165113214adfSAndy Whitcroft	return ($statement, $condition,
165213214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
165313214adfSAndy Whitcroft}
165413214adfSAndy Whitcroft
1655cf655043SAndy Whitcroftsub statement_lines {
1656cf655043SAndy Whitcroft	my ($stmt) = @_;
1657cf655043SAndy Whitcroft
1658cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1659cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1660cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1661cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1662cf655043SAndy Whitcroft
1663cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1664cf655043SAndy Whitcroft
1665cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1666cf655043SAndy Whitcroft}
1667cf655043SAndy Whitcroft
1668cf655043SAndy Whitcroftsub statement_rawlines {
1669cf655043SAndy Whitcroft	my ($stmt) = @_;
1670cf655043SAndy Whitcroft
1671cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1672cf655043SAndy Whitcroft
1673cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1674cf655043SAndy Whitcroft}
1675cf655043SAndy Whitcroft
1676cf655043SAndy Whitcroftsub statement_block_size {
1677cf655043SAndy Whitcroft	my ($stmt) = @_;
1678cf655043SAndy Whitcroft
1679cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1680cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1681cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1682cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1683cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1684cf655043SAndy Whitcroft
1685cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1686cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1687cf655043SAndy Whitcroft
1688cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1689cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1690cf655043SAndy Whitcroft
1691cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1692cf655043SAndy Whitcroft		return $stmt_lines;
1693cf655043SAndy Whitcroft	} else {
1694cf655043SAndy Whitcroft		return $stmt_statements;
1695cf655043SAndy Whitcroft	}
1696cf655043SAndy Whitcroft}
1697cf655043SAndy Whitcroft
169813214adfSAndy Whitcroftsub ctx_statement_full {
169913214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
170013214adfSAndy Whitcroft	my ($statement, $condition, $level);
170113214adfSAndy Whitcroft
170213214adfSAndy Whitcroft	my (@chunks);
170313214adfSAndy Whitcroft
1704cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
170513214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
170613214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1707773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
170813214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1709cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1710cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1711cf655043SAndy Whitcroft	}
1712cf655043SAndy Whitcroft
1713cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1714cf655043SAndy Whitcroft	# could continue the statement.
1715cf655043SAndy Whitcroft	for (;;) {
171613214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
171713214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1718cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1719773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1720cf655043SAndy Whitcroft		#print "C: push\n";
1721cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
172213214adfSAndy Whitcroft	}
172313214adfSAndy Whitcroft
172413214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
17258905a67cSAndy Whitcroft}
17268905a67cSAndy Whitcroft
17274a0df2efSAndy Whitcroftsub ctx_block_get {
1728f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
17294a0df2efSAndy Whitcroft	my $line;
17304a0df2efSAndy Whitcroft	my $start = $linenr - 1;
17314a0df2efSAndy Whitcroft	my $blk = '';
17324a0df2efSAndy Whitcroft	my @o;
17334a0df2efSAndy Whitcroft	my @c;
17344a0df2efSAndy Whitcroft	my @res = ();
17354a0df2efSAndy Whitcroft
1736f0a594c1SAndy Whitcroft	my $level = 0;
17374635f4fbSAndy Whitcroft	my @stack = ($level);
173800df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
173900df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
174000df344fSAndy Whitcroft		$remain--;
174100df344fSAndy Whitcroft
174200df344fSAndy Whitcroft		$blk .= $rawlines[$line];
17434635f4fbSAndy Whitcroft
17444635f4fbSAndy Whitcroft		# Handle nested #if/#else.
174501464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
17464635f4fbSAndy Whitcroft			push(@stack, $level);
174701464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
17484635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
174901464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
17504635f4fbSAndy Whitcroft			$level = pop(@stack);
17514635f4fbSAndy Whitcroft		}
17524635f4fbSAndy Whitcroft
175301464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1754f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1755f0a594c1SAndy Whitcroft			if ($off > 0) {
1756f0a594c1SAndy Whitcroft				$off--;
1757f0a594c1SAndy Whitcroft				next;
1758f0a594c1SAndy Whitcroft			}
17594a0df2efSAndy Whitcroft
1760f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1761f0a594c1SAndy Whitcroft				$level--;
1762f0a594c1SAndy Whitcroft				last if ($level == 0);
1763f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1764f0a594c1SAndy Whitcroft				$level++;
1765f0a594c1SAndy Whitcroft			}
1766f0a594c1SAndy Whitcroft		}
17674a0df2efSAndy Whitcroft
1768f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
176900df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
17704a0df2efSAndy Whitcroft		}
17714a0df2efSAndy Whitcroft
1772f0a594c1SAndy Whitcroft		last if ($level == 0);
17734a0df2efSAndy Whitcroft	}
17744a0df2efSAndy Whitcroft
1775f0a594c1SAndy Whitcroft	return ($level, @res);
17764a0df2efSAndy Whitcroft}
17774a0df2efSAndy Whitcroftsub ctx_block_outer {
17784a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
17794a0df2efSAndy Whitcroft
1780f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1781f0a594c1SAndy Whitcroft	return @r;
17824a0df2efSAndy Whitcroft}
17834a0df2efSAndy Whitcroftsub ctx_block {
17844a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
17854a0df2efSAndy Whitcroft
1786f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1787f0a594c1SAndy Whitcroft	return @r;
1788653d4876SAndy Whitcroft}
1789653d4876SAndy Whitcroftsub ctx_statement {
1790f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1791f0a594c1SAndy Whitcroft
1792f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1793f0a594c1SAndy Whitcroft	return @r;
1794f0a594c1SAndy Whitcroft}
1795f0a594c1SAndy Whitcroftsub ctx_block_level {
1796653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1797653d4876SAndy Whitcroft
1798f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
17994a0df2efSAndy Whitcroft}
18009c0ca6f9SAndy Whitcroftsub ctx_statement_level {
18019c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
18029c0ca6f9SAndy Whitcroft
18039c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
18049c0ca6f9SAndy Whitcroft}
18054a0df2efSAndy Whitcroft
18064a0df2efSAndy Whitcroftsub ctx_locate_comment {
18074a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
18084a0df2efSAndy Whitcroft
1809a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1810a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1811a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1812a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1813a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1814a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1815a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1816a55ee0ccSJoe Perches
18174a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1818a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
18194a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
18204a0df2efSAndy Whitcroft
18214a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
18224a0df2efSAndy Whitcroft	# comment.
18234a0df2efSAndy Whitcroft	my $in_comment = 0;
18244a0df2efSAndy Whitcroft	$current_comment = '';
18254a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
182600df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
182700df344fSAndy Whitcroft		#warn "           $line\n";
18284a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
18294a0df2efSAndy Whitcroft			$in_comment = 1;
18304a0df2efSAndy Whitcroft		}
18314a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
18324a0df2efSAndy Whitcroft			$in_comment = 1;
18334a0df2efSAndy Whitcroft		}
18344a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
18354a0df2efSAndy Whitcroft			$current_comment = '';
18364a0df2efSAndy Whitcroft		}
18374a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
18384a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
18394a0df2efSAndy Whitcroft			$in_comment = 0;
18404a0df2efSAndy Whitcroft		}
18414a0df2efSAndy Whitcroft	}
18424a0df2efSAndy Whitcroft
18434a0df2efSAndy Whitcroft	chomp($current_comment);
18444a0df2efSAndy Whitcroft	return($current_comment);
18454a0df2efSAndy Whitcroft}
18464a0df2efSAndy Whitcroftsub ctx_has_comment {
18474a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
18484a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
18494a0df2efSAndy Whitcroft
185000df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
18514a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
18524a0df2efSAndy Whitcroft
18534a0df2efSAndy Whitcroft	return ($cmt ne '');
18544a0df2efSAndy Whitcroft}
18554a0df2efSAndy Whitcroft
18564d001e4dSAndy Whitcroftsub raw_line {
18574d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
18584d001e4dSAndy Whitcroft
18594d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
18604d001e4dSAndy Whitcroft	$cnt++;
18614d001e4dSAndy Whitcroft
18624d001e4dSAndy Whitcroft	my $line;
18634d001e4dSAndy Whitcroft	while ($cnt) {
18644d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
18654d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
18664d001e4dSAndy Whitcroft		$cnt--;
18674d001e4dSAndy Whitcroft	}
18684d001e4dSAndy Whitcroft
18694d001e4dSAndy Whitcroft	return $line;
18704d001e4dSAndy Whitcroft}
18714d001e4dSAndy Whitcroft
18722a9f9d85STobin C. Hardingsub get_stat_real {
18732a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
18742a9f9d85STobin C. Harding
18752a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
18762a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
18772a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
18782a9f9d85STobin C. Harding	}
18792a9f9d85STobin C. Harding
18802a9f9d85STobin C. Harding	return $stat_real;
18812a9f9d85STobin C. Harding}
18822a9f9d85STobin C. Harding
1883e3d95a2aSTobin C. Hardingsub get_stat_here {
1884e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1885e3d95a2aSTobin C. Harding
1886e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1887e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1888e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1889e3d95a2aSTobin C. Harding	}
1890e3d95a2aSTobin C. Harding
1891e3d95a2aSTobin C. Harding	return $herectx;
1892e3d95a2aSTobin C. Harding}
1893e3d95a2aSTobin C. Harding
18940a920b5bSAndy Whitcroftsub cat_vet {
18950a920b5bSAndy Whitcroft	my ($vet) = @_;
18969c0ca6f9SAndy Whitcroft	my ($res, $coded);
18970a920b5bSAndy Whitcroft
18989c0ca6f9SAndy Whitcroft	$res = '';
18996c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
19006c72ffaaSAndy Whitcroft		$res .= $1;
19016c72ffaaSAndy Whitcroft		if ($2 ne '') {
19029c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
19036c72ffaaSAndy Whitcroft			$res .= $coded;
19046c72ffaaSAndy Whitcroft		}
19059c0ca6f9SAndy Whitcroft	}
19069c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
19070a920b5bSAndy Whitcroft
19089c0ca6f9SAndy Whitcroft	return $res;
19090a920b5bSAndy Whitcroft}
19100a920b5bSAndy Whitcroft
1911c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1912cf655043SAndy Whitcroftmy $av_pending;
1913c2fdda0dSAndy Whitcroftmy @av_paren_type;
19141f65f947SAndy Whitcroftmy $av_pend_colon;
1915c2fdda0dSAndy Whitcroft
1916c2fdda0dSAndy Whitcroftsub annotate_reset {
1917c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1918cf655043SAndy Whitcroft	$av_pending = '_';
1919cf655043SAndy Whitcroft	@av_paren_type = ('E');
19201f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1921c2fdda0dSAndy Whitcroft}
1922c2fdda0dSAndy Whitcroft
19236c72ffaaSAndy Whitcroftsub annotate_values {
19246c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
19256c72ffaaSAndy Whitcroft
19266c72ffaaSAndy Whitcroft	my $res;
19271f65f947SAndy Whitcroft	my $var = '_' x length($stream);
19286c72ffaaSAndy Whitcroft	my $cur = $stream;
19296c72ffaaSAndy Whitcroft
1930c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
19316c72ffaaSAndy Whitcroft
19326c72ffaaSAndy Whitcroft	while (length($cur)) {
1933773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1934cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1935171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
19366c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1937c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1938c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1939cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1940c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
19416c72ffaaSAndy Whitcroft			}
19426c72ffaaSAndy Whitcroft
1943c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
19449446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
19459446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1946addcdceaSAndy Whitcroft			$type = 'c';
19479446ef56SAndy Whitcroft
1948e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1949c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
19506c72ffaaSAndy Whitcroft			$type = 'T';
19516c72ffaaSAndy Whitcroft
1952389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1953389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1954389a2fe5SAndy Whitcroft			$type = 'T';
1955389a2fe5SAndy Whitcroft
1956c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1957171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1958c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1959171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1960171ae1a4SAndy Whitcroft			if ($2 ne '') {
1961cf655043SAndy Whitcroft				$av_pending = 'N';
1962171ae1a4SAndy Whitcroft			}
1963171ae1a4SAndy Whitcroft			$type = 'E';
1964171ae1a4SAndy Whitcroft
1965c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1966171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1967171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1968171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
19696c72ffaaSAndy Whitcroft
1970c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1971cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1972c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1973cf655043SAndy Whitcroft
1974cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1975cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1976171ae1a4SAndy Whitcroft			$type = 'E';
1977cf655043SAndy Whitcroft
1978c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1979cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1980cf655043SAndy Whitcroft			$av_preprocessor = 1;
1981cf655043SAndy Whitcroft
1982cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1983cf655043SAndy Whitcroft
1984171ae1a4SAndy Whitcroft			$type = 'E';
1985cf655043SAndy Whitcroft
1986c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1987cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1988cf655043SAndy Whitcroft
1989cf655043SAndy Whitcroft			$av_preprocessor = 1;
1990cf655043SAndy Whitcroft
1991cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1992cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1993cf655043SAndy Whitcroft			pop(@av_paren_type);
1994cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1995171ae1a4SAndy Whitcroft			$type = 'E';
19966c72ffaaSAndy Whitcroft
19976c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1998c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
19996c72ffaaSAndy Whitcroft
2000171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2001171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2002171ae1a4SAndy Whitcroft			$av_pending = $type;
2003171ae1a4SAndy Whitcroft			$type = 'N';
2004171ae1a4SAndy Whitcroft
20056c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2006c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
20076c72ffaaSAndy Whitcroft			if (defined $2) {
2008cf655043SAndy Whitcroft				$av_pending = 'V';
20096c72ffaaSAndy Whitcroft			}
20106c72ffaaSAndy Whitcroft			$type = 'N';
20116c72ffaaSAndy Whitcroft
201214b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2013c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
201414b111c1SAndy Whitcroft			$av_pending = 'E';
20156c72ffaaSAndy Whitcroft			$type = 'N';
20166c72ffaaSAndy Whitcroft
20171f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
20181f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
20191f65f947SAndy Whitcroft			$av_pend_colon = 'C';
20201f65f947SAndy Whitcroft			$type = 'N';
20211f65f947SAndy Whitcroft
202214b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2023c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
20246c72ffaaSAndy Whitcroft			$type = 'N';
20256c72ffaaSAndy Whitcroft
20266c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2027c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2028cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2029cf655043SAndy Whitcroft			$av_pending = '_';
20306c72ffaaSAndy Whitcroft			$type = 'N';
20316c72ffaaSAndy Whitcroft
20326c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2033cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2034cf655043SAndy Whitcroft			if ($new_type ne '_') {
2035cf655043SAndy Whitcroft				$type = $new_type;
2036c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2037c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
20386c72ffaaSAndy Whitcroft			} else {
2039c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
20406c72ffaaSAndy Whitcroft			}
20416c72ffaaSAndy Whitcroft
2042c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2043c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2044c8cb2ca3SAndy Whitcroft			$type = 'V';
2045cf655043SAndy Whitcroft			$av_pending = 'V';
20466c72ffaaSAndy Whitcroft
20478e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
20488e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
20491f65f947SAndy Whitcroft				$av_pend_colon = 'B';
20508e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
20518e761b04SAndy Whitcroft				$av_pend_colon = 'L';
20521f65f947SAndy Whitcroft			}
20531f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
20541f65f947SAndy Whitcroft			$type = 'V';
20551f65f947SAndy Whitcroft
20566c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2057c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
20586c72ffaaSAndy Whitcroft			$type = 'V';
20596c72ffaaSAndy Whitcroft
20606c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2061c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
20626c72ffaaSAndy Whitcroft			$type = 'N';
20636c72ffaaSAndy Whitcroft
2064cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2065c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
206613214adfSAndy Whitcroft			$type = 'E';
20671f65f947SAndy Whitcroft			$av_pend_colon = 'O';
206813214adfSAndy Whitcroft
20698e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
20708e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
20718e761b04SAndy Whitcroft			$type = 'C';
20728e761b04SAndy Whitcroft
20731f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
20741f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
20751f65f947SAndy Whitcroft			$type = 'N';
20761f65f947SAndy Whitcroft
20771f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
20781f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
20791f65f947SAndy Whitcroft
20801f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
20811f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
20821f65f947SAndy Whitcroft				$type = 'E';
20831f65f947SAndy Whitcroft			} else {
20841f65f947SAndy Whitcroft				$type = 'N';
20851f65f947SAndy Whitcroft			}
20861f65f947SAndy Whitcroft			$av_pend_colon = 'O';
20871f65f947SAndy Whitcroft
20888e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
208913214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
20906c72ffaaSAndy Whitcroft			$type = 'N';
20916c72ffaaSAndy Whitcroft
20920d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
209374048ed8SAndy Whitcroft			my $variant;
209474048ed8SAndy Whitcroft
209574048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
209674048ed8SAndy Whitcroft			if ($type eq 'V') {
209774048ed8SAndy Whitcroft				$variant = 'B';
209874048ed8SAndy Whitcroft			} else {
209974048ed8SAndy Whitcroft				$variant = 'U';
210074048ed8SAndy Whitcroft			}
210174048ed8SAndy Whitcroft
210274048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
210374048ed8SAndy Whitcroft			$type = 'N';
210474048ed8SAndy Whitcroft
21056c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2106c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
21076c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
21086c72ffaaSAndy Whitcroft				$type = 'N';
21096c72ffaaSAndy Whitcroft			}
21106c72ffaaSAndy Whitcroft
21116c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2112c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
21136c72ffaaSAndy Whitcroft		}
21146c72ffaaSAndy Whitcroft		if (defined $1) {
21156c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
21166c72ffaaSAndy Whitcroft			$res .= $type x length($1);
21176c72ffaaSAndy Whitcroft		}
21186c72ffaaSAndy Whitcroft	}
21196c72ffaaSAndy Whitcroft
21201f65f947SAndy Whitcroft	return ($res, $var);
21216c72ffaaSAndy Whitcroft}
21226c72ffaaSAndy Whitcroft
21238905a67cSAndy Whitcroftsub possible {
212413214adfSAndy Whitcroft	my ($possible, $line) = @_;
21259a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
21260776e594SAndy Whitcroft		^(?:
21270776e594SAndy Whitcroft			$Modifier|
21280776e594SAndy Whitcroft			$Storage|
21290776e594SAndy Whitcroft			$Type|
21309a974fdbSAndy Whitcroft			DEFINE_\S+
21319a974fdbSAndy Whitcroft		)$|
21329a974fdbSAndy Whitcroft		^(?:
21330776e594SAndy Whitcroft			goto|
21340776e594SAndy Whitcroft			return|
21350776e594SAndy Whitcroft			case|
21360776e594SAndy Whitcroft			else|
21370776e594SAndy Whitcroft			asm|__asm__|
213889a88353SAndy Whitcroft			do|
213989a88353SAndy Whitcroft			\#|
214089a88353SAndy Whitcroft			\#\#|
21419a974fdbSAndy Whitcroft		)(?:\s|$)|
21420776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
21439a974fdbSAndy Whitcroft	    )}x;
21449a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
21459a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2146c45dcabdSAndy Whitcroft		# Check for modifiers.
2147c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2148c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2149c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2150c45dcabdSAndy Whitcroft
2151c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2152c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2153d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
21549a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2155d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2156485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2157d2506586SAndy Whitcroft				}
21589a974fdbSAndy Whitcroft			}
2159c45dcabdSAndy Whitcroft
2160c45dcabdSAndy Whitcroft		} else {
216113214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2162485ff23eSAlex Dowad			push(@typeListFile, $possible);
2163c45dcabdSAndy Whitcroft		}
21648905a67cSAndy Whitcroft		build_types();
21650776e594SAndy Whitcroft	} else {
21660776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
21678905a67cSAndy Whitcroft	}
21688905a67cSAndy Whitcroft}
21698905a67cSAndy Whitcroft
21706c72ffaaSAndy Whitcroftmy $prefix = '';
21716c72ffaaSAndy Whitcroft
2172000d1cc1SJoe Perchessub show_type {
2173cbec18afSJoe Perches	my ($type) = @_;
217491bfe484SJoe Perches
2175522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2176522b837cSAlexey Dobriyan
2177cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2178cbec18afSJoe Perches
2179cbec18afSJoe Perches	return !defined $ignore_type{$type};
2180000d1cc1SJoe Perches}
2181000d1cc1SJoe Perches
2182f0a594c1SAndy Whitcroftsub report {
2183cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2184cbec18afSJoe Perches
2185cbec18afSJoe Perches	if (!show_type($type) ||
2186cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2187773647a0SAndy Whitcroft		return 0;
2188773647a0SAndy Whitcroft	}
218957230297SJoe Perches	my $output = '';
2190737c0767SJohn Brooks	if ($color) {
219157230297SJoe Perches		if ($level eq 'ERROR') {
219257230297SJoe Perches			$output .= RED;
219357230297SJoe Perches		} elsif ($level eq 'WARNING') {
219457230297SJoe Perches			$output .= YELLOW;
2195000d1cc1SJoe Perches		} else {
219657230297SJoe Perches			$output .= GREEN;
2197000d1cc1SJoe Perches		}
219857230297SJoe Perches	}
219957230297SJoe Perches	$output .= $prefix . $level . ':';
220057230297SJoe Perches	if ($show_types) {
2201737c0767SJohn Brooks		$output .= BLUE if ($color);
220257230297SJoe Perches		$output .= "$type:";
220357230297SJoe Perches	}
2204737c0767SJohn Brooks	$output .= RESET if ($color);
220557230297SJoe Perches	$output .= ' ' . $msg . "\n";
220634d8815fSJoe Perches
220734d8815fSJoe Perches	if ($showfile) {
220834d8815fSJoe Perches		my @lines = split("\n", $output, -1);
220934d8815fSJoe Perches		splice(@lines, 1, 1);
221034d8815fSJoe Perches		$output = join("\n", @lines);
221134d8815fSJoe Perches	}
221257230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
22138905a67cSAndy Whitcroft
221457230297SJoe Perches	push(our @report, $output);
2215773647a0SAndy Whitcroft
2216773647a0SAndy Whitcroft	return 1;
2217f0a594c1SAndy Whitcroft}
2218cbec18afSJoe Perches
2219f0a594c1SAndy Whitcroftsub report_dump {
222013214adfSAndy Whitcroft	our @report;
2221f0a594c1SAndy Whitcroft}
2222000d1cc1SJoe Perches
2223d752fcc8SJoe Perchessub fixup_current_range {
2224d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2225d752fcc8SJoe Perches
2226d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2227d752fcc8SJoe Perches		my $o = $1;
2228d752fcc8SJoe Perches		my $l = $2;
2229d752fcc8SJoe Perches		my $no = $o + $offset;
2230d752fcc8SJoe Perches		my $nl = $l + $length;
2231d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2232d752fcc8SJoe Perches	}
2233d752fcc8SJoe Perches}
2234d752fcc8SJoe Perches
2235d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2236d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2237d752fcc8SJoe Perches
2238d752fcc8SJoe Perches	my $range_last_linenr = 0;
2239d752fcc8SJoe Perches	my $delta_offset = 0;
2240d752fcc8SJoe Perches
2241d752fcc8SJoe Perches	my $old_linenr = 0;
2242d752fcc8SJoe Perches	my $new_linenr = 0;
2243d752fcc8SJoe Perches
2244d752fcc8SJoe Perches	my $next_insert = 0;
2245d752fcc8SJoe Perches	my $next_delete = 0;
2246d752fcc8SJoe Perches
2247d752fcc8SJoe Perches	my @lines = ();
2248d752fcc8SJoe Perches
2249d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2250d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2251d752fcc8SJoe Perches
2252d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2253d752fcc8SJoe Perches		my $save_line = 1;
2254d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2255323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2256d752fcc8SJoe Perches			$delta_offset = 0;
2257d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2258d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2259d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2260d752fcc8SJoe Perches		}
2261d752fcc8SJoe Perches
2262d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2263d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2264d752fcc8SJoe Perches			$save_line = 0;
2265d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2266d752fcc8SJoe Perches		}
2267d752fcc8SJoe Perches
2268d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2269d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2270d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2271d752fcc8SJoe Perches			$new_linenr++;
2272d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2273d752fcc8SJoe Perches		}
2274d752fcc8SJoe Perches
2275d752fcc8SJoe Perches		if ($save_line) {
2276d752fcc8SJoe Perches			push(@lines, $line);
2277d752fcc8SJoe Perches			$new_linenr++;
2278d752fcc8SJoe Perches		}
2279d752fcc8SJoe Perches
2280d752fcc8SJoe Perches		$old_linenr++;
2281d752fcc8SJoe Perches	}
2282d752fcc8SJoe Perches
2283d752fcc8SJoe Perches	return @lines;
2284d752fcc8SJoe Perches}
2285d752fcc8SJoe Perches
2286f2d7e4d4SJoe Perchessub fix_insert_line {
2287f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2288f2d7e4d4SJoe Perches
2289f2d7e4d4SJoe Perches	my $inserted = {
2290f2d7e4d4SJoe Perches		LINENR => $linenr,
2291f2d7e4d4SJoe Perches		LINE => $line,
2292f2d7e4d4SJoe Perches	};
2293f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2294f2d7e4d4SJoe Perches}
2295f2d7e4d4SJoe Perches
2296f2d7e4d4SJoe Perchessub fix_delete_line {
2297f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2298f2d7e4d4SJoe Perches
2299f2d7e4d4SJoe Perches	my $deleted = {
2300f2d7e4d4SJoe Perches		LINENR => $linenr,
2301f2d7e4d4SJoe Perches		LINE => $line,
2302f2d7e4d4SJoe Perches	};
2303f2d7e4d4SJoe Perches
2304f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2305f2d7e4d4SJoe Perches}
2306f2d7e4d4SJoe Perches
2307de7d4f0eSAndy Whitcroftsub ERROR {
2308cbec18afSJoe Perches	my ($type, $msg) = @_;
2309cbec18afSJoe Perches
2310cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2311de7d4f0eSAndy Whitcroft		our $clean = 0;
23126c72ffaaSAndy Whitcroft		our $cnt_error++;
23133705ce5bSJoe Perches		return 1;
2314de7d4f0eSAndy Whitcroft	}
23153705ce5bSJoe Perches	return 0;
2316773647a0SAndy Whitcroft}
2317de7d4f0eSAndy Whitcroftsub WARN {
2318cbec18afSJoe Perches	my ($type, $msg) = @_;
2319cbec18afSJoe Perches
2320cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2321de7d4f0eSAndy Whitcroft		our $clean = 0;
23226c72ffaaSAndy Whitcroft		our $cnt_warn++;
23233705ce5bSJoe Perches		return 1;
2324de7d4f0eSAndy Whitcroft	}
23253705ce5bSJoe Perches	return 0;
2326773647a0SAndy Whitcroft}
2327de7d4f0eSAndy Whitcroftsub CHK {
2328cbec18afSJoe Perches	my ($type, $msg) = @_;
2329cbec18afSJoe Perches
2330cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2331de7d4f0eSAndy Whitcroft		our $clean = 0;
23326c72ffaaSAndy Whitcroft		our $cnt_chk++;
23333705ce5bSJoe Perches		return 1;
23346c72ffaaSAndy Whitcroft	}
23353705ce5bSJoe Perches	return 0;
2336de7d4f0eSAndy Whitcroft}
2337de7d4f0eSAndy Whitcroft
23386ecd9674SAndy Whitcroftsub check_absolute_file {
23396ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
23406ecd9674SAndy Whitcroft	my $file = $absolute;
23416ecd9674SAndy Whitcroft
23426ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
23436ecd9674SAndy Whitcroft
23446ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
23456ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
23466ecd9674SAndy Whitcroft		if (-f "$root/$file") {
23476ecd9674SAndy Whitcroft			##print "file<$file>\n";
23486ecd9674SAndy Whitcroft			last;
23496ecd9674SAndy Whitcroft		}
23506ecd9674SAndy Whitcroft	}
23516ecd9674SAndy Whitcroft	if (! -f _)  {
23526ecd9674SAndy Whitcroft		return 0;
23536ecd9674SAndy Whitcroft	}
23546ecd9674SAndy Whitcroft
23556ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
23566ecd9674SAndy Whitcroft	my $prefix = $absolute;
23576ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
23586ecd9674SAndy Whitcroft
23596ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
23606ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2361000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2362000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
23636ecd9674SAndy Whitcroft	}
23646ecd9674SAndy Whitcroft}
23656ecd9674SAndy Whitcroft
23663705ce5bSJoe Perchessub trim {
23673705ce5bSJoe Perches	my ($string) = @_;
23683705ce5bSJoe Perches
2369b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2370b34c648bSJoe Perches
2371b34c648bSJoe Perches	return $string;
2372b34c648bSJoe Perches}
2373b34c648bSJoe Perches
2374b34c648bSJoe Perchessub ltrim {
2375b34c648bSJoe Perches	my ($string) = @_;
2376b34c648bSJoe Perches
2377b34c648bSJoe Perches	$string =~ s/^\s+//;
2378b34c648bSJoe Perches
2379b34c648bSJoe Perches	return $string;
2380b34c648bSJoe Perches}
2381b34c648bSJoe Perches
2382b34c648bSJoe Perchessub rtrim {
2383b34c648bSJoe Perches	my ($string) = @_;
2384b34c648bSJoe Perches
2385b34c648bSJoe Perches	$string =~ s/\s+$//;
23863705ce5bSJoe Perches
23873705ce5bSJoe Perches	return $string;
23883705ce5bSJoe Perches}
23893705ce5bSJoe Perches
239052ea8506SJoe Perchessub string_find_replace {
239152ea8506SJoe Perches	my ($string, $find, $replace) = @_;
239252ea8506SJoe Perches
239352ea8506SJoe Perches	$string =~ s/$find/$replace/g;
239452ea8506SJoe Perches
239552ea8506SJoe Perches	return $string;
239652ea8506SJoe Perches}
239752ea8506SJoe Perches
23983705ce5bSJoe Perchessub tabify {
23993705ce5bSJoe Perches	my ($leading) = @_;
24003705ce5bSJoe Perches
2401713a09deSAntonio Borneo	my $source_indent = $tabsize;
24023705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
24033705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
24043705ce5bSJoe Perches
24053705ce5bSJoe Perches	#convert leading spaces to tabs
24063705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
24073705ce5bSJoe Perches	#Remove spaces before a tab
24083705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
24093705ce5bSJoe Perches
24103705ce5bSJoe Perches	return "$leading";
24113705ce5bSJoe Perches}
24123705ce5bSJoe Perches
2413d1fe9c09SJoe Perchessub pos_last_openparen {
2414d1fe9c09SJoe Perches	my ($line) = @_;
2415d1fe9c09SJoe Perches
2416d1fe9c09SJoe Perches	my $pos = 0;
2417d1fe9c09SJoe Perches
2418d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2419d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2420d1fe9c09SJoe Perches
2421d1fe9c09SJoe Perches	my $last_openparen = 0;
2422d1fe9c09SJoe Perches
2423d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2424d1fe9c09SJoe Perches		return -1;
2425d1fe9c09SJoe Perches	}
2426d1fe9c09SJoe Perches
2427d1fe9c09SJoe Perches	my $len = length($line);
2428d1fe9c09SJoe Perches
2429d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2430d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2431d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2432d1fe9c09SJoe Perches			$pos += length($1) - 1;
2433d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2434d1fe9c09SJoe Perches			$last_openparen = $pos;
2435d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2436d1fe9c09SJoe Perches			last;
2437d1fe9c09SJoe Perches		}
2438d1fe9c09SJoe Perches	}
2439d1fe9c09SJoe Perches
244091cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2441d1fe9c09SJoe Perches}
2442d1fe9c09SJoe Perches
2443f36d3eb8SJoe Perchessub get_raw_comment {
2444f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2445f36d3eb8SJoe Perches	my $comment = '';
2446f36d3eb8SJoe Perches
2447f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2448f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2449f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2450f36d3eb8SJoe Perches		}
2451f36d3eb8SJoe Perches	}
2452f36d3eb8SJoe Perches
2453f36d3eb8SJoe Perches	return $comment;
2454f36d3eb8SJoe Perches}
2455f36d3eb8SJoe Perches
24560a920b5bSAndy Whitcroftsub process {
24570a920b5bSAndy Whitcroft	my $filename = shift;
24580a920b5bSAndy Whitcroft
24590a920b5bSAndy Whitcroft	my $linenr=0;
24600a920b5bSAndy Whitcroft	my $prevline="";
2461c2fdda0dSAndy Whitcroft	my $prevrawline="";
24620a920b5bSAndy Whitcroft	my $stashline="";
2463c2fdda0dSAndy Whitcroft	my $stashrawline="";
24640a920b5bSAndy Whitcroft
24654a0df2efSAndy Whitcroft	my $length;
24660a920b5bSAndy Whitcroft	my $indent;
24670a920b5bSAndy Whitcroft	my $previndent=0;
24680a920b5bSAndy Whitcroft	my $stashindent=0;
24690a920b5bSAndy Whitcroft
2470de7d4f0eSAndy Whitcroft	our $clean = 1;
24710a920b5bSAndy Whitcroft	my $signoff = 0;
2472cd261496SGeert Uytterhoeven	my $author = '';
2473cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
247448ca2d8aSDwaipayan Ray	my $author_sob = '';
24750a920b5bSAndy Whitcroft	my $is_patch = 0;
2476133712a2SRob Herring	my $is_binding_patch = -1;
247729ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
247815662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
247944d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2480ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2481490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2482bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
24832a076f40SJoe Perches	my $commit_log_long_line = 0;
2484e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
248513f1937eSJoe Perches	my $reported_maintainer_file = 0;
2486fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2487fa64205dSPasi Savanainen
2488365dd4eaSJoe Perches	my $last_blank_line = 0;
24895e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2490365dd4eaSJoe Perches
249113214adfSAndy Whitcroft	our @report = ();
24926c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
24936c72ffaaSAndy Whitcroft	our $cnt_error = 0;
24946c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
24956c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
24966c72ffaaSAndy Whitcroft
24970a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
24980a920b5bSAndy Whitcroft	my $realfile = '';
24990a920b5bSAndy Whitcroft	my $realline = 0;
25000a920b5bSAndy Whitcroft	my $realcnt = 0;
25010a920b5bSAndy Whitcroft	my $here = '';
250277cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
25030a920b5bSAndy Whitcroft	my $in_comment = 0;
2504c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
25050a920b5bSAndy Whitcroft	my $first_line = 0;
25061e855726SWolfram Sang	my $p1_prefix = '';
25070a920b5bSAndy Whitcroft
250813214adfSAndy Whitcroft	my $prev_values = 'E';
250913214adfSAndy Whitcroft
251013214adfSAndy Whitcroft	# suppression flags
2511773647a0SAndy Whitcroft	my %suppress_ifbraces;
2512170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
25132b474a1aSAndy Whitcroft	my %suppress_export;
25143e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2515653d4876SAndy Whitcroft
25167e51f197SJoe Perches	my %signatures = ();
2517323c1260SJoe Perches
2518c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2519de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2520c2fdda0dSAndy Whitcroft	#
2521de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2522de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2523773647a0SAndy Whitcroft
2524d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2525d8b07710SJoe Perches
25269f3a8992SRob Herring	my $checklicenseline = 1;
25279f3a8992SRob Herring
2528773647a0SAndy Whitcroft	sanitise_line_reset();
2529c2fdda0dSAndy Whitcroft	my $line;
2530c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2531773647a0SAndy Whitcroft		$linenr++;
2532773647a0SAndy Whitcroft		$line = $rawline;
2533c2fdda0dSAndy Whitcroft
25343705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
25353705ce5bSJoe Perches
2536773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2537de7d4f0eSAndy Whitcroft			$setup_docs = 0;
25382581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2539de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2540de7d4f0eSAndy Whitcroft			}
2541773647a0SAndy Whitcroft			#next;
2542de7d4f0eSAndy Whitcroft		}
254374fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2544773647a0SAndy Whitcroft			$realline=$1-1;
2545773647a0SAndy Whitcroft			if (defined $2) {
2546773647a0SAndy Whitcroft				$realcnt=$3+1;
2547773647a0SAndy Whitcroft			} else {
2548773647a0SAndy Whitcroft				$realcnt=1+1;
2549773647a0SAndy Whitcroft			}
2550c45dcabdSAndy Whitcroft			$in_comment = 0;
2551773647a0SAndy Whitcroft
2552773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2553773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2554773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2555773647a0SAndy Whitcroft			# at context start.
2556773647a0SAndy Whitcroft			my $edge;
255701fa9147SAndy Whitcroft			my $cnt = $realcnt;
255801fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
255901fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
256001fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
256101fa9147SAndy Whitcroft				$cnt--;
256201fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2563721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2564fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2565fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2566fae17daeSAndy Whitcroft					($edge) = $1;
2567fae17daeSAndy Whitcroft					last;
2568fae17daeSAndy Whitcroft				}
2569773647a0SAndy Whitcroft			}
2570773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2571773647a0SAndy Whitcroft				$in_comment = 1;
2572773647a0SAndy Whitcroft			}
2573773647a0SAndy Whitcroft
2574773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2575773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2576773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2577773647a0SAndy Whitcroft			if (!defined $edge &&
257883242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2579773647a0SAndy Whitcroft			{
2580773647a0SAndy Whitcroft				$in_comment = 1;
2581773647a0SAndy Whitcroft			}
2582773647a0SAndy Whitcroft
2583773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2584773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2585773647a0SAndy Whitcroft
2586171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2587773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2588171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2589773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2590773647a0SAndy Whitcroft		}
2591773647a0SAndy Whitcroft		push(@lines, $line);
2592773647a0SAndy Whitcroft
2593773647a0SAndy Whitcroft		if ($realcnt > 1) {
2594773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2595773647a0SAndy Whitcroft		} else {
2596773647a0SAndy Whitcroft			$realcnt = 0;
2597773647a0SAndy Whitcroft		}
2598773647a0SAndy Whitcroft
2599773647a0SAndy Whitcroft		#print "==>$rawline\n";
2600773647a0SAndy Whitcroft		#print "-->$line\n";
2601de7d4f0eSAndy Whitcroft
2602de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2603de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2604de7d4f0eSAndy Whitcroft		}
2605de7d4f0eSAndy Whitcroft	}
2606de7d4f0eSAndy Whitcroft
26076c72ffaaSAndy Whitcroft	$prefix = '';
26086c72ffaaSAndy Whitcroft
2609773647a0SAndy Whitcroft	$realcnt = 0;
2610773647a0SAndy Whitcroft	$linenr = 0;
2611194f66fcSJoe Perches	$fixlinenr = -1;
26120a920b5bSAndy Whitcroft	foreach my $line (@lines) {
26130a920b5bSAndy Whitcroft		$linenr++;
2614194f66fcSJoe Perches		$fixlinenr++;
26151b5539b1SJoe Perches		my $sline = $line;	#copy of $line
26161b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
26170a920b5bSAndy Whitcroft
2618c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2619f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
26206c72ffaaSAndy Whitcroft
262112c253abSJoe Perches# check if it's a mode change, rename or start of a patch
262212c253abSJoe Perches		if (!$in_commit_log &&
262312c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
262412c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
262512c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
262612c253abSJoe Perches			$is_patch = 1;
262712c253abSJoe Perches		}
262812c253abSJoe Perches
26290a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2630e518e9a5SJoe Perches		if (!$in_commit_log &&
263174fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
263274fd4f34SJoe Perches			my $context = $4;
26330a920b5bSAndy Whitcroft			$is_patch = 1;
26344a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
26350a920b5bSAndy Whitcroft			$realline=$1-1;
26360a920b5bSAndy Whitcroft			if (defined $2) {
26370a920b5bSAndy Whitcroft				$realcnt=$3+1;
26380a920b5bSAndy Whitcroft			} else {
26390a920b5bSAndy Whitcroft				$realcnt=1+1;
26400a920b5bSAndy Whitcroft			}
2641c2fdda0dSAndy Whitcroft			annotate_reset();
264213214adfSAndy Whitcroft			$prev_values = 'E';
264313214adfSAndy Whitcroft
2644773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2645170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
26462b474a1aSAndy Whitcroft			%suppress_export = ();
26473e469cdcSAndy Whitcroft			$suppress_statement = 0;
264874fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
264974fd4f34SJoe Perches				$context_function = $1;
265074fd4f34SJoe Perches			} else {
265174fd4f34SJoe Perches				undef $context_function;
265274fd4f34SJoe Perches			}
26530a920b5bSAndy Whitcroft			next;
26540a920b5bSAndy Whitcroft
26554a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
26564a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
26574a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2658773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
26590a920b5bSAndy Whitcroft			$realline++;
2660d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
26610a920b5bSAndy Whitcroft
26624a0df2efSAndy Whitcroft			# Measure the line length and indent.
2663c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
26640a920b5bSAndy Whitcroft
26650a920b5bSAndy Whitcroft			# Track the previous line.
26660a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
26670a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2668c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2669c2fdda0dSAndy Whitcroft
2670773647a0SAndy Whitcroft			#warn "line<$line>\n";
26716c72ffaaSAndy Whitcroft
2672d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2673d8aaf121SAndy Whitcroft			$realcnt--;
26740a920b5bSAndy Whitcroft		}
26750a920b5bSAndy Whitcroft
2676cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2677cc77cdcaSAndy Whitcroft
26786c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
26796c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2680773647a0SAndy Whitcroft
26812ac73b4fSJoe Perches		my $found_file = 0;
2682773647a0SAndy Whitcroft		# extract the filename as it passes
26833bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
26843bf9a009SRabin Vincent			$realfile = $1;
26852b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2686270c49a0SJoe Perches			$in_commit_log = 0;
26872ac73b4fSJoe Perches			$found_file = 1;
26883bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2689773647a0SAndy Whitcroft			$realfile = $1;
26902b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2691270c49a0SJoe Perches			$in_commit_log = 0;
26921e855726SWolfram Sang
26931e855726SWolfram Sang			$p1_prefix = $1;
2694e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2695e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2696000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2697000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
26981e855726SWolfram Sang			}
2699773647a0SAndy Whitcroft
2700c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2701000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2702000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2703773647a0SAndy Whitcroft			}
27042ac73b4fSJoe Perches			$found_file = 1;
27052ac73b4fSJoe Perches		}
27062ac73b4fSJoe Perches
270734d8815fSJoe Perches#make up the handle for any error we report on this line
270834d8815fSJoe Perches		if ($showfile) {
270934d8815fSJoe Perches			$prefix = "$realfile:$realline: "
271034d8815fSJoe Perches		} elsif ($emacs) {
27117d3a9f67SJoe Perches			if ($file) {
27127d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
27137d3a9f67SJoe Perches			} else {
271434d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
271534d8815fSJoe Perches			}
27167d3a9f67SJoe Perches		}
271734d8815fSJoe Perches
27182ac73b4fSJoe Perches		if ($found_file) {
271985b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
272085b0ee18SJoe Perches				WARN("OBSOLETE",
272185b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
272285b0ee18SJoe Perches			}
27237bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
27242ac73b4fSJoe Perches				$check = 1;
27252ac73b4fSJoe Perches			} else {
27262ac73b4fSJoe Perches				$check = $check_orig;
27272ac73b4fSJoe Perches			}
27289f3a8992SRob Herring			$checklicenseline = 1;
2729133712a2SRob Herring
2730133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2731133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2732133712a2SRob Herring
2733133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2734133712a2SRob Herring
2735133712a2SRob Herring				if (($last_binding_patch != -1) &&
2736133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2737133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2738858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2739133712a2SRob Herring				}
2740133712a2SRob Herring			}
2741133712a2SRob Herring
2742773647a0SAndy Whitcroft			next;
2743773647a0SAndy Whitcroft		}
2744773647a0SAndy Whitcroft
2745389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
27460a920b5bSAndy Whitcroft
2747c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2748c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2749c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
27500a920b5bSAndy Whitcroft
27516c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
27526c72ffaaSAndy Whitcroft
2753490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2754490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2755490b292cSJoe Perches		if ($in_commit_log) {
2756490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2757490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2758490b292cSJoe Perches			}
2759490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2760490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2761490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2762490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2763490b292cSJoe Perches		}
2764490b292cSJoe Perches
2765e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2766e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
276713e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
276813e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2769e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2770e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2771e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2772e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2773e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2774e518e9a5SJoe Perches		}
2775e518e9a5SJoe Perches
27763bf9a009SRabin Vincent# Check for incorrect file permissions
27773bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
27783bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
277904db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
278004db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2781000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2782000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
27833bf9a009SRabin Vincent			}
27843bf9a009SRabin Vincent		}
27853bf9a009SRabin Vincent
2786cd261496SGeert Uytterhoeven# Check the patch for a From:
2787cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2788cd261496SGeert Uytterhoeven			$author = $1;
2789e7f929f3SDwaipayan Ray			my $curline = $linenr;
2790e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2791e7f929f3SDwaipayan Ray				$author .= $1;
2792e7f929f3SDwaipayan Ray			}
2793cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2794cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2795dfa05c28SJoe Perches			$author = reformat_email($author);
2796cd261496SGeert Uytterhoeven		}
2797cd261496SGeert Uytterhoeven
279820112475SJoe Perches# Check the patch for a signoff:
2799dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
28004a0df2efSAndy Whitcroft			$signoff++;
280115662b3eSJoe Perches			$in_commit_log = 0;
280248ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2803fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2804cd261496SGeert Uytterhoeven					$authorsignoff = 1;
280548ca2d8aSDwaipayan Ray				} else {
280648ca2d8aSDwaipayan Ray					my $ctx = $1;
280748ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
280848ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
280948ca2d8aSDwaipayan Ray
281048ca2d8aSDwaipayan Ray					if ($email_address eq $author_address && $email_name eq $author_name) {
281148ca2d8aSDwaipayan Ray						$author_sob = $ctx;
281248ca2d8aSDwaipayan Ray						$authorsignoff = 2;
281348ca2d8aSDwaipayan Ray					} elsif ($email_address eq $author_address) {
281448ca2d8aSDwaipayan Ray						$author_sob = $ctx;
281548ca2d8aSDwaipayan Ray						$authorsignoff = 3;
281648ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
281748ca2d8aSDwaipayan Ray						$author_sob = $ctx;
281848ca2d8aSDwaipayan Ray						$authorsignoff = 4;
281948ca2d8aSDwaipayan Ray
282048ca2d8aSDwaipayan Ray						my $address1 = $email_address;
282148ca2d8aSDwaipayan Ray						my $address2 = $author_address;
282248ca2d8aSDwaipayan Ray
282348ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
282448ca2d8aSDwaipayan Ray							$address1 = "$1$2";
282548ca2d8aSDwaipayan Ray						}
282648ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
282748ca2d8aSDwaipayan Ray							$address2 = "$1$2";
282848ca2d8aSDwaipayan Ray						}
282948ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
283048ca2d8aSDwaipayan Ray							$authorsignoff = 5;
283148ca2d8aSDwaipayan Ray						}
283248ca2d8aSDwaipayan Ray					}
2833cd261496SGeert Uytterhoeven				}
2834cd261496SGeert Uytterhoeven			}
28350a920b5bSAndy Whitcroft		}
283620112475SJoe Perches
283744d303ebSJoe Perches# Check for patch separator
283844d303ebSJoe Perches		if ($line =~ /^---$/) {
283944d303ebSJoe Perches			$has_patch_separator = 1;
284044d303ebSJoe Perches			$in_commit_log = 0;
284144d303ebSJoe Perches		}
284244d303ebSJoe Perches
2843e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2844e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2845e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2846e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2847e0d975b1SJoe Perches		}
2848e0d975b1SJoe Perches
284920112475SJoe Perches# Check signature styles
2850270c49a0SJoe Perches		if (!$in_header_lines &&
2851ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
285220112475SJoe Perches			my $space_before = $1;
285320112475SJoe Perches			my $sign_off = $2;
285420112475SJoe Perches			my $space_after = $3;
285520112475SJoe Perches			my $email = $4;
285620112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
285720112475SJoe Perches
2858ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2859831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
2860831242abSAditya Srivastava				if ($suggested_signature eq "") {
2861ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
2862ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
2863831242abSAditya Srivastava				} else {
2864831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
2865831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2866831242abSAditya Srivastava					    $fix) {
2867831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2868831242abSAditya Srivastava					}
2869831242abSAditya Srivastava				}
2870ce0338dfSJoe Perches			}
287120112475SJoe Perches			if (defined $space_before && $space_before ne "") {
28723705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28733705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
28743705ce5bSJoe Perches				    $fix) {
2875194f66fcSJoe Perches					$fixed[$fixlinenr] =
28763705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
28773705ce5bSJoe Perches				}
287820112475SJoe Perches			}
287920112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
28803705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28813705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
28823705ce5bSJoe Perches				    $fix) {
2883194f66fcSJoe Perches					$fixed[$fixlinenr] =
28843705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
28853705ce5bSJoe Perches				}
28863705ce5bSJoe Perches
288720112475SJoe Perches			}
288820112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
28893705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28903705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
28913705ce5bSJoe Perches				    $fix) {
2892194f66fcSJoe Perches					$fixed[$fixlinenr] =
28933705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
28943705ce5bSJoe Perches				}
289520112475SJoe Perches			}
289620112475SJoe Perches
2897dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
289848ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
289920112475SJoe Perches			if ($suggested_email eq "") {
2900000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2901000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
290220112475SJoe Perches			} else {
290320112475SJoe Perches				my $dequoted = $suggested_email;
290420112475SJoe Perches				$dequoted =~ s/^"//;
290520112475SJoe Perches				$dequoted =~ s/" </ </;
290620112475SJoe Perches				# Don't force email to have quotes
290720112475SJoe Perches				# Allow just an angle bracketed address
2908fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
2909fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2910fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
2911fccaebf0SDwaipayan Ray					    $fix) {
2912fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
2913fccaebf0SDwaipayan Ray					}
2914fccaebf0SDwaipayan Ray				}
2915fccaebf0SDwaipayan Ray
2916fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
2917fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
2918fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
2919fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
2920fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2921fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
2922fccaebf0SDwaipayan Ray					    $fix) {
2923fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
2924fccaebf0SDwaipayan Ray					}
2925fccaebf0SDwaipayan Ray				}
2926fccaebf0SDwaipayan Ray
2927fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
2928fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
2929fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
2930000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2931fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
2932fccaebf0SDwaipayan Ray				}
2933fccaebf0SDwaipayan Ray
2934fccaebf0SDwaipayan Ray
2935fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
2936e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
2937fccaebf0SDwaipayan Ray				# begin with a #
2938fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
2939fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
2940fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
2941fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
2942fccaebf0SDwaipayan Ray						my $new_comment = $comment;
2943fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
2944fccaebf0SDwaipayan Ray
2945fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
2946fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
2947fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
2948fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
2949fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
2950fccaebf0SDwaipayan Ray
2951fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
2952fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
2953fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
2954fccaebf0SDwaipayan Ray
2955fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
2956fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
2957fccaebf0SDwaipayan Ray						    $fix) {
2958fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
2959fccaebf0SDwaipayan Ray						}
2960fccaebf0SDwaipayan Ray					}
2961fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
2962fccaebf0SDwaipayan Ray					my $new_comment = $comment;
2963fccaebf0SDwaipayan Ray
2964fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
2965fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
2966fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
2967fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
2968fccaebf0SDwaipayan Ray
2969fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
2970fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
2971fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
2972fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
2973fccaebf0SDwaipayan Ray
2974fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2975fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
2976fccaebf0SDwaipayan Ray					    $fix) {
2977fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
2978fccaebf0SDwaipayan Ray					}
297920112475SJoe Perches				}
29800a920b5bSAndy Whitcroft			}
29817e51f197SJoe Perches
29827e51f197SJoe Perches# Check for duplicate signatures
29837e51f197SJoe Perches			my $sig_nospace = $line;
29847e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
29857e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
29867e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
29877e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
29887e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
29897e51f197SJoe Perches			} else {
29907e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
29917e51f197SJoe Perches			}
29926c5d24eeSSean Christopherson
29936c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
29946c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
29956c5d24eeSSean Christopherson				if ($email eq $author) {
29966c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
29976c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
29986c5d24eeSSean Christopherson				}
29996c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
30006c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30016c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
30026c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
30036c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30046c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
30056c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
30066c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30076c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
30086c5d24eeSSean Christopherson				}
30096c5d24eeSSean Christopherson			}
30100a920b5bSAndy Whitcroft		}
30110a920b5bSAndy Whitcroft
3012a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3013a2fe16b9SJoe Perches		if ($in_header_lines &&
3014a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3015a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3016a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3017a2fe16b9SJoe Perches		}
3018a2fe16b9SJoe Perches
301944d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
302044d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
30217580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
30227580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
30237580c5b9SAditya Srivastava			    $fix) {
30247580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
30257580c5b9SAditya Srivastava			}
30267ebd05efSChristopher Covington		}
30277ebd05efSChristopher Covington
3028369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3029369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3030369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3031369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3032369c8dd3SJoe Perches					# timestamp
3033634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3034634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3035634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3036634cffccSJoe Perches					# stack dump address styles
3037369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3038369c8dd3SJoe Perches		}
3039369c8dd3SJoe Perches
30402a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
30412a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3042bf4daf12SJoe Perches		    length($line) > 75 &&
3043bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3044bf4daf12SJoe Perches					# file delta changes
3045bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
3046bf4daf12SJoe Perches					# filename then :
304727b379afSAditya Srivastava		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
304827b379afSAditya Srivastava					# A Fixes: or Link: line or signature tag line
3049bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
30502a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
30512a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
30522a076f40SJoe Perches			$commit_log_long_line = 1;
30532a076f40SJoe Perches		}
30542a076f40SJoe Perches
3055bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3056bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3057bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3058bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3059bf4daf12SJoe Perches		}
3060bf4daf12SJoe Perches
3061084a617aSDwaipayan Ray# Check for lines starting with a #
3062084a617aSDwaipayan Ray		if ($in_commit_log && $line =~ /^#/) {
3063084a617aSDwaipayan Ray			if (WARN("COMMIT_COMMENT_SYMBOL",
3064084a617aSDwaipayan Ray				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3065084a617aSDwaipayan Ray			    $fix) {
3066084a617aSDwaipayan Ray				$fixed[$fixlinenr] =~ s/^/ /;
3067084a617aSDwaipayan Ray			}
3068084a617aSDwaipayan Ray		}
3069084a617aSDwaipayan Ray
30700d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
3071369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3072a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3073e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
3074fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3075aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3076369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3077bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3078fe043ea1SJoe Perches			my $init_char = "c";
3079fe043ea1SJoe Perches			my $orig_commit = "";
30800d7835fcSJoe Perches			my $short = 1;
30810d7835fcSJoe Perches			my $long = 0;
30820d7835fcSJoe Perches			my $case = 1;
30830d7835fcSJoe Perches			my $space = 1;
30840d7835fcSJoe Perches			my $hasdesc = 0;
308519c146a6SJoe Perches			my $hasparens = 0;
30860d7835fcSJoe Perches			my $id = '0123456789ab';
30870d7835fcSJoe Perches			my $orig_desc = "commit description";
30880d7835fcSJoe Perches			my $description = "";
30890d7835fcSJoe Perches
3090fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3091fe043ea1SJoe Perches				$init_char = $1;
3092fe043ea1SJoe Perches				$orig_commit = lc($2);
3093fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
3094fe043ea1SJoe Perches				$orig_commit = lc($1);
3095fe043ea1SJoe Perches			}
3096fe043ea1SJoe Perches
30970d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
30980d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
30990d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
31000d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
31010d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
31020d7835fcSJoe Perches				$orig_desc = $1;
310319c146a6SJoe Perches				$hasparens = 1;
31040d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
31050d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
31060d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
31070d7835fcSJoe Perches				$orig_desc = $1;
310819c146a6SJoe Perches				$hasparens = 1;
3109b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
3110b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
3111b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
3112b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
3113b671fde0SJoe Perches				$orig_desc = $1;
3114b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
3115b671fde0SJoe Perches				$orig_desc .= " " . $1;
311619c146a6SJoe Perches				$hasparens = 1;
31170d7835fcSJoe Perches			}
31180d7835fcSJoe Perches
31190d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
31200d7835fcSJoe Perches							      $id, $orig_desc);
31210d7835fcSJoe Perches
3122948b133aSHeinrich Schuchardt			if (defined($id) &&
3123948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
3124d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
31250d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
31260d7835fcSJoe Perches			}
3127d311cd44SJoe Perches		}
3128d311cd44SJoe Perches
312913f1937eSJoe Perches# Check for added, moved or deleted files
313013f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
313113f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
313213f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
313313f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
313413f1937eSJoe Perches		      (defined($1) || defined($2))))) {
3135a82603a8SAndrew Jeffery			$is_patch = 1;
313613f1937eSJoe Perches			$reported_maintainer_file = 1;
313713f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
313813f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
313913f1937eSJoe Perches		}
314013f1937eSJoe Perches
3141e400edb1SRob Herring# Check for adding new DT bindings not in schema format
3142e400edb1SRob Herring		if (!$in_commit_log &&
3143e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3144e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3145e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
3146e400edb1SRob Herring			     "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
3147e400edb1SRob Herring		}
3148e400edb1SRob Herring
314900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
31508905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3151000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
3152000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
31536c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
3154de7d4f0eSAndy Whitcroft		}
3155de7d4f0eSAndy Whitcroft
3156de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3157de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3158171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
3159171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3160171ae1a4SAndy Whitcroft
3161171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
3162171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3163171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
3164171ae1a4SAndy Whitcroft
316534d99219SJoe Perches			CHK("INVALID_UTF8",
3166000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
316700df344fSAndy Whitcroft		}
31680a920b5bSAndy Whitcroft
316915662b3eSJoe Perches# Check if it's the start of a commit log
317015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
317115662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
3172eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
3173eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
317415662b3eSJoe Perches			$in_header_lines = 0;
317515662b3eSJoe Perches			$in_commit_log = 1;
3176ed43c4e5SAllen Hubbe			$has_commit_log = 1;
317715662b3eSJoe Perches		}
317815662b3eSJoe Perches
3179fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
3180fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
3181fa64205dSPasi Savanainen		if ($in_header_lines &&
3182fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3183fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
3184fa64205dSPasi Savanainen			$non_utf8_charset = 1;
3185fa64205dSPasi Savanainen		}
3186fa64205dSPasi Savanainen
3187fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
318815662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3189fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
319015662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
319115662b3eSJoe Perches		}
319215662b3eSJoe Perches
3193d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3194d6430f71SJoe Perches		if ($tree && $in_commit_log) {
3195d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3196d6430f71SJoe Perches				my $file = $1;
3197d6430f71SJoe Perches
3198d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3199d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
3200d6430f71SJoe Perches					#
3201d6430f71SJoe Perches				} else {
3202d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
3203d6430f71SJoe Perches				}
3204d6430f71SJoe Perches			}
3205d6430f71SJoe Perches		}
3206d6430f71SJoe Perches
320766b47b4aSKees Cook# Check for various typo / spelling mistakes
320866d7a382SJoe Perches		if (defined($misspellings) &&
320966d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
32107da07c31SDwaipayan Ray			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
321166b47b4aSKees Cook				my $typo = $1;
32127da07c31SDwaipayan Ray				my $blank = copy_spacing($rawline);
32137da07c31SDwaipayan Ray				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
32147da07c31SDwaipayan Ray				my $hereptr = "$hereline$ptr\n";
321566b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
321666b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
321766b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
32180675a8fbSJean Delvare				my $msg_level = \&WARN;
32190675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
32200675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
32217da07c31SDwaipayan Ray						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
322266b47b4aSKees Cook				    $fix) {
322366b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
322466b47b4aSKees Cook				}
322566b47b4aSKees Cook			}
322666b47b4aSKees Cook		}
322766b47b4aSKees Cook
3228a8dd86bfSMatteo Croce# check for invalid commit id
3229a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3230a8dd86bfSMatteo Croce			my $id;
3231a8dd86bfSMatteo Croce			my $description;
3232a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
3233a8dd86bfSMatteo Croce			if (!defined($id)) {
3234a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
3235a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3236a8dd86bfSMatteo Croce			}
3237a8dd86bfSMatteo Croce		}
3238a8dd86bfSMatteo Croce
3239310cd06bSJoe Perches# check for repeated words separated by a single space
32408d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
32418d0325ccSAditya Srivastava		if (($rawline =~ /^\+/ || $in_commit_log) &&
32428d0325ccSAditya Srivastava		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
32431db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3244310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3245310cd06bSJoe Perches
3246310cd06bSJoe Perches				my $first = $1;
3247310cd06bSJoe Perches				my $second = $2;
32481db81a68SDwaipayan Ray				my $start_pos = $-[1];
32491db81a68SDwaipayan Ray				my $end_pos = $+[2];
3250310cd06bSJoe Perches				if ($first =~ /(?:struct|union|enum)/) {
3251310cd06bSJoe Perches					pos($rawline) += length($first) + length($second) + 1;
3252310cd06bSJoe Perches					next;
3253310cd06bSJoe Perches				}
3254310cd06bSJoe Perches
32551db81a68SDwaipayan Ray				next if (lc($first) ne lc($second));
3256310cd06bSJoe Perches				next if ($first eq 'long');
3257310cd06bSJoe Perches
32581db81a68SDwaipayan Ray				# check for character before and after the word matches
32591db81a68SDwaipayan Ray				my $start_char = '';
32601db81a68SDwaipayan Ray				my $end_char = '';
32611db81a68SDwaipayan Ray				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
32621db81a68SDwaipayan Ray				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
32631db81a68SDwaipayan Ray
32641db81a68SDwaipayan Ray				next if ($start_char =~ /^\S$/);
32651db81a68SDwaipayan Ray				next if (index(" \t.,;?!", $end_char) == -1);
32661db81a68SDwaipayan Ray
32678d0325ccSAditya Srivastava				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
32688d0325ccSAditya Srivastava				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
32698d0325ccSAditya Srivastava					next if (!exists($allow_repeated_words{lc($first)}));
32708d0325ccSAditya Srivastava				}
32718d0325ccSAditya Srivastava
3272310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3273310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3274310cd06bSJoe Perches				    $fix) {
3275310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3276310cd06bSJoe Perches				}
3277310cd06bSJoe Perches			}
3278310cd06bSJoe Perches
3279310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3280310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
3281310cd06bSJoe Perches			    $prevrawline =~ /($word_pattern)\s*$/) {
3282310cd06bSJoe Perches				my $last_word = $1;
3283310cd06bSJoe Perches				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3284310cd06bSJoe Perches					if (WARN("REPEATED_WORD",
3285310cd06bSJoe Perches						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3286310cd06bSJoe Perches					    $fix) {
3287310cd06bSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3288310cd06bSJoe Perches					}
3289310cd06bSJoe Perches				}
3290310cd06bSJoe Perches			}
3291310cd06bSJoe Perches		}
3292310cd06bSJoe Perches
329330670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
329430670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
329500df344fSAndy Whitcroft
32960a920b5bSAndy Whitcroft#trailing whitespace
32979c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
3298c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3299d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3300d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
3301d5e616fcSJoe Perches			    $fix) {
3302194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3303d5e616fcSJoe Perches			}
3304c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3305c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
33063705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
33073705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
33083705ce5bSJoe Perches			    $fix) {
3309194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
33103705ce5bSJoe Perches			}
33113705ce5bSJoe Perches
3312d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
33130a920b5bSAndy Whitcroft		}
33145368df20SAndy Whitcroft
33154783f894SJosh Triplett# Check for FSF mailing addresses.
3316109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
33171bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
33183e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
33193e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
33204783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
33210675a8fbSJean Delvare			my $msg_level = \&ERROR;
33220675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
33230675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
33244783f894SJosh 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)
33254783f894SJosh Triplett		}
33264783f894SJosh Triplett
33273354957aSAndi Kleen# check for Kconfig help text having a real description
33289fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
33299fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
33303354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3331678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3332678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3333678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3334678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
33353354957aSAndi Kleen			my $length = 0;
33369fe287d7SAndy Whitcroft			my $cnt = $realcnt;
33379fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
33389fe287d7SAndy Whitcroft			my $f;
3339a1385803SAndy Whitcroft			my $is_start = 0;
33409fe287d7SAndy Whitcroft			my $is_end = 0;
3341a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
33429fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
33439fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
33449fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
33459fe287d7SAndy Whitcroft
33469fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
33478d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3348a1385803SAndy Whitcroft
334986adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3350a1385803SAndy Whitcroft					$is_start = 1;
335122a4ac02SMasahiro Yamada				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
3352a1385803SAndy Whitcroft					$length = -1;
3353a1385803SAndy Whitcroft				}
3354a1385803SAndy Whitcroft
33559fe287d7SAndy Whitcroft				$f =~ s/^.//;
33563354957aSAndi Kleen				$f =~ s/#.*//;
33573354957aSAndi Kleen				$f =~ s/^\s+//;
33583354957aSAndi Kleen				next if ($f =~ /^$/);
3359678ae162SUlf Magnusson
3360678ae162SUlf Magnusson				# This only checks context lines in the patch
3361678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3362678ae162SUlf Magnusson				# positives, even though some of these are
3363678ae162SUlf Magnusson				# common words in help texts
3364678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3365678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
33669fe287d7SAndy Whitcroft					$is_end = 1;
33679fe287d7SAndy Whitcroft					last;
33689fe287d7SAndy Whitcroft				}
33693354957aSAndi Kleen				$length++;
33703354957aSAndi Kleen			}
337156193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3372000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
337356193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
337456193274SVadim Bendebury			}
3375a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
33763354957aSAndi Kleen		}
33773354957aSAndi Kleen
33787ccf41a8SJoe Perches# check MAINTAINERS entries
33797ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
33807ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
33817ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3382628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3383628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3384628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3385628f91a2SJoe Perches				    $fix) {
3386628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3387628f91a2SJoe Perches				}
3388628f91a2SJoe Perches			}
33897ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
33907ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
33917ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
33927ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
33937ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
33947ccf41a8SJoe Perches				my $cur = $1;
33957ccf41a8SJoe Perches				my $curval = $2;
33967ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
33977ccf41a8SJoe Perches				my $prev = $1;
33987ccf41a8SJoe Perches				my $prevval = $2;
33997ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
34007ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
34017ccf41a8SJoe Perches				if ($curindex < 0) {
34027ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
34037ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
34047ccf41a8SJoe Perches				} else {
34057ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
34067ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
34077ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
34087ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
34097ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
34107ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
34117ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
34127ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
34137ccf41a8SJoe Perches					}
34147ccf41a8SJoe Perches				}
34157ccf41a8SJoe Perches			}
34167ccf41a8SJoe Perches		}
3417628f91a2SJoe Perches
3418c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3419c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3420c68e5878SArnaud Lacombe			my $flag = $1;
3421c68e5878SArnaud Lacombe			my $replacement = {
3422c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3423c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3424c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3425c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3426c68e5878SArnaud Lacombe			};
3427c68e5878SArnaud Lacombe
3428c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3429c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3430c68e5878SArnaud Lacombe		}
3431c68e5878SArnaud Lacombe
3432bff5da43SRob Herring# check for DT compatible documentation
34337dd05b38SFlorian Vaussard		if (defined $root &&
34347dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
34357dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
34367dd05b38SFlorian Vaussard
3437bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3438bff5da43SRob Herring
3439cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3440852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3441cc93319bSFlorian Vaussard
3442bff5da43SRob Herring			foreach my $compat (@compats) {
3443bff5da43SRob Herring				my $compat2 = $compat;
3444185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3445185d566bSRob Herring				my $compat3 = $compat;
3446185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3447185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3448bff5da43SRob Herring				if ( $? >> 8 ) {
3449bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3450bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3451bff5da43SRob Herring				}
3452bff5da43SRob Herring
34534fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
34544fbf32a6SFlorian Vaussard				my $vendor = $1;
3455852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3456bff5da43SRob Herring				if ( $? >> 8 ) {
3457bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3458cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3459bff5da43SRob Herring				}
3460bff5da43SRob Herring			}
3461bff5da43SRob Herring		}
3462bff5da43SRob Herring
34639f3a8992SRob Herring# check for using SPDX license tag at beginning of files
34649f3a8992SRob Herring		if ($realline == $checklicenseline) {
34659f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
34669f3a8992SRob Herring				$checklicenseline = 2;
34679f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
34689f3a8992SRob Herring				my $comment = "";
34699f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
34709f3a8992SRob Herring					$comment = '/*';
34719f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
34729f3a8992SRob Herring					$comment = '//';
3473c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
34749f3a8992SRob Herring					$comment = '#';
34759f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
34769f3a8992SRob Herring					$comment = '..';
34779f3a8992SRob Herring				}
34789f3a8992SRob Herring
3479fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3480fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3481fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3482ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3483fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3484fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3485fdf13693SJoe Perches				}
3486fdf13693SJoe Perches
34879f3a8992SRob Herring				if ($comment !~ /^$/ &&
3488ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
34899f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
34909f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
34913b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
34923b6e8ac9SJoe Perches					my $spdx_license = $1;
34933b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
34943b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
34953b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
34963b6e8ac9SJoe Perches					}
349750c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
349850c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
349950c92900SLubomir Rintel						my $msg_level = \&WARN;
350050c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
350150c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
350250c92900SLubomir Rintel
350350c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
350450c92900SLubomir Rintel						    $fix) {
350550c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
350650c92900SLubomir Rintel						}
350750c92900SLubomir Rintel					}
35089f3a8992SRob Herring				}
35099f3a8992SRob Herring			}
35109f3a8992SRob Herring		}
35119f3a8992SRob Herring
3512a0154cdbSJoe Perches# check for embedded filenames
3513a0154cdbSJoe Perches		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3514a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3515a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3516a0154cdbSJoe Perches		}
3517a0154cdbSJoe Perches
35185368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3519d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
35205368df20SAndy Whitcroft
3521a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3522a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3523a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3524a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3525a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3526a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3527a8da38a9SJoe Perches		}
3528a8da38a9SJoe Perches
352947e0c88bSJoe Perches# line length limit (with some exclusions)
353047e0c88bSJoe Perches#
353147e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
353247e0c88bSJoe Perches#	logging functions like pr_info that end in a string
353347e0c88bSJoe Perches#	lines with a single string
353447e0c88bSJoe Perches#	#defines that are a single string
35352e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
353647e0c88bSJoe Perches#
353747e0c88bSJoe Perches# There are 3 different line length message types:
3538ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
353947e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
354047e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
354147e0c88bSJoe Perches#
354247e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
354347e0c88bSJoe Perches#
354447e0c88bSJoe Perches
3545b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
354647e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
354747e0c88bSJoe Perches
354847e0c88bSJoe Perches			# Check the allowed long line types first
354947e0c88bSJoe Perches
355047e0c88bSJoe Perches			# logging functions that end in a string that starts
355147e0c88bSJoe Perches			# before $max_line_length
355247e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
355347e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
355447e0c88bSJoe Perches				$msg_type = "";
355547e0c88bSJoe Perches
355647e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
355747e0c88bSJoe Perches			# #defines with only strings
355847e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
355947e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
356047e0c88bSJoe Perches				$msg_type = "";
356147e0c88bSJoe Perches
3562cc147506SJoe Perches			# More special cases
3563cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3564cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3565d560a5f8SJoe Perches				$msg_type = "";
3566d560a5f8SJoe Perches
35672e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
35682e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
35692e4bbbc5SAndreas Brauchli				$msg_type = "";
35702e4bbbc5SAndreas Brauchli
357147e0c88bSJoe Perches			# Otherwise set the alternate message types
357247e0c88bSJoe Perches
357347e0c88bSJoe Perches			# a comment starts before $max_line_length
357447e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
357547e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
357647e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
357747e0c88bSJoe Perches
357847e0c88bSJoe Perches			# a quoted string starts before $max_line_length
357947e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
358047e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
358147e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
358247e0c88bSJoe Perches			}
358347e0c88bSJoe Perches
358447e0c88bSJoe Perches			if ($msg_type ne "" &&
358547e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3586bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3587bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3588bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3589bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
35900a920b5bSAndy Whitcroft			}
359147e0c88bSJoe Perches		}
35920a920b5bSAndy Whitcroft
35938905a67cSAndy Whitcroft# check for adding lines without a newline.
35948905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
359547ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
359647ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
359747ca69b8STom Rix			    $fix) {
359847ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
359947ca69b8STom Rix			}
36008905a67cSAndy Whitcroft		}
36018905a67cSAndy Whitcroft
3602b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3603de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
36040a920b5bSAndy Whitcroft
36050a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3606713a09deSAntonio Borneo# more than $tabsize must use tabs.
3607c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3608c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3609c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3610d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
36113705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
36123705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
36133705ce5bSJoe Perches			    $fix) {
3614194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
36153705ce5bSJoe Perches			}
36160a920b5bSAndy Whitcroft		}
36170a920b5bSAndy Whitcroft
361808e44365SAlberto Panizzo# check for space before tabs.
361908e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
362008e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
36213705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
36223705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
36233705ce5bSJoe Perches			    $fix) {
3624194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3625713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3626194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3627c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
36283705ce5bSJoe Perches			}
362908e44365SAlberto Panizzo		}
363008e44365SAlberto Panizzo
36316a487211SJoe Perches# check for assignments on the start of a line
36326a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3633da7355abSAditya Srivastava			my $operator = $1;
3634da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3635da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3636da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3637da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3638da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3639da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3640da7355abSAditya Srivastava			}
36416a487211SJoe Perches		}
36426a487211SJoe Perches
3643d1fe9c09SJoe Perches# check for && or || at the start of a line
3644d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
36458e08f076SAditya Srivastava			my $operator = $1;
36468e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
36478e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
36488e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
36498e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
36508e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
36518e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
36528e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
36538e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
36548e08f076SAditya Srivastava			}
3655d1fe9c09SJoe Perches		}
3656d1fe9c09SJoe Perches
3657a91e8994SJoe Perches# check indentation starts on a tab stop
36585b57980dSJoe Perches		if ($perl_version_ok &&
3659bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3660a91e8994SJoe Perches			my $indent = length($1);
3661713a09deSAntonio Borneo			if ($indent % $tabsize) {
3662a91e8994SJoe Perches				if (WARN("TABSTOP",
3663a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3664a91e8994SJoe Perches				    $fix) {
3665713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3666a91e8994SJoe Perches				}
3667a91e8994SJoe Perches			}
3668a91e8994SJoe Perches		}
3669a91e8994SJoe Perches
3670d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
36715b57980dSJoe Perches		if ($perl_version_ok &&
3672fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3673d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3674d1fe9c09SJoe Perches			my $oldindent = $1;
3675d1fe9c09SJoe Perches			my $rest = $2;
3676d1fe9c09SJoe Perches
3677d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3678d1fe9c09SJoe Perches			if ($pos >= 0) {
3679b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3680b34a26f3SJoe Perches				my $newindent = $2;
3681d1fe9c09SJoe Perches
3682d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3683713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3684713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3685d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3686d1fe9c09SJoe Perches
3687d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3688d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
36893705ce5bSJoe Perches
36903705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
36913705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
36923705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3693194f66fcSJoe Perches						$fixed[$fixlinenr] =~
36943705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
36953705ce5bSJoe Perches					}
3696d1fe9c09SJoe Perches				}
3697d1fe9c09SJoe Perches			}
3698d1fe9c09SJoe Perches		}
3699d1fe9c09SJoe Perches
37006ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
37016ab3a970SJoe Perches# avoid checking a few false positives:
37026ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
37036ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
37046ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
37056ab3a970SJoe Perches#   multiline macros that define functions
37066ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
37076ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
37086ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
37093705ce5bSJoe Perches			if (CHK("SPACING",
3710f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
37113705ce5bSJoe Perches			    $fix) {
3712194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3713f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
37143705ce5bSJoe Perches			}
3715aad4f614SJoe Perches		}
3716aad4f614SJoe Perches
371786406b1cSJoe Perches# Block comment styles
371886406b1cSJoe Perches# Networking with an initial /*
371905880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3720fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
372185ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
3722c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
372305880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
372405880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
372505880600SJoe Perches		}
372605880600SJoe Perches
372786406b1cSJoe Perches# Block comments use * on subsequent lines
372886406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
372986406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3730a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
373161135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3732a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
373386406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
373486406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3735a605e32eSJoe Perches		}
3736a605e32eSJoe Perches
373786406b1cSJoe Perches# Block comments use */ on trailing lines
373886406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3739c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3740c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3741c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
374286406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
374386406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
374405880600SJoe Perches		}
374505880600SJoe Perches
374608eb9b80SJoe Perches# Block comment * alignment
374708eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3748af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3749af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3750af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
375108eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3752af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3753af207524SJoe Perches			my $oldindent;
375408eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3755af207524SJoe Perches			if (defined($1)) {
3756af207524SJoe Perches				$oldindent = expand_tabs($1);
3757af207524SJoe Perches			} else {
3758af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3759af207524SJoe Perches				$oldindent = expand_tabs($1);
3760af207524SJoe Perches			}
376108eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
376208eb9b80SJoe Perches			my $newindent = $1;
376308eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3764af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
376508eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
376608eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
376708eb9b80SJoe Perches			}
376808eb9b80SJoe Perches		}
376908eb9b80SJoe Perches
37707f619191SJoe Perches# check for missing blank lines after struct/union declarations
37717f619191SJoe Perches# with exceptions for various attributes and macros
37727f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
37737f619191SJoe Perches		    $line =~ /^\+/ &&
37747f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
37757f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
37767f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
37777f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
37787f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
37797f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
37807f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
37810bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
37827f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3783d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3784d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3785d752fcc8SJoe Perches			    $fix) {
3786f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3787d752fcc8SJoe Perches			}
37887f619191SJoe Perches		}
37897f619191SJoe Perches
3790365dd4eaSJoe Perches# check for multiple consecutive blank lines
3791365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3792365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3793365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3794d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3795d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3796d752fcc8SJoe Perches			    $fix) {
3797f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3798d752fcc8SJoe Perches			}
3799d752fcc8SJoe Perches
3800365dd4eaSJoe Perches			$last_blank_line = $linenr;
3801365dd4eaSJoe Perches		}
3802365dd4eaSJoe Perches
38033b617e3bSJoe Perches# check for missing blank lines after declarations
3804b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
3805b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3806b5e8736aSJoe Perches			# use temporaries
3807b5e8736aSJoe Perches			my $sl = $sline;
3808b5e8736aSJoe Perches			my $pl = $prevline;
3809b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
3810b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3811b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3812b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
38135a4e1fd3SJoe Perches			# function pointer declarations
3814b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
38153f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3816b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
38173f7bac03SJoe Perches			# known declaration macros
3818b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
38193f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
3820b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
38213f7bac03SJoe Perches			# other possible extensions of declaration lines
3822b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
38233f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
3824b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
38253f7bac03SJoe Perches			# looks like a declaration
3826b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
38275a4e1fd3SJoe Perches			# function pointer declarations
3828b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
38293f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3830b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
38313f7bac03SJoe Perches			# known declaration macros
3832b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
38333f7bac03SJoe Perches			# start of struct or union or enum
3834b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
38353f7bac03SJoe Perches			# start or end of block or continuation of declaration
3836b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
38373f7bac03SJoe Perches			# bitfield continuation
3838b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
38393f7bac03SJoe Perches			# other possible extensions of declaration lines
3840b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3841d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
3842d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
3843d752fcc8SJoe Perches				    $fix) {
3844f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
3845d752fcc8SJoe Perches				}
38463b617e3bSJoe Perches			}
3847b5e8736aSJoe Perches		}
38483b617e3bSJoe Perches
38495f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
38506b4c5bebSAndy Whitcroft# Exceptions:
38516b4c5bebSAndy Whitcroft#  1) within comments
38526b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
38536b4c5bebSAndy Whitcroft#  3) hanging labels
38543705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
38555f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
38563705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
38573705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
38583705ce5bSJoe Perches			    $fix) {
3859194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
38603705ce5bSJoe Perches			}
38615f7ddae6SRaffaele Recalcati		}
38625f7ddae6SRaffaele Recalcati
3863b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3864b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3865b9ea10d6SAndy Whitcroft
38665751a24eSJoe Perches# check for unusual line ending [ or (
38675751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
38685751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
38695751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
38705751a24eSJoe Perches		}
38715751a24eSJoe Perches
38724dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
38734dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
38744dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
38754dbed76fSJoe Perches			$context_function = $1;
38764dbed76fSJoe Perches		}
38774dbed76fSJoe Perches
38784dbed76fSJoe Perches# check if this appears to be the end of function declaration
38794dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
38804dbed76fSJoe Perches			undef $context_function;
38814dbed76fSJoe Perches		}
38824dbed76fSJoe Perches
3883032a4c0fSJoe Perches# check indentation of any line with a bare else
3884840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3885032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3886032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3887032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3888840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3889840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3890840080a0SJoe Perches			     defined $lines[$linenr] &&
3891840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3892032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3893032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3894032a4c0fSJoe Perches			}
3895032a4c0fSJoe Perches		}
3896032a4c0fSJoe Perches
3897c00df19aSJoe Perches# check indentation of a line with a break;
3898dc58bc55SJoe Perches# if the previous line is a goto, return or break
3899dc58bc55SJoe Perches# and is indented the same # of tabs
3900c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3901c00df19aSJoe Perches			my $tabs = $1;
3902dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
3903dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
3904dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
3905dc58bc55SJoe Perches				    $fix) {
3906dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
3907dc58bc55SJoe Perches				}
3908c00df19aSJoe Perches			}
3909c00df19aSJoe Perches		}
3910c00df19aSJoe Perches
3911c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3912cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3913000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3914000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3915c2fdda0dSAndy Whitcroft		}
391622f2a2efSAndy Whitcroft
391756e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
391856e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
391956e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
392056e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
392156e77d70SJoe Perches		}
392256e77d70SJoe Perches
39239c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
39242b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
39252b474a1aSAndy Whitcroft		    $realline_next);
39263e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3927ca819864SJoe Perches		if ($linenr > $suppress_statement &&
39281b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3929170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3930f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3931171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3932171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3933171ae1a4SAndy Whitcroft
39343e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
39353e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
39363e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
39373e469cdcSAndy Whitcroft			# until we hit end of it.
39383e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
39393e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
39403e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
39413e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
39423e469cdcSAndy Whitcroft			}
3943f74bd194SAndy Whitcroft
39442b474a1aSAndy Whitcroft			# Find the real next line.
39452b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
39462b474a1aSAndy Whitcroft			if (defined $realline_next &&
39472b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
39482b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
39492b474a1aSAndy Whitcroft				$realline_next++;
39502b474a1aSAndy Whitcroft			}
39512b474a1aSAndy Whitcroft
3952171ae1a4SAndy Whitcroft			my $s = $stat;
3953171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3954cf655043SAndy Whitcroft
3955c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3956171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3957c2fdda0dSAndy Whitcroft
3958c2fdda0dSAndy Whitcroft			# Ignore functions being called
3959171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3960c2fdda0dSAndy Whitcroft
3961463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3962463f2864SAndy Whitcroft
3963c45dcabdSAndy Whitcroft			# declarations always start with types
3964d2506586SAndy 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) {
3965c45dcabdSAndy Whitcroft				my $type = $1;
3966c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3967c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3968c45dcabdSAndy Whitcroft
39696c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3970a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3971c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3972c2fdda0dSAndy Whitcroft			}
39738905a67cSAndy Whitcroft
39746c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
397565863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3976c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
39779c0ca6f9SAndy Whitcroft			}
39788905a67cSAndy Whitcroft
39798905a67cSAndy Whitcroft			# Check for any sort of function declaration.
39808905a67cSAndy Whitcroft			# int foo(something bar, other baz);
39818905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3982171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
39838905a67cSAndy Whitcroft				my ($name_len) = length($1);
39848905a67cSAndy Whitcroft
3985cf655043SAndy Whitcroft				my $ctx = $s;
3986773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
39878905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3988cf655043SAndy Whitcroft
39898905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3990c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
39918905a67cSAndy Whitcroft
3992c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
39938905a67cSAndy Whitcroft					}
39948905a67cSAndy Whitcroft				}
39958905a67cSAndy Whitcroft			}
39968905a67cSAndy Whitcroft
39979c0ca6f9SAndy Whitcroft		}
39989c0ca6f9SAndy Whitcroft
399900df344fSAndy Whitcroft#
400000df344fSAndy Whitcroft# Checks which may be anchored in the context.
400100df344fSAndy Whitcroft#
400200df344fSAndy Whitcroft
400300df344fSAndy Whitcroft# Check for switch () and associated case and default
400400df344fSAndy Whitcroft# statements should be at the same indent.
400500df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
400600df344fSAndy Whitcroft			my $err = '';
400700df344fSAndy Whitcroft			my $sep = '';
400800df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
400900df344fSAndy Whitcroft			shift(@ctx);
401000df344fSAndy Whitcroft			for my $ctx (@ctx) {
401100df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
401200df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
401300df344fSAndy Whitcroft							$indent != $cindent) {
401400df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
401500df344fSAndy Whitcroft					$sep = '';
401600df344fSAndy Whitcroft				} else {
401700df344fSAndy Whitcroft					$sep = "[...]\n";
401800df344fSAndy Whitcroft				}
401900df344fSAndy Whitcroft			}
402000df344fSAndy Whitcroft			if ($err ne '') {
4021000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4022000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4023de7d4f0eSAndy Whitcroft			}
4024de7d4f0eSAndy Whitcroft		}
4025de7d4f0eSAndy Whitcroft
4026de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4027de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
40280fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4029773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4030773647a0SAndy Whitcroft
40319c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
40328eef05ddSJoe Perches
40338eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
40348eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
40358eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
40368eef05ddSJoe Perches			}
40378eef05ddSJoe Perches
4038de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4039de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4040de7d4f0eSAndy Whitcroft
4041548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4042548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4043de7d4f0eSAndy Whitcroft
4044548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4045548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4046548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4047548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4048548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4049773647a0SAndy Whitcroft				$ctx_ln++;
4050773647a0SAndy Whitcroft			}
4051548596d5SAndy Whitcroft
405253210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
405353210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4054773647a0SAndy Whitcroft
4055773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4056000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4057000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
405801464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
405900df344fSAndy Whitcroft			}
4060773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4061773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4062773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4063773647a0SAndy Whitcroft			{
40649c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
40659c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4066000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4067000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
406801464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
40699c0ca6f9SAndy Whitcroft				}
40709c0ca6f9SAndy Whitcroft			}
407100df344fSAndy Whitcroft		}
407200df344fSAndy Whitcroft
40734d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4074f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
40753e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
40763e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
40773e469cdcSAndy Whitcroft					if (!defined $stat);
40784d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
40794d001e4dSAndy Whitcroft
40804d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
40814d001e4dSAndy Whitcroft
40829f5af480SJoe Perches			# remove inline comments
40839f5af480SJoe Perches			$s =~ s/$;/ /g;
40849f5af480SJoe Perches			$c =~ s/$;/ /g;
40854d001e4dSAndy Whitcroft
40864d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
40876f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
40886f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
40894d001e4dSAndy Whitcroft
40909f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
40919f5af480SJoe Perches			# none on the first line, and are going to readd them
40929f5af480SJoe Perches			# where necessary.
40939f5af480SJoe Perches			$s =~ s/\n./\n/gs;
40949f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
40959f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
40969f5af480SJoe Perches			}
40979f5af480SJoe Perches
40984d001e4dSAndy Whitcroft			# We want to check the first line inside the block
40994d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
41004d001e4dSAndy Whitcroft			#  1) any blank line termination
41014d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
41024d001e4dSAndy Whitcroft			#  3) any do (...) {
41034d001e4dSAndy Whitcroft			my $continuation = 0;
41044d001e4dSAndy Whitcroft			my $check = 0;
41054d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
41064d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
41074d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
41084d001e4dSAndy Whitcroft				$continuation = 1;
41094d001e4dSAndy Whitcroft			}
41109bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
41114d001e4dSAndy Whitcroft				$check = 1;
41124d001e4dSAndy Whitcroft				$cond_lines++;
41134d001e4dSAndy Whitcroft			}
41144d001e4dSAndy Whitcroft
41154d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
41164d001e4dSAndy Whitcroft			# preprocessor statement.
41174d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
41184d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
41194d001e4dSAndy Whitcroft				$check = 0;
41204d001e4dSAndy Whitcroft			}
41214d001e4dSAndy Whitcroft
41229bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4123740504c6SAndy Whitcroft			$continuation = 0;
41249bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
41259bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
41264d001e4dSAndy Whitcroft
4127f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4128f16fa28fSAndy Whitcroft				# is not linear.
4129f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4130f16fa28fSAndy Whitcroft					$check = 0;
4131f16fa28fSAndy Whitcroft				}
4132f16fa28fSAndy Whitcroft
41339bd49efeSAndy Whitcroft				# Ignore:
41349bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
41359bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
41369bd49efeSAndy Whitcroft				#  3) labels.
4137740504c6SAndy Whitcroft				if ($continuation ||
4138740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
41399bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
41409bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4141740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
414230dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
41439bd49efeSAndy Whitcroft						$cond_lines++;
41449bd49efeSAndy Whitcroft					}
41454d001e4dSAndy Whitcroft				}
414630dad6ebSAndy Whitcroft			}
41474d001e4dSAndy Whitcroft
41484d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
41494d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
41504d001e4dSAndy Whitcroft
41514d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
41524d001e4dSAndy Whitcroft			# this is not this patch's fault.
41534d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
41544d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
41554d001e4dSAndy Whitcroft				$check = 0;
41564d001e4dSAndy Whitcroft			}
41574d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
41584d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
41594d001e4dSAndy Whitcroft			}
41604d001e4dSAndy Whitcroft
41619bd49efeSAndy 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";
41624d001e4dSAndy Whitcroft
41639f5af480SJoe Perches			if ($check && $s ne '' &&
4164713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
41659f5af480SJoe Perches			     ($sindent < $indent) ||
4166f6950a73SJoe Perches			     ($sindent == $indent &&
4167f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4168713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4169000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4170000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
41714d001e4dSAndy Whitcroft			}
41724d001e4dSAndy Whitcroft		}
41734d001e4dSAndy Whitcroft
41746c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
41756c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
41761f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
41771f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
41786c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4179c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4180c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4181cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4182cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
41831f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4184c2fdda0dSAndy Whitcroft		}
41856c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
41866c72ffaaSAndy Whitcroft
418700df344fSAndy Whitcroft#ignore lines not being added
41883705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
418900df344fSAndy Whitcroft
419099ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
419199ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
419299ca38c2SJoe Perches#	struct foo bar = *(&(bar));
419399ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
419499ca38c2SJoe Perches			my $var = $1;
419599ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
419699ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
419799ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
419899ca38c2SJoe Perches			}
419999ca38c2SJoe Perches		}
420099ca38c2SJoe Perches
420111ca40a0SJoe Perches# check for dereferences that span multiple lines
420211ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
420311ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
420411ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
420511ca40a0SJoe Perches			my $ref = $1;
420611ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
420711ca40a0SJoe Perches			$ref .= $1;
420811ca40a0SJoe Perches			$ref =~ s/\s//g;
420911ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
421011ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
421111ca40a0SJoe Perches		}
421211ca40a0SJoe Perches
4213a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4214c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4215a1ce18e4SJoe Perches			my $type = $1;
4216a1ce18e4SJoe Perches			my $var = $2;
4217207a8e84SJoe Perches			$var = "" if (!defined $var);
4218207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4219a1ce18e4SJoe Perches				my $sign = $1;
4220a1ce18e4SJoe Perches				my $pointer = $2;
4221a1ce18e4SJoe Perches
4222a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4223a1ce18e4SJoe Perches
4224a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4225a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4226a1ce18e4SJoe Perches				    $fix) {
4227a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4228207a8e84SJoe Perches					my $comp_pointer = $pointer;
4229207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4230207a8e84SJoe Perches					$decl .= $comp_pointer;
4231207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4232207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4233a1ce18e4SJoe Perches				}
4234a1ce18e4SJoe Perches			}
4235a1ce18e4SJoe Perches		}
4236a1ce18e4SJoe Perches
4237653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
42387429c690SAndy Whitcroft		if ($dbg_type) {
42397429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4240000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4241000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
42427429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4243000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4244000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
42457429c690SAndy Whitcroft			}
4246653d4876SAndy Whitcroft			next;
4247653d4876SAndy Whitcroft		}
4248a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4249a1ef277eSAndy Whitcroft		if ($dbg_attr) {
42509360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4251000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4252000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
42539360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4254000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4255000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4256a1ef277eSAndy Whitcroft			}
4257a1ef277eSAndy Whitcroft			next;
4258a1ef277eSAndy Whitcroft		}
4259653d4876SAndy Whitcroft
4260f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
426199423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
426299423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4263d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4264d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4265f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4266f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4267f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4268d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4269d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4270f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4271d752fcc8SJoe Perches				$fixedline = $line;
42728d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4273f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4274d752fcc8SJoe Perches			}
4275f0a594c1SAndy Whitcroft		}
4276f0a594c1SAndy Whitcroft
427700df344fSAndy Whitcroft#
427800df344fSAndy Whitcroft# Checks which are anchored on the added line.
427900df344fSAndy Whitcroft#
428000df344fSAndy Whitcroft
4281653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4282c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4283653d4876SAndy Whitcroft			my $path = $1;
4284653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4285000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4286495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4287495e9d84SJoe Perches			}
4288495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4289495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4290495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4291653d4876SAndy Whitcroft			}
4292653d4876SAndy Whitcroft		}
4293653d4876SAndy Whitcroft
429400df344fSAndy Whitcroft# no C99 // comments
429500df344fSAndy Whitcroft		if ($line =~ m{//}) {
42963705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
42973705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
42983705ce5bSJoe Perches			    $fix) {
4299194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
43003705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
43013705ce5bSJoe Perches					my $comment = trim($1);
4302194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
43033705ce5bSJoe Perches				}
43043705ce5bSJoe Perches			}
430500df344fSAndy Whitcroft		}
430600df344fSAndy Whitcroft		# Remove C99 comments.
43070a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
43086c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
43090a920b5bSAndy Whitcroft
43102b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
43112b474a1aSAndy Whitcroft# the whole statement.
43122b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
43132b474a1aSAndy Whitcroft		if (defined $realline_next &&
43142b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
43152b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
431636794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
43173cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
43183cbf62dfSAndy Whitcroft			# a prefix:
43193cbf62dfSAndy Whitcroft			#   XXX(foo);
43203cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4321653d4876SAndy Whitcroft			my $name = $1;
432287a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
43233cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
43243cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
43253cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
43263cbf62dfSAndy Whitcroft
43273cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
43282b474a1aSAndy Whitcroft				\n.}\s*$|
432948012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
433048012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
433148012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
43322b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
43332b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
433448012058SAndy Whitcroft			    )/x) {
43352b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
43362b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
43372b474a1aSAndy Whitcroft			} else {
43382b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
43390a920b5bSAndy Whitcroft			}
43400a920b5bSAndy Whitcroft		}
43412b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
43422b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
434336794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
43442b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
43452b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
43462b474a1aSAndy Whitcroft		}
43472b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
43482b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4349000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4350000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
43512b474a1aSAndy Whitcroft		}
43520a920b5bSAndy Whitcroft
43535150bda4SJoe Eloff# check for global initialisers.
43546d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
4355d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
43566d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4357d5e616fcSJoe Perches			    $fix) {
43586d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4359d5e616fcSJoe Perches			}
4360f0a594c1SAndy Whitcroft		}
43610a920b5bSAndy Whitcroft# check for static initialisers.
43626d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4363d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
43646d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4365d5e616fcSJoe Perches				      $herecurr) &&
4366d5e616fcSJoe Perches			    $fix) {
43676d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4368d5e616fcSJoe Perches			}
43690a920b5bSAndy Whitcroft		}
43700a920b5bSAndy Whitcroft
43711813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
43721813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
43731813087dSJoe Perches			my $tmp = trim($1);
43741813087dSJoe Perches			WARN("MISORDERED_TYPE",
43751813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
43761813087dSJoe Perches		}
43771813087dSJoe Perches
4378809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4379809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4380809e082eSJoe Perches			my $type = trim($1);
4381809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4382809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4383809e082eSJoe Perches			my $new_type = $type;
4384809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4385809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4386809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4387809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4388809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4389809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4390809e082eSJoe Perches			$new_type = trim($new_type);
4391809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4392809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4393809e082eSJoe Perches			    $fix) {
4394809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4395809e082eSJoe Perches			}
4396809e082eSJoe Perches		}
4397809e082eSJoe Perches
4398cb710ecaSJoe Perches# check for static const char * arrays.
4399cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4400000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4401000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4402cb710ecaSJoe Perches				$herecurr);
4403cb710ecaSJoe Perches		}
4404cb710ecaSJoe Perches
440577b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
440677b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
440777b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
440877b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
440977b8c0a8SJoe Perches			    $fix) {
441077b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
441177b8c0a8SJoe Perches			}
441277b8c0a8SJoe Perches		}
441377b8c0a8SJoe Perches
4414cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4415cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4416000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4417000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4418cb710ecaSJoe Perches				$herecurr);
4419cb710ecaSJoe Perches		}
4420cb710ecaSJoe Perches
4421ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4422ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4423ab7e23f3SJoe Perches			my $found = $1;
4424ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4425ab7e23f3SJoe Perches				WARN("CONST_CONST",
4426ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4427ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4428ab7e23f3SJoe Perches				WARN("CONST_CONST",
4429ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4430ab7e23f3SJoe Perches			}
4431ab7e23f3SJoe Perches		}
4432ab7e23f3SJoe Perches
443373169765SJoe Perches# check for const static or static <non ptr type> const declarations
443473169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
443573169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
443673169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
443773169765SJoe Perches			if (WARN("STATIC_CONST",
443873169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
443973169765SJoe Perches			    $fix) {
444073169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
444173169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
444273169765SJoe Perches			}
444373169765SJoe Perches		}
444473169765SJoe Perches
44459b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
44469b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
44479b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
44489b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
44499b0fa60dSJoe Perches				$herecurr);
44509b0fa60dSJoe Perches		}
44519b0fa60dSJoe Perches
4452b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4453b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4454b598b670SJoe Perches			my $array = $1;
4455b598b670SJoe 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*\))@) {
4456b598b670SJoe Perches				my $array_div = $1;
4457b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4458b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4459b598b670SJoe Perches				    $fix) {
4460b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4461b598b670SJoe Perches				}
4462b598b670SJoe Perches			}
4463b598b670SJoe Perches		}
4464b598b670SJoe Perches
4465b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
446616b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4467b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4468b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4469b36190c5SJoe Perches			    $fix) {
4470194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4471b36190c5SJoe Perches			}
4472b36190c5SJoe Perches		}
4473b36190c5SJoe Perches
4474653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4475653d4876SAndy Whitcroft# make sense.
4476653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
44778054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4478c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
44798ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
448046d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4481000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4482000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
44830a920b5bSAndy Whitcroft		}
44840a920b5bSAndy Whitcroft
44850a920b5bSAndy Whitcroft# * goes on variable not on type
448665863862SAndy Whitcroft		# (char*[ const])
4487bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4488bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
44893705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4490d8aaf121SAndy Whitcroft
449165863862SAndy Whitcroft			# Should start with a space.
449265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
449365863862SAndy Whitcroft			# Should not end with a space.
449465863862SAndy Whitcroft			$to =~ s/\s+$//;
449565863862SAndy Whitcroft			# '*'s should not have spaces between.
4496f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
449765863862SAndy Whitcroft			}
4498d8aaf121SAndy Whitcroft
44993705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
450065863862SAndy Whitcroft			if ($from ne $to) {
45013705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
45023705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
45033705ce5bSJoe Perches				    $fix) {
45043705ce5bSJoe Perches					my $sub_from = $ident;
45053705ce5bSJoe Perches					my $sub_to = $ident;
45063705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4507194f66fcSJoe Perches					$fixed[$fixlinenr] =~
45083705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
45093705ce5bSJoe Perches				}
451065863862SAndy Whitcroft			}
4511bfcb2cc7SAndy Whitcroft		}
4512bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4513bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
45143705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4515d8aaf121SAndy Whitcroft
451665863862SAndy Whitcroft			# Should start with a space.
451765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
451865863862SAndy Whitcroft			# Should not end with a space.
451965863862SAndy Whitcroft			$to =~ s/\s+$//;
452065863862SAndy Whitcroft			# '*'s should not have spaces between.
4521f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
452265863862SAndy Whitcroft			}
452365863862SAndy Whitcroft			# Modifiers should have spaces.
452465863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
452565863862SAndy Whitcroft
45263705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4527667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
45283705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
45293705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
45303705ce5bSJoe Perches				    $fix) {
45313705ce5bSJoe Perches
45323705ce5bSJoe Perches					my $sub_from = $match;
45333705ce5bSJoe Perches					my $sub_to = $match;
45343705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4535194f66fcSJoe Perches					$fixed[$fixlinenr] =~
45363705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
45373705ce5bSJoe Perches				}
453865863862SAndy Whitcroft			}
45390a920b5bSAndy Whitcroft		}
45400a920b5bSAndy Whitcroft
45419d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
45429d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
45430675a8fbSJean Delvare			my $msg_level = \&WARN;
45440675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
45450675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
45469d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
45479d3e3c70SJoe Perches		}
45480a920b5bSAndy Whitcroft
45499d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
45508905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4551000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4552000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
45538905a67cSAndy Whitcroft		}
45548905a67cSAndy Whitcroft
455517441227SJoe Perches# check for uses of printk_ratelimit
455617441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4557000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4558000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
455917441227SJoe Perches		}
456017441227SJoe Perches
4561eeef5733SJoe Perches# printk should use KERN_* levels
4562eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4563000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4564eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
456500df344fSAndy Whitcroft		}
45660a920b5bSAndy Whitcroft
4567f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4568f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4569f5eea3b0SJoe Perches			my $printk = $1;
4570f5eea3b0SJoe Perches			my $modifier = $2;
4571f5eea3b0SJoe Perches			my $orig = $3;
4572f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4573243f3803SJoe Perches			my $level = lc($orig);
4574243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
45758f26b837SJoe Perches			my $level2 = $level;
45768f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4577f5eea3b0SJoe Perches			$level .= $modifier;
4578f5eea3b0SJoe Perches			$level2 .= $modifier;
4579243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4580f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4581243f3803SJoe Perches		}
4582243f3803SJoe Perches
4583f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4584dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4585dc139313SJoe Perches			my $orig = $1;
4586dc139313SJoe Perches			my $level = lc($orig);
4587dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4588dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4589dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4590dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4591dc139313SJoe Perches		}
4592dc139313SJoe Perches
45938020b253SNicolas Boichat# trace_printk should not be used in production code.
45948020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
45958020b253SNicolas Boichat			WARN("TRACE_PRINTK",
45968020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
45978020b253SNicolas Boichat		}
45988020b253SNicolas Boichat
459991c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
460091c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
460191c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
460291c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
460391c9afafSAndy Lutomirski			WARN("ENOSYS",
460491c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
460591c9afafSAndy Lutomirski		}
460691c9afafSAndy Lutomirski
46076b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
46086b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
46096b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
46106b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
46116b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
46126b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
46136b9ea5ffSJakub Kicinski			    $fix) {
46146b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
46156b9ea5ffSJakub Kicinski			}
46166b9ea5ffSJakub Kicinski		}
46176b9ea5ffSJakub Kicinski
4618653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4619653d4876SAndy Whitcroft# or if closed on same line
46205b57980dSJoe Perches		if ($perl_version_ok &&
46212d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
46222d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
46232d453e3bSJoe Perches		    $sline !~ /}/) {
46248d182478SJoe Perches			if (ERROR("OPEN_BRACE",
46252d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
46268d182478SJoe Perches			    $fix) {
46278d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46288d182478SJoe Perches				my $fixed_line = $rawline;
462903f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
46308d182478SJoe Perches				my $line1 = $1;
46318d182478SJoe Perches				my $line2 = $2;
46328d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
46338d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
46348d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
46358d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
46368d182478SJoe Perches				}
46378d182478SJoe Perches			}
46380a920b5bSAndy Whitcroft		}
4639653d4876SAndy Whitcroft
46408905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
46418905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
46428905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
46438d182478SJoe Perches			if (ERROR("OPEN_BRACE",
46448d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
46458d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46468d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46478d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46488d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
46498d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46508d182478SJoe Perches				$fixedline = $rawline;
46518d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
46528d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46538d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46548d182478SJoe Perches				}
46558d182478SJoe Perches			}
46568905a67cSAndy Whitcroft		}
46578905a67cSAndy Whitcroft
46580c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
46593705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
46603705ce5bSJoe Perches			if (WARN("SPACING",
46613705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
46623705ce5bSJoe Perches			    $fix) {
4663194f66fcSJoe Perches				$fixed[$fixlinenr] =~
46643705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
46653705ce5bSJoe Perches			}
46660c73b4ebSAndy Whitcroft		}
46670c73b4ebSAndy Whitcroft
466831070b5dSJoe Perches# Function pointer declarations
466931070b5dSJoe Perches# check spacing between type, funcptr, and args
467031070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
467191f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
467231070b5dSJoe Perches			my $declare = $1;
467331070b5dSJoe Perches			my $pre_pointer_space = $2;
467431070b5dSJoe Perches			my $post_pointer_space = $3;
467531070b5dSJoe Perches			my $funcname = $4;
467631070b5dSJoe Perches			my $post_funcname_space = $5;
467731070b5dSJoe Perches			my $pre_args_space = $6;
467831070b5dSJoe Perches
467991f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
468091f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
468191f72e9cSJoe Perches# don't need a space so don't warn for those.
468291f72e9cSJoe Perches			my $post_declare_space = "";
468391f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
468491f72e9cSJoe Perches				$post_declare_space = $1;
468591f72e9cSJoe Perches				$declare = rtrim($declare);
468691f72e9cSJoe Perches			}
468791f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
468831070b5dSJoe Perches				WARN("SPACING",
468931070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
469091f72e9cSJoe Perches				$post_declare_space = " ";
469131070b5dSJoe Perches			}
469231070b5dSJoe Perches
469331070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
469491f72e9cSJoe Perches# This test is not currently implemented because these declarations are
469591f72e9cSJoe Perches# equivalent to
469691f72e9cSJoe Perches#	int  foo(int bar, ...)
469791f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
469891f72e9cSJoe Perches#
469991f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
470091f72e9cSJoe Perches#				WARN("SPACING",
470191f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
470291f72e9cSJoe Perches#			}
470331070b5dSJoe Perches
470431070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
470531070b5dSJoe Perches			if (defined $pre_pointer_space &&
470631070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
470731070b5dSJoe Perches				WARN("SPACING",
470831070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
470931070b5dSJoe Perches			}
471031070b5dSJoe Perches
471131070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
471231070b5dSJoe Perches			if (defined $post_pointer_space &&
471331070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
471431070b5dSJoe Perches				WARN("SPACING",
471531070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
471631070b5dSJoe Perches			}
471731070b5dSJoe Perches
471831070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
471931070b5dSJoe Perches			if (defined $post_funcname_space &&
472031070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
472131070b5dSJoe Perches				WARN("SPACING",
472231070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
472331070b5dSJoe Perches			}
472431070b5dSJoe Perches
472531070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
472631070b5dSJoe Perches			if (defined $pre_args_space &&
472731070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
472831070b5dSJoe Perches				WARN("SPACING",
472931070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
473031070b5dSJoe Perches			}
473131070b5dSJoe Perches
473231070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4733194f66fcSJoe Perches				$fixed[$fixlinenr] =~
473491f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
473531070b5dSJoe Perches			}
473631070b5dSJoe Perches		}
473731070b5dSJoe Perches
47388d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
47398d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4740fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4741fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
47428d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
47438d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
47448d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4745fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
474638dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
47473705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
47483705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
47493705ce5bSJoe Perches				    $fix) {
4750194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
47513705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
47523705ce5bSJoe Perches				}
47538d31cfceSAndy Whitcroft			}
47548d31cfceSAndy Whitcroft		}
47558d31cfceSAndy Whitcroft
4756f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
47576c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4758c2fdda0dSAndy Whitcroft			my $name = $1;
4759773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4760773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4761c2fdda0dSAndy Whitcroft
4762c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4763773647a0SAndy Whitcroft			if ($name =~ /^(?:
4764773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4765773647a0SAndy Whitcroft				volatile|__volatile__|
4766773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4767773647a0SAndy Whitcroft				asm|__asm__)$/x)
4768773647a0SAndy Whitcroft			{
4769c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4770c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4771c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4772c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4773773647a0SAndy Whitcroft
4774773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4775c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4776c2fdda0dSAndy Whitcroft
4777c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4778c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4779773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4780c2fdda0dSAndy Whitcroft
4781c2fdda0dSAndy Whitcroft			} else {
47823705ce5bSJoe Perches				if (WARN("SPACING",
47833705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
47843705ce5bSJoe Perches					     $fix) {
4785194f66fcSJoe Perches					$fixed[$fixlinenr] =~
47863705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
47873705ce5bSJoe Perches				}
4788f0a594c1SAndy Whitcroft			}
47896c72ffaaSAndy Whitcroft		}
47909a4cad4eSEric Nelson
4791653d4876SAndy Whitcroft# Check operator spacing.
47920a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
47933705ce5bSJoe Perches			my $fixed_line = "";
47943705ce5bSJoe Perches			my $line_fixed = 0;
47953705ce5bSJoe Perches
47969c0ca6f9SAndy Whitcroft			my $ops = qr{
47979c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
47989c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
47999c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
48001f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
480184731623SJoe Perches				\?:|\?|:
48029c0ca6f9SAndy Whitcroft			}x;
4803cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
48043705ce5bSJoe Perches
48053705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
48063705ce5bSJoe Perches##			foreach my $el (@elements) {
48073705ce5bSJoe Perches##				print("el: <$el>\n");
48083705ce5bSJoe Perches##			}
48093705ce5bSJoe Perches
48103705ce5bSJoe Perches			my @fix_elements = ();
481100df344fSAndy Whitcroft			my $off = 0;
48126c72ffaaSAndy Whitcroft
48133705ce5bSJoe Perches			foreach my $el (@elements) {
48143705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
48153705ce5bSJoe Perches				$off += length($el);
48163705ce5bSJoe Perches			}
48173705ce5bSJoe Perches
48183705ce5bSJoe Perches			$off = 0;
48193705ce5bSJoe Perches
48206c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4821b34c648bSJoe Perches			my $last_after = -1;
48226c72ffaaSAndy Whitcroft
48230a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
48243705ce5bSJoe Perches
48253705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
48263705ce5bSJoe Perches
48273705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
48283705ce5bSJoe Perches
48294a0df2efSAndy Whitcroft				$off += length($elements[$n]);
48304a0df2efSAndy Whitcroft
483125985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4832773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4833773647a0SAndy Whitcroft				my $cc = '';
4834773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4835773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4836773647a0SAndy Whitcroft				}
4837773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4838773647a0SAndy Whitcroft
48394a0df2efSAndy Whitcroft				my $a = '';
48404a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
48414a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4842cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
48434a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
48444a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4845773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
48464a0df2efSAndy Whitcroft
48470a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
48484a0df2efSAndy Whitcroft
48494a0df2efSAndy Whitcroft				my $c = '';
48500a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
48514a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
48524a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4853cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
48544a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
48554a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
48568b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
48574a0df2efSAndy Whitcroft				} else {
48584a0df2efSAndy Whitcroft					$c = 'E';
48590a920b5bSAndy Whitcroft				}
48600a920b5bSAndy Whitcroft
48614a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
48624a0df2efSAndy Whitcroft
48634a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
48644a0df2efSAndy Whitcroft
48656c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4866de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
48670a920b5bSAndy Whitcroft
486874048ed8SAndy Whitcroft				# Pull out the value of this operator.
48696c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
48700a920b5bSAndy Whitcroft
48711f65f947SAndy Whitcroft				# Get the full operator variant.
48721f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
48731f65f947SAndy Whitcroft
487413214adfSAndy Whitcroft				# Ignore operators passed as parameters.
487513214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4876d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
487713214adfSAndy Whitcroft
4878cf655043SAndy Whitcroft#				# Ignore comments
4879cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
488013214adfSAndy Whitcroft
4881d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
488213214adfSAndy Whitcroft				} elsif ($op eq ';') {
4883cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4884cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
48853705ce5bSJoe Perches						if (ERROR("SPACING",
48863705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4887b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
48883705ce5bSJoe Perches							$line_fixed = 1;
48893705ce5bSJoe Perches						}
4890d8aaf121SAndy Whitcroft					}
4891d8aaf121SAndy Whitcroft
4892d8aaf121SAndy Whitcroft				# // is a comment
4893d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
48940a920b5bSAndy Whitcroft
4895b00e4814SJoe Perches				#   :   when part of a bitfield
4896b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4897b00e4814SJoe Perches					# skip the bitfield test for now
4898b00e4814SJoe Perches
48991f65f947SAndy Whitcroft				# No spaces for:
49001f65f947SAndy Whitcroft				#   ->
4901b00e4814SJoe Perches				} elsif ($op eq '->') {
49024a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
49033705ce5bSJoe Perches						if (ERROR("SPACING",
49043705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4905b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
49063705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
49073705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
49083705ce5bSJoe Perches							}
4909b34c648bSJoe Perches							$line_fixed = 1;
49103705ce5bSJoe Perches						}
49110a920b5bSAndy Whitcroft					}
49120a920b5bSAndy Whitcroft
49132381097bSJoe Perches				# , must not have a space before and must have a space on the right.
49140a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
49152381097bSJoe Perches					my $rtrim_before = 0;
49162381097bSJoe Perches					my $space_after = 0;
49172381097bSJoe Perches					if ($ctx =~ /Wx./) {
49182381097bSJoe Perches						if (ERROR("SPACING",
49192381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
49202381097bSJoe Perches							$line_fixed = 1;
49212381097bSJoe Perches							$rtrim_before = 1;
49222381097bSJoe Perches						}
49232381097bSJoe Perches					}
4924cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
49253705ce5bSJoe Perches						if (ERROR("SPACING",
49263705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
49273705ce5bSJoe Perches							$line_fixed = 1;
4928b34c648bSJoe Perches							$last_after = $n;
49292381097bSJoe Perches							$space_after = 1;
49302381097bSJoe Perches						}
49312381097bSJoe Perches					}
49322381097bSJoe Perches					if ($rtrim_before || $space_after) {
49332381097bSJoe Perches						if ($rtrim_before) {
49342381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
49352381097bSJoe Perches						} else {
49362381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
49372381097bSJoe Perches						}
49382381097bSJoe Perches						if ($space_after) {
49392381097bSJoe Perches							$good .= " ";
49403705ce5bSJoe Perches						}
49410a920b5bSAndy Whitcroft					}
49420a920b5bSAndy Whitcroft
49439c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
494474048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
49459c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
49469c0ca6f9SAndy Whitcroft
49479c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
49489c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
49499c0ca6f9SAndy Whitcroft				# unary operator, or a cast
49509c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
495174048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
49520d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4953cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
49543705ce5bSJoe Perches						if (ERROR("SPACING",
49553705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4956b34c648bSJoe Perches							if ($n != $last_after + 2) {
4957b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
49583705ce5bSJoe Perches								$line_fixed = 1;
49593705ce5bSJoe Perches							}
49600a920b5bSAndy Whitcroft						}
4961b34c648bSJoe Perches					}
4962a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4963171ae1a4SAndy Whitcroft						# A unary '*' may be const
4964171ae1a4SAndy Whitcroft
4965171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
49663705ce5bSJoe Perches						if (ERROR("SPACING",
49673705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4968b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
49693705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
49703705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
49713705ce5bSJoe Perches							}
4972b34c648bSJoe Perches							$line_fixed = 1;
49733705ce5bSJoe Perches						}
49740a920b5bSAndy Whitcroft					}
49750a920b5bSAndy Whitcroft
49760a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
49770a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4978773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
49793705ce5bSJoe Perches						if (ERROR("SPACING",
49803705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4981b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
49823705ce5bSJoe Perches							$line_fixed = 1;
49833705ce5bSJoe Perches						}
49840a920b5bSAndy Whitcroft					}
4985773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4986773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
49873705ce5bSJoe Perches						if (ERROR("SPACING",
49883705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4989b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
49903705ce5bSJoe Perches							$line_fixed = 1;
49913705ce5bSJoe Perches						}
4992653d4876SAndy Whitcroft					}
4993773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
49943705ce5bSJoe Perches						if (ERROR("SPACING",
49953705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4996b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
49973705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
49983705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4999773647a0SAndy Whitcroft							}
5000b34c648bSJoe Perches							$line_fixed = 1;
50013705ce5bSJoe Perches						}
50023705ce5bSJoe Perches					}
50030a920b5bSAndy Whitcroft
50040a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
50059c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
50069c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
50079c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5008c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5009c2fdda0dSAndy Whitcroft					 $op eq '%')
50100a920b5bSAndy Whitcroft				{
5011d2e025f3SJoe Perches					if ($check) {
5012d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5013d2e025f3SJoe Perches							if (CHK("SPACING",
5014d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5015d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5016d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5017d2e025f3SJoe Perches								$line_fixed = 1;
5018d2e025f3SJoe Perches							}
5019d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5020d2e025f3SJoe Perches							if (CHK("SPACING",
5021d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5022d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5023d2e025f3SJoe Perches								$line_fixed = 1;
5024d2e025f3SJoe Perches							}
5025d2e025f3SJoe Perches						}
5026d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
50273705ce5bSJoe Perches						if (ERROR("SPACING",
50283705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5029b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5030b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5031b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5032b34c648bSJoe Perches							}
50333705ce5bSJoe Perches							$line_fixed = 1;
50343705ce5bSJoe Perches						}
50350a920b5bSAndy Whitcroft					}
50360a920b5bSAndy Whitcroft
50371f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
50381f65f947SAndy Whitcroft				# terminating a case value or a label.
50391f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
50401f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
50413705ce5bSJoe Perches						if (ERROR("SPACING",
50423705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5043b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50443705ce5bSJoe Perches							$line_fixed = 1;
50453705ce5bSJoe Perches						}
50461f65f947SAndy Whitcroft					}
50471f65f947SAndy Whitcroft
50480a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5049cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
50501f65f947SAndy Whitcroft					my $ok = 0;
50511f65f947SAndy Whitcroft
505222f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
50531f65f947SAndy Whitcroft					if (($op eq '<' &&
50541f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
50551f65f947SAndy Whitcroft					    ($op eq '>' &&
50561f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
50571f65f947SAndy Whitcroft					{
50581f65f947SAndy Whitcroft						$ok = 1;
50591f65f947SAndy Whitcroft					}
50601f65f947SAndy Whitcroft
5061e0df7e1fSJoe Perches					# for asm volatile statements
5062e0df7e1fSJoe Perches					# ignore a colon with another
5063e0df7e1fSJoe Perches					# colon immediately before or after
5064e0df7e1fSJoe Perches					if (($op eq ':') &&
5065e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5066e0df7e1fSJoe Perches						$ok = 1;
5067e0df7e1fSJoe Perches					}
5068e0df7e1fSJoe Perches
506984731623SJoe Perches					# messages are ERROR, but ?: are CHK
50701f65f947SAndy Whitcroft					if ($ok == 0) {
50710675a8fbSJean Delvare						my $msg_level = \&ERROR;
50720675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
507384731623SJoe Perches
50740675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
50753705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5076b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5077b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5078b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5079b34c648bSJoe Perches							}
50803705ce5bSJoe Perches							$line_fixed = 1;
50813705ce5bSJoe Perches						}
50820a920b5bSAndy Whitcroft					}
508322f2a2efSAndy Whitcroft				}
50844a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
50853705ce5bSJoe Perches
50863705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
50873705ce5bSJoe Perches
50883705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
50890a920b5bSAndy Whitcroft			}
50903705ce5bSJoe Perches
50913705ce5bSJoe Perches			if (($#elements % 2) == 0) {
50923705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
50933705ce5bSJoe Perches			}
50943705ce5bSJoe Perches
5095194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5096194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
50973705ce5bSJoe Perches			}
50983705ce5bSJoe Perches
50993705ce5bSJoe Perches
51000a920b5bSAndy Whitcroft		}
51010a920b5bSAndy Whitcroft
5102786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5103d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5104786b6326SJoe Perches			if (WARN("SPACING",
5105786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5106786b6326SJoe Perches			    $fix) {
5107194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5108786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5109786b6326SJoe Perches			}
5110786b6326SJoe Perches		}
5111786b6326SJoe Perches
5112f0a594c1SAndy Whitcroft# check for multiple assignments
5113f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5114000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5115000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5116f0a594c1SAndy Whitcroft		}
5117f0a594c1SAndy Whitcroft
511822f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
511922f2a2efSAndy Whitcroft## # continuation.
512022f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
512122f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
512222f2a2efSAndy Whitcroft##
512322f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5124e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
512522f2a2efSAndy Whitcroft## 			my $ln = $line;
512622f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
512722f2a2efSAndy Whitcroft## 			}
512822f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5129000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5130000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
513122f2a2efSAndy Whitcroft## 			}
513222f2a2efSAndy Whitcroft## 		}
5133f0a594c1SAndy Whitcroft
51340a920b5bSAndy Whitcroft#need space before brace following if, while, etc
51356b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
51366ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
51373705ce5bSJoe Perches			if (ERROR("SPACING",
51383705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
51393705ce5bSJoe Perches			    $fix) {
51406ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
51413705ce5bSJoe Perches			}
5142de7d4f0eSAndy Whitcroft		}
5143de7d4f0eSAndy Whitcroft
5144c4a62ef9SJoe Perches## # check for blank lines before declarations
5145c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5146c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5147c4a62ef9SJoe Perches##			WARN("SPACING",
5148c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5149c4a62ef9SJoe Perches##		}
5150c4a62ef9SJoe Perches##
5151c4a62ef9SJoe Perches
5152de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5153de7d4f0eSAndy Whitcroft# on the line
515494fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5155d5e616fcSJoe Perches			if (ERROR("SPACING",
5156d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5157d5e616fcSJoe Perches			    $fix) {
5158194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5159d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5160d5e616fcSJoe Perches			}
51610a920b5bSAndy Whitcroft		}
51620a920b5bSAndy Whitcroft
516322f2a2efSAndy Whitcroft# check spacing on square brackets
516422f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
51653705ce5bSJoe Perches			if (ERROR("SPACING",
51663705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
51673705ce5bSJoe Perches			    $fix) {
5168194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51693705ce5bSJoe Perches				    s/\[\s+/\[/;
51703705ce5bSJoe Perches			}
517122f2a2efSAndy Whitcroft		}
517222f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
51733705ce5bSJoe Perches			if (ERROR("SPACING",
51743705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
51753705ce5bSJoe Perches			    $fix) {
5176194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51773705ce5bSJoe Perches				    s/\s+\]/\]/;
51783705ce5bSJoe Perches			}
517922f2a2efSAndy Whitcroft		}
518022f2a2efSAndy Whitcroft
5181c45dcabdSAndy Whitcroft# check spacing on parentheses
51829c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
51839c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
51843705ce5bSJoe Perches			if (ERROR("SPACING",
51853705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
51863705ce5bSJoe Perches			    $fix) {
5187194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51883705ce5bSJoe Perches				    s/\(\s+/\(/;
51893705ce5bSJoe Perches			}
519022f2a2efSAndy Whitcroft		}
519113214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5192c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5193c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
51943705ce5bSJoe Perches			if (ERROR("SPACING",
51953705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
51963705ce5bSJoe Perches			    $fix) {
5197194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51983705ce5bSJoe Perches				    s/\s+\)/\)/;
51993705ce5bSJoe Perches			}
520022f2a2efSAndy Whitcroft		}
520122f2a2efSAndy Whitcroft
5202e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5203e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5204e2826fd0SJoe Perches
5205e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5206ea4acbb1SJoe Perches			my $var = $1;
5207ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5208ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5209ea4acbb1SJoe Perches			    $fix) {
5210ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5211ea4acbb1SJoe Perches			}
5212ea4acbb1SJoe Perches		}
5213ea4acbb1SJoe Perches
5214ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5215ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5216ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5217ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5218ea4acbb1SJoe Perches			my $var = $2;
5219ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5220ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5221ea4acbb1SJoe Perches			    $fix) {
5222ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5223ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5224ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5225ea4acbb1SJoe Perches			}
5226e2826fd0SJoe Perches		}
5227e2826fd0SJoe Perches
522863b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5229a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5230a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
52315b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
523263b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
523363b7c73eSJoe Perches			my $if_stat = $1;
523463b7c73eSJoe Perches			my $test = substr($2, 1, -1);
523563b7c73eSJoe Perches			my $herectx;
523663b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
523763b7c73eSJoe Perches				my $match = $1;
523863b7c73eSJoe Perches				# avoid parentheses around potential macro args
523963b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
524063b7c73eSJoe Perches				if (!defined($herectx)) {
524163b7c73eSJoe Perches					$herectx = $here . "\n";
524263b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
524363b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
524463b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
524563b7c73eSJoe Perches						$herectx .=  $rl . "\n";
524663b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
524763b7c73eSJoe Perches					}
524863b7c73eSJoe Perches				}
524963b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
525063b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
525163b7c73eSJoe Perches			}
525263b7c73eSJoe Perches		}
525363b7c73eSJoe Perches
52540a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
52554a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
52560a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
52573705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
52583705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
52593705ce5bSJoe Perches			    $fix) {
5260194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52613705ce5bSJoe Perches				    s/^(.)\s+/$1/;
52623705ce5bSJoe Perches			}
52630a920b5bSAndy Whitcroft		}
52640a920b5bSAndy Whitcroft
526540873abaSJoe Perches# check if a statement with a comma should be two statements like:
526640873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
526740873abaSJoe Perches#	bar = baz();
526840873abaSJoe Perches		if (defined($stat) &&
526940873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
527040873abaSJoe Perches			my $cnt = statement_rawlines($stat);
527140873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
527240873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
527340873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
527440873abaSJoe Perches		}
527540873abaSJoe Perches
52765b9553abSJoe Perches# return is not a function
5277507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5278c45dcabdSAndy Whitcroft			my $spacing = $1;
52795b57980dSJoe Perches			if ($perl_version_ok &&
52805b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
52815b9553abSJoe Perches				my $value = $1;
52825b9553abSJoe Perches				$value = deparenthesize($value);
52835b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5284000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5285000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
52865b9553abSJoe Perches				}
5287c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5288000d1cc1SJoe Perches				ERROR("SPACING",
5289000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5290c45dcabdSAndy Whitcroft			}
5291c45dcabdSAndy Whitcroft		}
5292507e5141SJoe Perches
5293b43ae21bSJoe Perches# unnecessary return in a void function
5294b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5295b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5296b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5297b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5298b43ae21bSJoe Perches		    $linenr >= 3 &&
5299b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5300b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
53019819cf25SJoe Perches			WARN("RETURN_VOID",
5302b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
53039819cf25SJoe Perches		}
53049819cf25SJoe Perches
5305189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
53065b57980dSJoe Perches		if ($perl_version_ok &&
5307189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5308189248d8SJoe Perches			my $openparens = $1;
5309189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5310189248d8SJoe Perches			my $msg = "";
5311189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5312189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5313189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5314189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5315189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5316189248d8SJoe Perches			}
5317189248d8SJoe Perches		}
5318189248d8SJoe Perches
5319c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5320c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5321c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5322c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
53235b57980dSJoe Perches		if ($perl_version_ok &&
5324c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5325c5595fa2SJoe Perches			my $lead = $1;
5326c5595fa2SJoe Perches			my $const = $2;
5327c5595fa2SJoe Perches			my $comp = $3;
5328c5595fa2SJoe Perches			my $to = $4;
5329c5595fa2SJoe Perches			my $newcomp = $comp;
5330f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5331c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5332c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5333c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5334c5595fa2SJoe Perches			    $fix) {
5335c5595fa2SJoe Perches				if ($comp eq "<") {
5336c5595fa2SJoe Perches					$newcomp = ">";
5337c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5338c5595fa2SJoe Perches					$newcomp = ">=";
5339c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5340c5595fa2SJoe Perches					$newcomp = "<";
5341c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5342c5595fa2SJoe Perches					$newcomp = "<=";
5343c5595fa2SJoe Perches				}
5344c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5345c5595fa2SJoe Perches			}
5346c5595fa2SJoe Perches		}
5347c5595fa2SJoe Perches
5348f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5349f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
535053a3c448SAndy Whitcroft			my $name = $1;
535153a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
5352000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5353f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
535453a3c448SAndy Whitcroft			}
535553a3c448SAndy Whitcroft		}
5356c45dcabdSAndy Whitcroft
53570a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
53584a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
53593705ce5bSJoe Perches			if (ERROR("SPACING",
53603705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
53613705ce5bSJoe Perches			    $fix) {
5362194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53633705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
53643705ce5bSJoe Perches			}
53650a920b5bSAndy Whitcroft		}
53660a920b5bSAndy Whitcroft
5367f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5368f5fe35ddSAndy Whitcroft# statements after the conditional.
5369170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
53703e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
53713e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
53723e469cdcSAndy Whitcroft					if (!defined $stat);
5373170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5374170d3a22SAndy Whitcroft						$remain_next, $off_next);
5375170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5376170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5377170d3a22SAndy Whitcroft
5378170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5379170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5380170d3a22SAndy Whitcroft				# then count those as offsets.
5381170d3a22SAndy Whitcroft				my ($whitespace) =
5382170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5383170d3a22SAndy Whitcroft				my $offset =
5384170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5385170d3a22SAndy Whitcroft
5386170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5387170d3a22SAndy Whitcroft								$offset} = 1;
5388170d3a22SAndy Whitcroft			}
5389170d3a22SAndy Whitcroft		}
5390170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5391c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5392170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5393171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
53948905a67cSAndy Whitcroft
5395b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
539665b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
539765b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
539865b64b3bSJoe Perches				    $fix && $perl_version_ok) {
539965b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
540065b64b3bSJoe Perches						my $space = $1;
540165b64b3bSJoe Perches						my $not = $2;
540265b64b3bSJoe Perches						my $statement = $3;
540365b64b3bSJoe Perches						my $assigned = $4;
540465b64b3bSJoe Perches						my $test = $8;
540565b64b3bSJoe Perches						my $against = $9;
540665b64b3bSJoe Perches						my $brace = $15;
540765b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
540865b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
540965b64b3bSJoe Perches						my $newline = "${space}if (";
541065b64b3bSJoe Perches						$newline .= '!' if defined($not);
541165b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
541265b64b3bSJoe Perches						$newline .= "$assigned";
541365b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
541465b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
541565b64b3bSJoe Perches						$newline .= ')';
541665b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
541765b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
541865b64b3bSJoe Perches					}
541965b64b3bSJoe Perches				}
54208905a67cSAndy Whitcroft			}
54218905a67cSAndy Whitcroft
54228905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
54238905a67cSAndy Whitcroft			# conditional.
5424773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
54258905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
542613214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
542753210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
542853210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5429773647a0SAndy Whitcroft			{
5430bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5431bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5432bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
543342bdf74cSHidetoshi Seto				my $stat_real = '';
5434bb44ad39SAndy Whitcroft
543542bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
543642bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5437bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5438bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5439bb44ad39SAndy Whitcroft				}
5440bb44ad39SAndy Whitcroft
5441000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5442000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
54438905a67cSAndy Whitcroft			}
54448905a67cSAndy Whitcroft		}
54458905a67cSAndy Whitcroft
544613214adfSAndy Whitcroft# Check for bitwise tests written as boolean
544713214adfSAndy Whitcroft		if ($line =~ /
544813214adfSAndy Whitcroft			(?:
544913214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
545013214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
545113214adfSAndy Whitcroft				(?:\&\&|\|\|)
545213214adfSAndy Whitcroft			|
545313214adfSAndy Whitcroft				(?:\&\&|\|\|)
545413214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
545513214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
545613214adfSAndy Whitcroft			)/x)
545713214adfSAndy Whitcroft		{
5458000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5459000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
546013214adfSAndy Whitcroft		}
546113214adfSAndy Whitcroft
54628905a67cSAndy Whitcroft# if and else should not have general statements after it
546313214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
546413214adfSAndy Whitcroft			my $s = $1;
546513214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
546613214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5467000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5468000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
54690a920b5bSAndy Whitcroft			}
547013214adfSAndy Whitcroft		}
547139667782SAndy Whitcroft# if should not continue a brace
547239667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5473000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5474048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
547539667782SAndy Whitcroft				$herecurr);
547639667782SAndy Whitcroft		}
5477a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5478a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5479a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
54803fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5481a1080bf8SAndy Whitcroft			\s*return\s+
5482a1080bf8SAndy Whitcroft		    )/xg)
5483a1080bf8SAndy Whitcroft		{
5484000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5485000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5486a1080bf8SAndy Whitcroft		}
54870a920b5bSAndy Whitcroft
54880a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
54890a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
54908b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
54910a920b5bSAndy Whitcroft		    $previndent == $indent) {
54928b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
54938b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
54948b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
54958b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
54968b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
54978b8856f4SJoe Perches				my $fixedline = $prevrawline;
54988b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
54998b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
55008b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55018b8856f4SJoe Perches				}
55028b8856f4SJoe Perches				$fixedline = $rawline;
55038b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
55048b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
55058b8856f4SJoe Perches			}
55060a920b5bSAndy Whitcroft		}
55070a920b5bSAndy Whitcroft
55088b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5509c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5510c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5511c2fdda0dSAndy Whitcroft
5512c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5513c2fdda0dSAndy Whitcroft			# conditional.
5514773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5515c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5516c2fdda0dSAndy Whitcroft
5517c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
55188b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
55198b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
55208b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
55218b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
55228b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
55238b8856f4SJoe Perches					my $fixedline = $prevrawline;
55248b8856f4SJoe Perches					my $trailing = $rawline;
55258b8856f4SJoe Perches					$trailing =~ s/^\+//;
55268b8856f4SJoe Perches					$trailing = trim($trailing);
55278b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
55288b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55298b8856f4SJoe Perches				}
5530c2fdda0dSAndy Whitcroft			}
5531c2fdda0dSAndy Whitcroft		}
5532c2fdda0dSAndy Whitcroft
553395e2c602SJoe Perches#Specific variable tests
5534323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5535323c1260SJoe Perches			my $var = $1;
553695e2c602SJoe Perches
553795e2c602SJoe Perches#CamelCase
5538807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5539be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
55404104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
55414104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
554222735ce8SJoe Perches#Ignore Page<foo> variants
5543807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5544d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5545d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5546d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5547f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5548f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
55497e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
55507e781f67SJoe Perches					my $word = $1;
55517e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5552d8b07710SJoe Perches					if ($check) {
5553d8b07710SJoe Perches						seed_camelcase_includes();
5554d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5555d8b07710SJoe Perches							seed_camelcase_file($realfile);
5556d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5557d8b07710SJoe Perches						}
5558d8b07710SJoe Perches					}
55597e781f67SJoe Perches					if (!defined $camelcase{$word}) {
55607e781f67SJoe Perches						$camelcase{$word} = 1;
5561be79794bSJoe Perches						CHK("CAMELCASE",
55627e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
55637e781f67SJoe Perches					}
5564323c1260SJoe Perches				}
5565323c1260SJoe Perches			}
55663445686aSJoe Perches		}
55670a920b5bSAndy Whitcroft
55680a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5569d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5570d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5571d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5572d5e616fcSJoe Perches			    $fix) {
5573194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5574d5e616fcSJoe Perches			}
55750a920b5bSAndy Whitcroft		}
55760a920b5bSAndy Whitcroft
55770e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
55780e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5579c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5580e09dec48SAndy Whitcroft			my $file = "$1.h";
5581e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5582e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5583e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
55847840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5585c45dcabdSAndy Whitcroft			{
55860e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
55870e212e0aSFabian Frederick				if ($asminclude > 0) {
5588e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5589000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5590000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5591e09dec48SAndy Whitcroft					} else {
5592000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5593000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5594e09dec48SAndy Whitcroft					}
55950a920b5bSAndy Whitcroft				}
55960a920b5bSAndy Whitcroft			}
55970e212e0aSFabian Frederick		}
55980a920b5bSAndy Whitcroft
5599653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5600653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5601cf655043SAndy Whitcroft# in a known good container
5602b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5603b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5604d8aaf121SAndy Whitcroft			my $ln = $linenr;
5605d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5606c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5607c45dcabdSAndy Whitcroft			my $ctx = '';
560808a2843eSJoe Perches			my $has_flow_statement = 0;
560908a2843eSJoe Perches			my $has_arg_concat = 0;
5610c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5611f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5612f74bd194SAndy Whitcroft			$ctx = $dstat;
5613c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5614a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5615c45dcabdSAndy Whitcroft
561608a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
561762e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
561808a2843eSJoe Perches
5619f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5620f59b64bfSJoe Perches			my $define_args = $1;
5621f59b64bfSJoe Perches			my $define_stmt = $dstat;
5622f59b64bfSJoe Perches			my @def_args = ();
5623f59b64bfSJoe Perches
5624f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5625f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5626f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
56278c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5628f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5629f59b64bfSJoe Perches			}
5630f59b64bfSJoe Perches
5631292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5632c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5633c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5634c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5635c45dcabdSAndy Whitcroft
5636c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
56372e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
56382e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
56392e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5640bf30d6edSAndy Whitcroft			{
5641c45dcabdSAndy Whitcroft			}
5642c45dcabdSAndy Whitcroft
5643342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
564433acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
564533acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5646e45bab8eSAndy Whitcroft			{
5647e45bab8eSAndy Whitcroft			}
5648e45bab8eSAndy Whitcroft
564942e15293SJoe Perches			# Make asm volatile uses seem like a generic function
565042e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
565142e15293SJoe Perches
5652c45dcabdSAndy Whitcroft			my $exceptions = qr{
5653c45dcabdSAndy Whitcroft				$Declare|
5654c45dcabdSAndy Whitcroft				module_param_named|
5655a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5656c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5657c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5658383099fdSAndy Whitcroft				__typeof__\(|
565922fd2d3eSStefani Seibold				union|
566022fd2d3eSStefani Seibold				struct|
5661ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
56626b10df42SVladimir Zapolskiy				^\"|\"$|
56636b10df42SVladimir Zapolskiy				^\[
5664c45dcabdSAndy Whitcroft			}x;
56655eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5666f59b64bfSJoe Perches
5667f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5668f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5669e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5670f59b64bfSJoe Perches
5671f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5672f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5673f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
56743cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5675356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5676f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5677f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5678e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
567972f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
56802e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5681f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5682f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5683f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
56844e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5685f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5686c45dcabdSAndy Whitcroft			{
5687e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5688e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5689e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5690e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5691f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5692f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5693f74bd194SAndy Whitcroft				} else {
5694000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5695388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5696d8aaf121SAndy Whitcroft				}
5697f59b64bfSJoe Perches
5698f59b64bfSJoe Perches			}
56995207649bSJoe Perches
57005207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
57015207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
57025207649bSJoe Perches			my $first = 1;
57035207649bSJoe Perches			$define_stmt = "";
57045207649bSJoe Perches			foreach my $l (@stmt_array) {
57055207649bSJoe Perches				$l =~ s/\\$//;
57065207649bSJoe Perches				if ($first) {
57075207649bSJoe Perches					$define_stmt = $l;
57085207649bSJoe Perches					$first = 0;
57095207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
57105207649bSJoe Perches					$define_stmt .= substr($l, 1);
57115207649bSJoe Perches				}
57125207649bSJoe Perches			}
57135207649bSJoe Perches			$define_stmt =~ s/$;//g;
57145207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
57155207649bSJoe Perches			$define_stmt = trim($define_stmt);
57165207649bSJoe Perches
5717f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5718f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5719f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
57209192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
57217fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
57226dba824eSBrendan Jackman				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
57237fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
57247fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5725d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5726f59b64bfSJoe Perches				if ($use_cnt > 1) {
5727f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5728f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5729f59b64bfSJoe Perches				    }
57309192d41aSJoe Perches# check if any macro arguments may have other precedence issues
57317fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
57329192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
57339192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
57349192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
57359192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
57369192d41aSJoe Perches				}
57370a920b5bSAndy Whitcroft			}
57385023d347SJoe Perches
573908a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
574008a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
574108a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
574208a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5743e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
574408a2843eSJoe Perches
574508a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
574608a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
574708a2843eSJoe Perches			}
574808a2843eSJoe Perches
5749481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
57505023d347SJoe Perches
57515023d347SJoe Perches		} else {
57525023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5753481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5754481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
57555023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
57565023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
57575023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
57585023d347SJoe Perches			}
5759653d4876SAndy Whitcroft		}
57600a920b5bSAndy Whitcroft
5761b13edf7fSJoe Perches# do {} while (0) macro tests:
5762b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5763b13edf7fSJoe Perches# macro should not end with a semicolon
57645b57980dSJoe Perches		if ($perl_version_ok &&
5765b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5766b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5767b13edf7fSJoe Perches			my $ln = $linenr;
5768b13edf7fSJoe Perches			my $cnt = $realcnt;
5769b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5770b13edf7fSJoe Perches			my $ctx = '';
5771b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5772b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5773b13edf7fSJoe Perches			$ctx = $dstat;
5774b13edf7fSJoe Perches
5775b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
57761b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5777b13edf7fSJoe Perches
5778b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5779b13edf7fSJoe Perches				my $stmts = $2;
5780b13edf7fSJoe Perches				my $semis = $3;
5781b13edf7fSJoe Perches
5782b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5783b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5784e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5785b13edf7fSJoe Perches
5786ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5787ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5788b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5789b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5790b13edf7fSJoe Perches				}
5791b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5792b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5793b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5794b13edf7fSJoe Perches				}
5795f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5796f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5797f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5798e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5799f5ef95b1SJoe Perches
5800f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5801f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5802b13edf7fSJoe Perches			}
5803b13edf7fSJoe Perches		}
5804b13edf7fSJoe Perches
5805f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
580613214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
580713214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5808cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
580913214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5810cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5811cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5812aad4f614SJoe Perches				my @allowed = ();
5813aad4f614SJoe Perches				my $allow = 0;
581413214adfSAndy Whitcroft				my $seen = 0;
5815773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5816cf655043SAndy Whitcroft				my $ln = $linenr - 1;
581713214adfSAndy Whitcroft				for my $chunk (@chunks) {
581813214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
581913214adfSAndy Whitcroft
5820773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5821773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5822773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5823773647a0SAndy Whitcroft
5824aad4f614SJoe Perches					$allowed[$allow] = 0;
5825773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5826773647a0SAndy Whitcroft
5827773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5828773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5829773647a0SAndy Whitcroft
5830773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5831cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5832cf655043SAndy Whitcroft
5833773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
583413214adfSAndy Whitcroft
583513214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
583613214adfSAndy Whitcroft
5837aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5838cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5839cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5840aad4f614SJoe Perches						$allowed[$allow] = 1;
584113214adfSAndy Whitcroft					}
584213214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5843cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5844aad4f614SJoe Perches						$allowed[$allow] = 1;
584513214adfSAndy Whitcroft					}
5846cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5847cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5848aad4f614SJoe Perches						$allowed[$allow] = 1;
584913214adfSAndy Whitcroft					}
5850aad4f614SJoe Perches					$allow++;
585113214adfSAndy Whitcroft				}
5852aad4f614SJoe Perches				if ($seen) {
5853aad4f614SJoe Perches					my $sum_allowed = 0;
5854aad4f614SJoe Perches					foreach (@allowed) {
5855aad4f614SJoe Perches						$sum_allowed += $_;
5856aad4f614SJoe Perches					}
5857aad4f614SJoe Perches					if ($sum_allowed == 0) {
5858000d1cc1SJoe Perches						WARN("BRACES",
5859000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5860aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5861aad4f614SJoe Perches						 $seen != $allow) {
5862aad4f614SJoe Perches						CHK("BRACES",
5863aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5864aad4f614SJoe Perches					}
586513214adfSAndy Whitcroft				}
586613214adfSAndy Whitcroft			}
586713214adfSAndy Whitcroft		}
5868773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
586913214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5870cf655043SAndy Whitcroft			my $allowed = 0;
5871f0a594c1SAndy Whitcroft
5872cf655043SAndy Whitcroft			# Check the pre-context.
5873cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5874cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5875cf655043SAndy Whitcroft				$allowed = 1;
5876f0a594c1SAndy Whitcroft			}
5877773647a0SAndy Whitcroft
5878773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5879773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5880773647a0SAndy Whitcroft
5881cf655043SAndy Whitcroft			# Check the condition.
5882cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5883773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5884cf655043SAndy Whitcroft			if (defined $cond) {
5885773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5886cf655043SAndy Whitcroft			}
5887cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5888cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5889cf655043SAndy Whitcroft				$allowed = 1;
5890cf655043SAndy Whitcroft			}
5891cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5892cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5893cf655043SAndy Whitcroft				$allowed = 1;
5894cf655043SAndy Whitcroft			}
5895cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5896cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5897cf655043SAndy Whitcroft				$allowed = 1;
5898cf655043SAndy Whitcroft			}
5899cf655043SAndy Whitcroft			# Check the post-context.
5900cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5901cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5902cf655043SAndy Whitcroft				if (defined $cond) {
5903773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5904cf655043SAndy Whitcroft				}
5905cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5906cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5907cf655043SAndy Whitcroft					$allowed = 1;
5908cf655043SAndy Whitcroft				}
5909cf655043SAndy Whitcroft			}
5910cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5911f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5912e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5913cf655043SAndy Whitcroft
5914000d1cc1SJoe Perches				WARN("BRACES",
5915000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5916f0a594c1SAndy Whitcroft			}
5917f0a594c1SAndy Whitcroft		}
5918f0a594c1SAndy Whitcroft
5919e4c5babdSJoe Perches# check for single line unbalanced braces
592095330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
592195330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5922e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5923e4c5babdSJoe Perches		}
5924e4c5babdSJoe Perches
59250979ae66SJoe Perches# check for unnecessary blank lines around braces
592677b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5927f8e58219SJoe Perches			if (CHK("BRACES",
5928f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5929f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5930f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5931f8e58219SJoe Perches			}
59320979ae66SJoe Perches		}
593377b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5934f8e58219SJoe Perches			if (CHK("BRACES",
5935f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5936f8e58219SJoe Perches			    $fix) {
5937f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5938f8e58219SJoe Perches			}
59390979ae66SJoe Perches		}
59400979ae66SJoe Perches
59414a0df2efSAndy Whitcroft# no volatiles please
59426c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
59436c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5944000d1cc1SJoe Perches			WARN("VOLATILE",
59458c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
59464a0df2efSAndy Whitcroft		}
59474a0df2efSAndy Whitcroft
59485e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
59495e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
59505e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
59515e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
595233acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
59535e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
59545e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
59555e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
59565e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
59575e4f6ba5SJoe Perches				     $fix &&
59585e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
59595e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
59605e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
59615e4f6ba5SJoe Perches				my $comma_close = "";
59625e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
59635e4f6ba5SJoe Perches					$comma_close = $1;
59645e4f6ba5SJoe Perches				}
59655e4f6ba5SJoe Perches
59665e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
59675e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
59685e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
59695e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
59705e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
59715e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
59725e4f6ba5SJoe Perches				$fixedline = $rawline;
59735e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
59745e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
59755e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
59765e4f6ba5SJoe Perches				}
59775e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
59785e4f6ba5SJoe Perches			}
59795e4f6ba5SJoe Perches		}
59805e4f6ba5SJoe Perches
59815e4f6ba5SJoe Perches# check for missing a space in a string concatenation
59825e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
59835e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
59845e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
59855e4f6ba5SJoe Perches		}
59865e4f6ba5SJoe Perches
598777cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5988e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5989e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5990e4b7d309SJoe Perches# function declarations
599177cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
599277cb8546SJoe Perches		    defined($context_function) &&
5993e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5994e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
599577cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5996e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
599777cb8546SJoe Perches		}
599877cb8546SJoe Perches
5999*adb2da82SJoe Perches# check for unnecessary function tracing like uses
6000*adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6001*adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6002*adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6003*adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6004*adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6005*adb2da82SJoe Perches			    $fix) {
6006*adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6007*adb2da82SJoe Perches			}
6008*adb2da82SJoe Perches		}
6009*adb2da82SJoe Perches
60105e4f6ba5SJoe Perches# check for spaces before a quoted newline
60115e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
60125e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
60135e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
60145e4f6ba5SJoe Perches			    $fix) {
60155e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
60165e4f6ba5SJoe Perches			}
60175e4f6ba5SJoe Perches
60185e4f6ba5SJoe Perches		}
60195e4f6ba5SJoe Perches
6020f17dba4fSJoe Perches# concatenated string without spaces between elements
602179682c0cSJoe Perches		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
602279682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
602379682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
602479682c0cSJoe Perches			    $fix) {
602579682c0cSJoe Perches				while ($line =~ /($String)/g) {
602679682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
602779682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
602879682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
602979682c0cSJoe Perches				}
603079682c0cSJoe Perches			}
6031f17dba4fSJoe Perches		}
6032f17dba4fSJoe Perches
603390ad30e5SJoe Perches# uncoalesced string fragments
603433acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
603579682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
603679682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
603779682c0cSJoe Perches			    $fix) {
603879682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
603979682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
604079682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
604179682c0cSJoe Perches				}
604279682c0cSJoe Perches			}
604390ad30e5SJoe Perches		}
604490ad30e5SJoe Perches
6045522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6046522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6047522b837cSAlexey Dobriyan		my $show_Z = 1;
60485e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6049522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
60505e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6051522b837cSAlexey Dobriyan			# check for %L
6052522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
60535e4f6ba5SJoe Perches				WARN("PRINTF_L",
6054522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6055522b837cSAlexey Dobriyan				$show_L = 0;
60565e4f6ba5SJoe Perches			}
6057522b837cSAlexey Dobriyan			# check for %Z
6058522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6059522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6060522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6061522b837cSAlexey Dobriyan				$show_Z = 0;
6062522b837cSAlexey Dobriyan			}
6063522b837cSAlexey Dobriyan			# check for 0x<decimal>
6064522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6065522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
60666e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
60676e300757SJoe Perches			}
60685e4f6ba5SJoe Perches		}
60695e4f6ba5SJoe Perches
60705e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
60713f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
60725e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
60735e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
60745e4f6ba5SJoe Perches		}
60755e4f6ba5SJoe Perches
607600df344fSAndy Whitcroft# warn about #if 0
6077c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
607860f89010SPrakruthi Deepak Heragu			WARN("IF_0",
607960f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
608060f89010SPrakruthi Deepak Heragu		}
608160f89010SPrakruthi Deepak Heragu
608260f89010SPrakruthi Deepak Heragu# warn about #if 1
608360f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
608460f89010SPrakruthi Deepak Heragu			WARN("IF_1",
608560f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
60864a0df2efSAndy Whitcroft		}
60874a0df2efSAndy Whitcroft
608803df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
608903df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6090100425deSJoe Perches			my $tested = quotemeta($1);
6091100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6092100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6093100425deSJoe Perches				my $func = $1;
6094100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6095100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6096100425deSJoe Perches				    $fix) {
6097100425deSJoe Perches					my $do_fix = 1;
6098100425deSJoe Perches					my $leading_tabs = "";
6099100425deSJoe Perches					my $new_leading_tabs = "";
6100100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6101100425deSJoe Perches						$leading_tabs = $1;
6102100425deSJoe Perches					} else {
6103100425deSJoe Perches						$do_fix = 0;
6104100425deSJoe Perches					}
6105100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6106100425deSJoe Perches						$new_leading_tabs = $1;
6107100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6108100425deSJoe Perches							$do_fix = 0;
6109100425deSJoe Perches						}
6110100425deSJoe Perches					} else {
6111100425deSJoe Perches						$do_fix = 0;
6112100425deSJoe Perches					}
6113100425deSJoe Perches					if ($do_fix) {
6114100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6115100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6116100425deSJoe Perches					}
6117100425deSJoe Perches				}
61184c432a8fSGreg Kroah-Hartman			}
61194c432a8fSGreg Kroah-Hartman		}
6120f0a594c1SAndy Whitcroft
6121ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6122ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6123ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6124ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6125ebfdc409SJoe Perches		    $linenr > 3) {
6126ebfdc409SJoe Perches			my $testval = $2;
6127ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6128ebfdc409SJoe Perches
6129ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6130ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6131ebfdc409SJoe Perches
6132e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6133e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6134ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6135ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6136ebfdc409SJoe Perches			}
6137ebfdc409SJoe Perches		}
6138ebfdc409SJoe Perches
6139f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6140dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6141f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6142f78d98f6SJoe Perches			my $level = $1;
6143f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6144f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6145f78d98f6SJoe Perches			    $fix) {
6146f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6147f78d98f6SJoe Perches			}
6148f78d98f6SJoe Perches		}
6149f78d98f6SJoe Perches
615045c55e92SJoe Perches# check for logging continuations
615145c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
615245c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
615345c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
615445c55e92SJoe Perches		}
615545c55e92SJoe Perches
615670eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
615770eb2275SDwaipayan Ray		if (defined $stat &&
615870eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
615970eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
616070eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
616170eb2275SDwaipayan Ray			$lc = $lc + $linenr;
616270eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
616370eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
616470eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
616570eb2275SDwaipayan Ray				my $pspec = $1;
616670eb2275SDwaipayan Ray				my $h = $2;
616770eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
616870eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
616970eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
617070eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
617170eb2275SDwaipayan Ray					my $nspec = $pspec;
617270eb2275SDwaipayan Ray					$nspec =~ s/h//g;
617370eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
617470eb2275SDwaipayan Ray				}
617570eb2275SDwaipayan Ray			}
617670eb2275SDwaipayan Ray		}
617770eb2275SDwaipayan Ray
6178abb08a53SJoe Perches# check for mask then right shift without a parentheses
61795b57980dSJoe Perches		if ($perl_version_ok &&
6180abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6181abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6182abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6183abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6184abb08a53SJoe Perches		}
6185abb08a53SJoe Perches
6186b75ac618SJoe Perches# check for pointer comparisons to NULL
61875b57980dSJoe Perches		if ($perl_version_ok) {
6188b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6189b75ac618SJoe Perches				my $val = $1;
6190b75ac618SJoe Perches				my $equal = "!";
6191b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6192b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6193b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6194b75ac618SJoe Perches					    $fix) {
6195b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6196b75ac618SJoe Perches				}
6197b75ac618SJoe Perches			}
6198b75ac618SJoe Perches		}
6199b75ac618SJoe Perches
62008716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
62018716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
62028716de38SJoe Perches			my $attr = $1;
62038716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
62048716de38SJoe Perches				my $ptr = $1;
62058716de38SJoe Perches				my $var = $2;
62068716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
62078716de38SJoe Perches				      ERROR("MISPLACED_INIT",
62088716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
62098716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
62108716de38SJoe Perches				      WARN("MISPLACED_INIT",
62118716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
62128716de38SJoe Perches				    $fix) {
6213194f66fcSJoe 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;
62148716de38SJoe Perches				}
62158716de38SJoe Perches			}
62168716de38SJoe Perches		}
62178716de38SJoe Perches
6218e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6219e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6220e970b884SJoe Perches			my $attr = $1;
6221e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6222e970b884SJoe Perches			my $attr_prefix = $1;
6223e970b884SJoe Perches			my $attr_type = $2;
6224e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6225e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6226e970b884SJoe Perches			    $fix) {
6227194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6228e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6229e970b884SJoe Perches			}
6230e970b884SJoe Perches		}
6231e970b884SJoe Perches
6232e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6233e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6234e970b884SJoe Perches			my $attr = $1;
6235e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6236e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6237e970b884SJoe Perches			    $fix) {
6238194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6239e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6240e970b884SJoe Perches				$lead = rtrim($1);
6241e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6242e970b884SJoe Perches				$lead = "${lead}const ";
6243194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6244e970b884SJoe Perches			}
6245e970b884SJoe Perches		}
6246e970b884SJoe Perches
6247c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6248c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6249c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6250c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6251c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6252c17893c7SJoe Perches			    $fix) {
6253c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6254c17893c7SJoe Perches			}
6255c17893c7SJoe Perches		}
6256c17893c7SJoe Perches
6257fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6258fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6259fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6260fbdb8138SJoe Perches			my $constant_func = $1;
6261fbdb8138SJoe Perches			my $func = $constant_func;
6262fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6263fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6264fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6265fbdb8138SJoe Perches			    $fix) {
6266194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6267fbdb8138SJoe Perches			}
6268fbdb8138SJoe Perches		}
6269fbdb8138SJoe Perches
62701a15a250SPatrick Pannuto# prefer usleep_range over udelay
627137581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
627243c1d77cSJoe Perches			my $delay = $1;
62731a15a250SPatrick Pannuto			# ignore udelay's < 10, however
627443c1d77cSJoe Perches			if (! ($delay < 10) ) {
6275000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6276458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
627743c1d77cSJoe Perches			}
627843c1d77cSJoe Perches			if ($delay > 2000) {
627943c1d77cSJoe Perches				WARN("LONG_UDELAY",
628043c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
62811a15a250SPatrick Pannuto			}
62821a15a250SPatrick Pannuto		}
62831a15a250SPatrick Pannuto
628409ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
628509ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
628609ef8725SPatrick Pannuto			if ($1 < 20) {
6287000d1cc1SJoe Perches				WARN("MSLEEP",
6288458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
628909ef8725SPatrick Pannuto			}
629009ef8725SPatrick Pannuto		}
629109ef8725SPatrick Pannuto
629236ec1939SJoe Perches# check for comparisons of jiffies
629336ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
629436ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
629536ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
629636ec1939SJoe Perches		}
629736ec1939SJoe Perches
62989d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
62999d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
63009d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
63019d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
63029d7a34a5SJoe Perches		}
63039d7a34a5SJoe Perches
630400df344fSAndy Whitcroft# warn about #ifdefs in C files
6305c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
630600df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
630700df344fSAndy Whitcroft#			print "$herecurr";
630800df344fSAndy Whitcroft#			$clean = 0;
630900df344fSAndy Whitcroft#		}
631000df344fSAndy Whitcroft
631122f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6312c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
63133705ce5bSJoe Perches			if (ERROR("SPACING",
63143705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
63153705ce5bSJoe Perches			    $fix) {
6316194f66fcSJoe Perches				$fixed[$fixlinenr] =~
63173705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
63183705ce5bSJoe Perches			}
63193705ce5bSJoe Perches
632022f2a2efSAndy Whitcroft		}
632122f2a2efSAndy Whitcroft
63224a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6323171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6324171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
63254a0df2efSAndy Whitcroft			my $which = $1;
63264a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6327000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6328000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
63294a0df2efSAndy Whitcroft			}
63304a0df2efSAndy Whitcroft		}
63314a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6332402c2553SMichael S. Tsirkin
6333402c2553SMichael S. Tsirkin		my $barriers = qr{
6334402c2553SMichael S. Tsirkin			mb|
6335402c2553SMichael S. Tsirkin			rmb|
6336ad83ec6cSWill Deacon			wmb
6337402c2553SMichael S. Tsirkin		}x;
6338402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6339402c2553SMichael S. Tsirkin			mb__before_atomic|
6340402c2553SMichael S. Tsirkin			mb__after_atomic|
6341402c2553SMichael S. Tsirkin			store_release|
6342402c2553SMichael S. Tsirkin			load_acquire|
6343402c2553SMichael S. Tsirkin			store_mb|
6344402c2553SMichael S. Tsirkin			(?:$barriers)
6345402c2553SMichael S. Tsirkin		}x;
6346402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6347402c2553SMichael S. Tsirkin			(?:$barriers)|
634843e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
634943e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6350402c2553SMichael S. Tsirkin		}x;
6351402c2553SMichael S. Tsirkin
6352402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
63534a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6354c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6355000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
63564a0df2efSAndy Whitcroft			}
63574a0df2efSAndy Whitcroft		}
63583ad81779SPaul E. McKenney
6359f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6360f4073b0fSMichael S. Tsirkin
6361f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6362f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6363f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6364f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6365f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6366f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6367f4073b0fSMichael S. Tsirkin		}
6368f4073b0fSMichael S. Tsirkin
6369cb426e99SJoe Perches# check for waitqueue_active without a comment.
6370cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6371cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6372cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6373cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6374cb426e99SJoe Perches			}
6375cb426e99SJoe Perches		}
63763ad81779SPaul E. McKenney
63775099a722SMarco Elver# check for data_race without a comment.
63785099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
63795099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
63805099a722SMarco Elver				WARN("DATA_RACE",
63815099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
63825099a722SMarco Elver			}
63835099a722SMarco Elver		}
63845099a722SMarco Elver
63854a0df2efSAndy Whitcroft# check of hardware specific defines
6386c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6387000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6388000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
63890a920b5bSAndy Whitcroft		}
6390653d4876SAndy Whitcroft
6391596ed45bSJoe Perches# check that the storage class is not after a type
6392596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6393000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6394596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6395596ed45bSJoe Perches		}
6396596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6397596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6398596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6399596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6400596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6401596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6402596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6403d4977c78STobias Klauser		}
6404d4977c78STobias Klauser
6405de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6406de7d4f0eSAndy Whitcroft# storage class and type.
64079c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
64089c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6409000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6410000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6411de7d4f0eSAndy Whitcroft		}
6412de7d4f0eSAndy Whitcroft
64138905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
64142b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
64152b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6416d5e616fcSJoe Perches			if (WARN("INLINE",
6417d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6418d5e616fcSJoe Perches			    $fix) {
6419194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6420d5e616fcSJoe Perches
6421d5e616fcSJoe Perches			}
64228905a67cSAndy Whitcroft		}
64238905a67cSAndy Whitcroft
64247ebe1d17SDwaipayan Ray# Check for compiler attributes
64252b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
64267ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
64277ebe1d17SDwaipayan Ray			my $attr = $1;
64287ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
64297ebe1d17SDwaipayan Ray
64307ebe1d17SDwaipayan Ray			my %attr_list = (
64310830aab0SJoe Perches				"alias"				=> "__alias",
64327ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
64337ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
64347ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
64357ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
64367ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
64377ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
64387ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
64397ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
64407ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
64417ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
64427ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
64437ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
64447ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
64457ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
64467ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
64477ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
64487ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
64497ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
64507ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6451339f29d9SJoe Perches				"section"			=> "__section",
64520830aab0SJoe Perches				"used"				=> "__used",
64530830aab0SJoe Perches				"weak"				=> "__weak"
64547ebe1d17SDwaipayan Ray			);
64557ebe1d17SDwaipayan Ray
64567ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6457339f29d9SJoe Perches				my $orig_attr = $1;
64587ebe1d17SDwaipayan Ray				my $params = '';
64597ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6460339f29d9SJoe Perches				my $curr_attr = $orig_attr;
64617ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
64627ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6463339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
64647ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
64657ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6466339f29d9SJoe Perches						$new = "__$1\($2";
64677ebe1d17SDwaipayan Ray					} else {
6468339f29d9SJoe Perches						$new = "$new$params";
64697ebe1d17SDwaipayan Ray					}
64707ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6471339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
64727ebe1d17SDwaipayan Ray					    $fix) {
6473339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6474339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6475339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6476339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6477339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
64787ebe1d17SDwaipayan Ray					}
647939b7e287SJoe Perches				}
6480462811d9SJoe Perches			}
6481462811d9SJoe Perches
64827ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
64837ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
64847ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
64857ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6486d5e616fcSJoe Perches			}
64876061d949SJoe Perches		}
64886061d949SJoe Perches
6489619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
64905b57980dSJoe Perches		if ($perl_version_ok &&
6491619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6492619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6493619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6494619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6495619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6496619a908aSJoe Perches		}
6497619a908aSJoe Perches
6498fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6499e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6500fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6501e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6502e6176fa4SJoe Perches			my $type = $1;
6503e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6504e6176fa4SJoe Perches				$type = $1;
6505e6176fa4SJoe Perches				my $kernel_type = 'u';
6506e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6507e6176fa4SJoe Perches				$type =~ /(\d+)/;
6508e6176fa4SJoe Perches				$kernel_type .= $1;
6509e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6510e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6511e6176fa4SJoe Perches				    $fix) {
6512e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6513e6176fa4SJoe Perches				}
6514e6176fa4SJoe Perches			}
6515e6176fa4SJoe Perches		}
6516e6176fa4SJoe Perches
6517938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6518938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6519938224b5SJoe Perches			my $cast = $1;
6520938224b5SJoe Perches			my $const = $2;
6521938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
6522938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
6523938224b5SJoe Perches			    $fix) {
6524938224b5SJoe Perches				my $suffix = "";
6525938224b5SJoe Perches				my $newconst = $const;
6526938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
6527938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6528938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
6529938224b5SJoe Perches					$suffix .= 'LL';
6530938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
6531938224b5SJoe Perches					$suffix .= 'L';
6532938224b5SJoe Perches				}
6533938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6534938224b5SJoe Perches			}
6535938224b5SJoe Perches		}
6536938224b5SJoe Perches
65378f53a9b8SJoe Perches# check for sizeof(&)
65388f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6539000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6540000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
65418f53a9b8SJoe Perches		}
65428f53a9b8SJoe Perches
654366c80b60SJoe Perches# check for sizeof without parenthesis
654466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6545d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6546d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6547d5e616fcSJoe Perches			    $fix) {
6548194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6549d5e616fcSJoe Perches			}
655066c80b60SJoe Perches		}
655166c80b60SJoe Perches
655288982feaSJoe Perches# check for struct spinlock declarations
655388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
655488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
655588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
655688982feaSJoe Perches		}
655788982feaSJoe Perches
6558a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
655906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6560a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6561caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6562caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6563d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6564d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6565d5e616fcSJoe Perches				    $fix) {
6566194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6567d5e616fcSJoe Perches				}
6568a6962d72SJoe Perches			}
6569a6962d72SJoe Perches		}
6570a6962d72SJoe Perches
65710b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
65725b57980dSJoe Perches		if ($perl_version_ok &&
65730b523769SJoe Perches		    defined $stat &&
65740b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
65750b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6576e3c6bc95STobin C. Harding			my $stat_real;
6577e3c6bc95STobin C. Harding
65780b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
65790b523769SJoe Perches			$lc = $lc + $linenr;
65800b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6581ffe07513SJoe Perches				my $specifier;
6582ffe07513SJoe Perches				my $extension;
65833bd32d6aSSakari Ailus				my $qualifier;
6584ffe07513SJoe Perches				my $bad_specifier = "";
65850b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
65860b523769SJoe Perches				$fmt =~ s/%%//g;
6587e3c6bc95STobin C. Harding
65883bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6589e3c6bc95STobin C. Harding					$specifier = $1;
6590e3c6bc95STobin C. Harding					$extension = $2;
65913bd32d6aSSakari Ailus					$qualifier = $3;
6592361b0d28SLinus Torvalds					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
65933bd32d6aSSakari Ailus					    ($extension eq "f" &&
65943bd32d6aSSakari Ailus					     defined $qualifier && $qualifier !~ /^w/)) {
6595e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
65960b523769SJoe Perches						last;
65970b523769SJoe Perches					}
6598e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6599e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6600e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
66010b523769SJoe Perches						}
6602e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6603e3c6bc95STobin 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");
6604e3c6bc95STobin C. Harding					}
6605e3c6bc95STobin C. Harding				}
6606e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
66072a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
66081df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
66091df7338aSSergey Senozhatsky					my $use = "";
6610e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
66111df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6612e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
66131df7338aSSergey Senozhatsky					}
66142a9f9d85STobin C. Harding
66150b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6616e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6617e3c6bc95STobin C. Harding				}
66180b523769SJoe Perches			}
66190b523769SJoe Perches		}
66200b523769SJoe Perches
6621554e165cSAndy Whitcroft# Check for misused memsets
66225b57980dSJoe Perches		if ($perl_version_ok &&
6623d1fe9c09SJoe Perches		    defined $stat &&
66249e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6625554e165cSAndy Whitcroft
6626d7c76ba7SJoe Perches			my $ms_addr = $2;
6627d1fe9c09SJoe Perches			my $ms_val = $7;
6628d1fe9c09SJoe Perches			my $ms_size = $12;
6629d7c76ba7SJoe Perches
6630554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6631554e165cSAndy Whitcroft				ERROR("MEMSET",
6632d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6633554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6634554e165cSAndy Whitcroft				WARN("MEMSET",
6635d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6636d7c76ba7SJoe Perches			}
6637d7c76ba7SJoe Perches		}
6638d7c76ba7SJoe Perches
663998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
66405b57980dSJoe Perches#		if ($perl_version_ok &&
6641f333195dSJoe Perches#		    defined $stat &&
6642f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6643f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6644f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6645f333195dSJoe Perches#			    $fix) {
6646f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6647f333195dSJoe Perches#			}
6648f333195dSJoe Perches#		}
664998a9bba5SJoe Perches
6650b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
66515b57980dSJoe Perches#		if ($perl_version_ok &&
6652f333195dSJoe Perches#		    defined $stat &&
6653f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6654f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6655f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6656f333195dSJoe Perches#		}
6657b6117d17SMateusz Kulikowski
66588617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
66598617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
66605b57980dSJoe Perches#		if ($perl_version_ok &&
6661f333195dSJoe Perches#		    defined $stat &&
6662f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6663f333195dSJoe Perches#
6664f333195dSJoe Perches#			my $ms_val = $7;
6665f333195dSJoe Perches#
6666f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6667f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6668f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6669f333195dSJoe Perches#				    $fix) {
6670f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6671f333195dSJoe Perches#				}
6672f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6673f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6674f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6675f333195dSJoe Perches#				    $fix) {
6676f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6677f333195dSJoe Perches#				}
6678f333195dSJoe Perches#			}
6679f333195dSJoe Perches#		}
66808617cd09SMateusz Kulikowski
66815dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
66825dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
66835dbdb2d8SJoe Perches			WARN("STRLCPY",
66845dbdb2d8SJoe Perches			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
66855dbdb2d8SJoe Perches		}
66865dbdb2d8SJoe Perches
6687d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
66885b57980dSJoe Perches		if ($perl_version_ok &&
6689d1fe9c09SJoe Perches		    defined $stat &&
6690d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6691d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6692d7c76ba7SJoe Perches				my $call = $1;
6693d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6694d7c76ba7SJoe Perches				my $arg1 = $3;
6695d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6696d1fe9c09SJoe Perches				my $arg2 = $8;
6697d7c76ba7SJoe Perches				my $cast;
6698d7c76ba7SJoe Perches
6699d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6700d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6701d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6702d7c76ba7SJoe Perches					$cast = $cast1;
6703d7c76ba7SJoe Perches				} else {
6704d7c76ba7SJoe Perches					$cast = $cast2;
6705d7c76ba7SJoe Perches				}
6706d7c76ba7SJoe Perches				WARN("MINMAX",
6707d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6708554e165cSAndy Whitcroft			}
6709554e165cSAndy Whitcroft		}
6710554e165cSAndy Whitcroft
67114a273195SJoe Perches# check usleep_range arguments
67125b57980dSJoe Perches		if ($perl_version_ok &&
67134a273195SJoe Perches		    defined $stat &&
67144a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
67154a273195SJoe Perches			my $min = $1;
67164a273195SJoe Perches			my $max = $7;
67174a273195SJoe Perches			if ($min eq $max) {
67184a273195SJoe Perches				WARN("USLEEP_RANGE",
6719458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
67204a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
67214a273195SJoe Perches				 $min > $max) {
67224a273195SJoe Perches				WARN("USLEEP_RANGE",
6723458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
67244a273195SJoe Perches			}
67254a273195SJoe Perches		}
67264a273195SJoe Perches
6727823b794cSJoe Perches# check for naked sscanf
67285b57980dSJoe Perches		if ($perl_version_ok &&
6729823b794cSJoe Perches		    defined $stat &&
67306c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6731823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6732823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6733823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6734823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6735823b794cSJoe Perches			$lc = $lc + $linenr;
67362a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6737823b794cSJoe Perches			WARN("NAKED_SSCANF",
6738823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6739823b794cSJoe Perches		}
6740823b794cSJoe Perches
6741afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
67425b57980dSJoe Perches		if ($perl_version_ok &&
6743afc819abSJoe Perches		    defined $stat &&
6744afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6745afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6746afc819abSJoe Perches			$lc = $lc + $linenr;
67472a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6748afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6749afc819abSJoe Perches				my $format = $6;
6750afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6751afc819abSJoe Perches				if ($count == 1 &&
6752afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6753afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6754afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6755afc819abSJoe Perches				}
6756afc819abSJoe Perches			}
6757afc819abSJoe Perches		}
6758afc819abSJoe Perches
675970dc8a48SJoe Perches# check for new externs in .h files.
676070dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
676170dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6762d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
676370dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
676470dc8a48SJoe Perches			    $fix) {
6765194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
676670dc8a48SJoe Perches			}
676770dc8a48SJoe Perches		}
676870dc8a48SJoe Perches
6769de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6770171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6771c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6772171ae1a4SAndy Whitcroft		{
6773c45dcabdSAndy Whitcroft			my $function_name = $1;
6774c45dcabdSAndy Whitcroft			my $paren_space = $2;
6775171ae1a4SAndy Whitcroft
6776171ae1a4SAndy Whitcroft			my $s = $stat;
6777171ae1a4SAndy Whitcroft			if (defined $cond) {
6778171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6779171ae1a4SAndy Whitcroft			}
6780d8b44b58SKees Cook			if ($s =~ /^\s*;/)
6781c45dcabdSAndy Whitcroft			{
6782000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6783000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6784de7d4f0eSAndy Whitcroft			}
6785de7d4f0eSAndy Whitcroft
6786171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6787000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6788000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6789171ae1a4SAndy Whitcroft			}
67909c9ba34eSAndy Whitcroft
67919c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
67929c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
67939c9ba34eSAndy Whitcroft		{
6794000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6795000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6796171ae1a4SAndy Whitcroft		}
6797171ae1a4SAndy Whitcroft
6798a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
6799a0ad7596SJoe Perches		if (defined $stat &&
6800d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6801d8b44b58SKees Cook		    $1 ne "void") {
6802d8b44b58SKees Cook			my $args = trim($1);
6803ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6804ca0d8929SJoe Perches				my $arg = trim($1);
6805d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6806ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6807ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6808ca0d8929SJoe Perches				}
6809ca0d8929SJoe Perches			}
6810ca0d8929SJoe Perches		}
6811ca0d8929SJoe Perches
6812a0ad7596SJoe Perches# check for function definitions
68135b57980dSJoe Perches		if ($perl_version_ok &&
6814a0ad7596SJoe Perches		    defined $stat &&
6815a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6816a0ad7596SJoe Perches			$context_function = $1;
6817a0ad7596SJoe Perches
6818a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6819a0ad7596SJoe Perches			my $ok = 0;
6820a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6821a0ad7596SJoe Perches			my $herectx = $here . "\n";
6822a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6823a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6824a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6825a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6826a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6827a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6828a0ad7596SJoe Perches			}
6829a0ad7596SJoe Perches			if (!$ok) {
6830a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6831a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6832a0ad7596SJoe Perches			}
6833a0ad7596SJoe Perches		}
6834a0ad7596SJoe Perches
6835de7d4f0eSAndy Whitcroft# checks for new __setup's
6836de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6837de7d4f0eSAndy Whitcroft			my $name = $1;
6838de7d4f0eSAndy Whitcroft
6839de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6840000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
68412581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
6842de7d4f0eSAndy Whitcroft			}
6843653d4876SAndy Whitcroft		}
68449c0ca6f9SAndy Whitcroft
6845e29a70f1SJoe Perches# check for pointless casting of alloc functions
6846e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6847000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6848000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
68499c0ca6f9SAndy Whitcroft		}
685013214adfSAndy Whitcroft
6851a640d25cSJoe Perches# alloc style
6852a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
68535b57980dSJoe Perches		if ($perl_version_ok &&
6854e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6855a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6856a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6857a640d25cSJoe Perches		}
6858a640d25cSJoe Perches
685960a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
68605b57980dSJoe Perches		if ($perl_version_ok &&
68611b4a2ed4SJoe Perches		    defined $stat &&
68621b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
686360a55369SJoe Perches			my $oldfunc = $3;
686460a55369SJoe Perches			my $a1 = $4;
686560a55369SJoe Perches			my $a2 = $10;
686660a55369SJoe Perches			my $newfunc = "kmalloc_array";
686760a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
686860a55369SJoe Perches			my $r1 = $a1;
686960a55369SJoe Perches			my $r2 = $a2;
687060a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
687160a55369SJoe Perches				$r1 = $a2;
687260a55369SJoe Perches				$r2 = $a1;
687360a55369SJoe Perches			}
6874e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6875e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
68761b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6877e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6878e3d95a2aSTobin C. Harding
6879e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
68801b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
68811b4a2ed4SJoe Perches				    $cnt == 1 &&
6882e367455aSJoe Perches				    $fix) {
6883194f66fcSJoe 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;
688460a55369SJoe Perches				}
688560a55369SJoe Perches			}
688660a55369SJoe Perches		}
688760a55369SJoe Perches
6888972fdea2SJoe Perches# check for krealloc arg reuse
68895b57980dSJoe Perches		if ($perl_version_ok &&
68904cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
68914cab63ceSJoe Perches		    $1 eq $3) {
6892972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
6893972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6894972fdea2SJoe Perches		}
6895972fdea2SJoe Perches
68965ce59ae0SJoe Perches# check for alloc argument mismatch
68975ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
68985ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
68995ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
69005ce59ae0SJoe Perches		}
69015ce59ae0SJoe Perches
6902caf2a54fSJoe Perches# check for multiple semicolons
6903caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6904d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6905d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6906d5e616fcSJoe Perches			    $fix) {
6907194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6908d5e616fcSJoe Perches			}
6909d1e2ad07SJoe Perches		}
6910d1e2ad07SJoe Perches
6911cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6912cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6913cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
69140ab90191SJoe Perches			my $ull = "";
69150ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
69160ab90191SJoe Perches			if (CHK("BIT_MACRO",
69170ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
69180ab90191SJoe Perches			    $fix) {
69190ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
69200ab90191SJoe Perches			}
69210ab90191SJoe Perches		}
69220ab90191SJoe Perches
692350161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
69243e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
692550161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
69263e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
692750161266SJoe Perches		}
692850161266SJoe Perches
69292d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
69303e89ad85SJerome Forissier		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
69312d632745SJoe Perches			my $config = $1;
69322d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
69333e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
69342d632745SJoe Perches			    $fix) {
69352d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
69362d632745SJoe Perches			}
69372d632745SJoe Perches		}
69382d632745SJoe Perches
6939f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
6940f36d3eb8SJoe Perches		my @fallthroughs = (
6941f36d3eb8SJoe Perches			'fallthrough',
6942f36d3eb8SJoe Perches			'@fallthrough@',
6943f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
6944f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6945f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6946f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6947f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6948f36d3eb8SJoe Perches		    );
6949f36d3eb8SJoe Perches		if ($raw_comment ne '') {
6950f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
6951f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
6952f36d3eb8SJoe Perches					my $msg_level = \&WARN;
6953f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
6954f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
6955f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6956f36d3eb8SJoe Perches					last;
6957f36d3eb8SJoe Perches				}
6958f36d3eb8SJoe Perches			}
6959f36d3eb8SJoe Perches		}
6960f36d3eb8SJoe Perches
6961d1e2ad07SJoe Perches# check for switch/default statements without a break;
69625b57980dSJoe Perches		if ($perl_version_ok &&
6963d1e2ad07SJoe Perches		    defined $stat &&
6964d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6965d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6966e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
6967e3d95a2aSTobin C. Harding
6968d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6969d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6970caf2a54fSJoe Perches		}
6971caf2a54fSJoe Perches
697213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6973d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6974d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6975d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6976d5e616fcSJoe Perches			    $fix) {
6977194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6978d5e616fcSJoe Perches			}
697913214adfSAndy Whitcroft		}
6980773647a0SAndy Whitcroft
698162ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
698262ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
698362ec818fSJoe Perches			ERROR("DATE_TIME",
698462ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
698562ec818fSJoe Perches		}
698662ec818fSJoe Perches
69872c92488aSJoe Perches# check for use of yield()
69882c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
69892c92488aSJoe Perches			WARN("YIELD",
69902c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
69912c92488aSJoe Perches		}
69922c92488aSJoe Perches
6993179f8f40SJoe Perches# check for comparisons against true and false
6994179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6995179f8f40SJoe Perches			my $lead = $1;
6996179f8f40SJoe Perches			my $arg = $2;
6997179f8f40SJoe Perches			my $test = $3;
6998179f8f40SJoe Perches			my $otype = $4;
6999179f8f40SJoe Perches			my $trail = $5;
7000179f8f40SJoe Perches			my $op = "!";
7001179f8f40SJoe Perches
7002179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7003179f8f40SJoe Perches
7004179f8f40SJoe Perches			my $type = lc($otype);
7005179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7006179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7007179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7008179f8f40SJoe Perches					$op = "";
7009179f8f40SJoe Perches				}
7010179f8f40SJoe Perches
7011179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7012179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7013179f8f40SJoe Perches
7014179f8f40SJoe Perches## maybe suggesting a correct construct would better
7015179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7016179f8f40SJoe Perches
7017179f8f40SJoe Perches			}
7018179f8f40SJoe Perches		}
7019179f8f40SJoe Perches
70204882720bSThomas Gleixner# check for semaphores initialized locked
70214882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7022000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7023000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7024773647a0SAndy Whitcroft		}
70256712d858SJoe Perches
702667d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
702767d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7028000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
702967d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7030773647a0SAndy Whitcroft		}
70316712d858SJoe Perches
7032ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7033f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7034000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7035ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7036f3db6639SMichael Ellerman		}
70376712d858SJoe Perches
70383d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
70393d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
70403d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
70413d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
70423d709ab5SPaul E. McKenney		}
70433d709ab5SPaul E. McKenney
70449189c7e7SJoe Perches# check for deprecated apis
70459189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
70469189c7e7SJoe Perches			my $deprecated_api = $1;
70479189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
70489189c7e7SJoe Perches			WARN("DEPRECATED_API",
70499189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
70509189c7e7SJoe Perches		}
70519189c7e7SJoe Perches
70520f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7053d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7054ced69da1SQuentin Monnet		if (defined($const_structs) &&
7055ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7056d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7057000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7058d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
70592b6db5cbSAndy Whitcroft		}
7060773647a0SAndy Whitcroft
7061773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7062773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
706335cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7064773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7065c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7066c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7067171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7068171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
706935cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
707035cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7071773647a0SAndy Whitcroft		{
7072000d1cc1SJoe Perches			WARN("NR_CPUS",
7073000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7074773647a0SAndy Whitcroft		}
70759c9ba34eSAndy Whitcroft
707652ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
707752ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
707852ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
707952ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
708052ea8506SJoe Perches		}
708152ea8506SJoe Perches
7082acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
70835b57980dSJoe Perches		if ($perl_version_ok &&
7084acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7085acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7086acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7087acd9362cSJoe Perches		}
7088acd9362cSJoe Perches
7089de3f186fSDenis Efremov# nested likely/unlikely calls
7090de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7091de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7092de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7093de3f186fSDenis Efremov		}
7094de3f186fSDenis Efremov
7095691d77b6SAndy Whitcroft# whine mightly about in_atomic
7096691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7097691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7098000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7099000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7100f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7101000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7102000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7103691d77b6SAndy Whitcroft			}
7104691d77b6SAndy Whitcroft		}
71051704f47bSPeter Zijlstra
71061704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
71071704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
71081704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
71091704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
71101704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
71111704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7112000d1cc1SJoe Perches				ERROR("LOCKDEP",
7113000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
71141704f47bSPeter Zijlstra			}
71151704f47bSPeter Zijlstra		}
711688f8831cSDave Jones
7117b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7118b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7119000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7120000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
712188f8831cSDave Jones		}
71222435880fSJoe Perches
712300180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
712400180468SJoe Perches# and whether or not function naming is typical and if
712500180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
71265b57980dSJoe Perches		if ($perl_version_ok &&
712700180468SJoe Perches		    defined $stat &&
712800180468SJoe 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*\)/) {
712900180468SJoe Perches			my $var = $1;
713000180468SJoe Perches			my $perms = $2;
713100180468SJoe Perches			my $show = $3;
713200180468SJoe Perches			my $store = $4;
713300180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
713400180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
713500180468SJoe Perches			    $store =~ /^${var}_store$/ &&
713600180468SJoe Perches			    $octal_perms eq "0644") {
713700180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
713800180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
713900180468SJoe Perches				    $fix) {
714000180468SJoe 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})/;
714100180468SJoe Perches				}
714200180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
714300180468SJoe Perches				 $store =~ /^NULL$/ &&
714400180468SJoe Perches				 $octal_perms eq "0444") {
714500180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
714600180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
714700180468SJoe Perches				    $fix) {
714800180468SJoe 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})/;
714900180468SJoe Perches				}
715000180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
715100180468SJoe Perches				 $store =~ /^${var}_store$/ &&
715200180468SJoe Perches				 $octal_perms eq "0200") {
715300180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
715400180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
715500180468SJoe Perches				    $fix) {
715600180468SJoe 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})/;
715700180468SJoe Perches				}
715800180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
715900180468SJoe Perches				 $octal_perms eq "0444" ||
716000180468SJoe Perches				 $octal_perms eq "0200") {
716100180468SJoe Perches				my $newshow = "$show";
716200180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
716300180468SJoe Perches				my $newstore = $store;
716400180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
716500180468SJoe Perches				my $rename = "";
716600180468SJoe Perches				if ($show ne $newshow) {
716700180468SJoe Perches					$rename .= " '$show' to '$newshow'";
716800180468SJoe Perches				}
716900180468SJoe Perches				if ($store ne $newstore) {
717000180468SJoe Perches					$rename .= " '$store' to '$newstore'";
717100180468SJoe Perches				}
717200180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
717300180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
717400180468SJoe Perches			} else {
717500180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
717600180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
717700180468SJoe Perches			}
717800180468SJoe Perches		}
717900180468SJoe Perches
7180515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7181515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
718273121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
718373121534SJoe Perches#   specific definition of not visible in sysfs.
718473121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
718573121534SJoe Perches#   use the default permissions
71865b57980dSJoe Perches		if ($perl_version_ok &&
7187459cf0aeSJoe Perches		    defined $stat &&
7188515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
71892435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
71902435880fSJoe Perches				my $func = $entry->[0];
71912435880fSJoe Perches				my $arg_pos = $entry->[1];
71922435880fSJoe Perches
7193459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7194459cf0aeSJoe Perches				$lc = $lc + $linenr;
71952a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7196459cf0aeSJoe Perches
71972435880fSJoe Perches				my $skip_args = "";
71982435880fSJoe Perches				if ($arg_pos > 1) {
71992435880fSJoe Perches					$arg_pos--;
72002435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
72012435880fSJoe Perches				}
7202f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7203459cf0aeSJoe Perches				if ($stat =~ /$test/) {
72042435880fSJoe Perches					my $val = $1;
72052435880fSJoe Perches					$val = $6 if ($skip_args ne "");
720673121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
720773121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
720873121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
72092435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7210459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7211f90774e1SJoe Perches					}
7212f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7213c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7214459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
72152435880fSJoe Perches					}
7216459cf0aeSJoe Perches				}
7217459cf0aeSJoe Perches			}
7218459cf0aeSJoe Perches		}
7219459cf0aeSJoe Perches
7220459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7221bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
722200180468SJoe Perches			my $oval = $1;
722300180468SJoe Perches			my $octal = perms_to_octal($oval);
7224f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7225459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7226f90774e1SJoe Perches			    $fix) {
722700180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
72282435880fSJoe Perches			}
722913214adfSAndy Whitcroft		}
72305a6d20ceSBjorn Andersson
72315a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
72325a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
72335a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
72345a6d20ceSBjorn Andersson			my $valid_licenses = qr{
72355a6d20ceSBjorn Andersson						GPL|
72365a6d20ceSBjorn Andersson						GPL\ v2|
72375a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
72385a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
72395a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
72405a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
72415a6d20ceSBjorn Andersson						Proprietary
72425a6d20ceSBjorn Andersson					}x;
72435a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
72445a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
72455a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
72465a6d20ceSBjorn Andersson			}
72475a6d20ceSBjorn Andersson		}
72486a8d76cbSMatteo Croce
72496a8d76cbSMatteo Croce# check for sysctl duplicate constants
72506a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
72516a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
72526a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
72536a8d76cbSMatteo Croce		}
7254515a235eSJoe Perches	}
725513214adfSAndy Whitcroft
725613214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
725713214adfSAndy Whitcroft	# so just keep quiet.
725813214adfSAndy Whitcroft	if ($#rawlines == -1) {
725913214adfSAndy Whitcroft		exit(0);
72600a920b5bSAndy Whitcroft	}
72610a920b5bSAndy Whitcroft
72628905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
72638905a67cSAndy Whitcroft	# things that appear to be patches.
72648905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
72658905a67cSAndy Whitcroft		exit(0);
72668905a67cSAndy Whitcroft	}
72678905a67cSAndy Whitcroft
7268e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
72698905a67cSAndy Whitcroft	# just keep quiet.
72708905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
72718905a67cSAndy Whitcroft		exit(0);
72728905a67cSAndy Whitcroft	}
72738905a67cSAndy Whitcroft
7274a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7275000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7276000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
72770a920b5bSAndy Whitcroft	}
7278cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7279cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7280000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7281000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
728248ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
728348ca2d8aSDwaipayan Ray			# authorsignoff values:
728448ca2d8aSDwaipayan Ray			# 0 -> missing sign off
728548ca2d8aSDwaipayan Ray			# 1 -> sign off identical
728648ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
728748ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
728848ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
728948ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
729048ca2d8aSDwaipayan Ray
729148ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
729248ca2d8aSDwaipayan Ray
729348ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
729448ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7295cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
729648ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
729748ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
729848ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
729948ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
730048ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
730148ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
730248ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
730348ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
730448ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
730548ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
730648ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
730748ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
730848ca2d8aSDwaipayan Ray			}
7309cd261496SGeert Uytterhoeven		}
73100a920b5bSAndy Whitcroft	}
73110a920b5bSAndy Whitcroft
7312f0a594c1SAndy Whitcroft	print report_dump();
731313214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
731413214adfSAndy Whitcroft		print "$filename " if ($summary_file);
73156c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
73166c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
73176c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
73186c72ffaaSAndy Whitcroft	}
73198905a67cSAndy Whitcroft
7320d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7321ef212196SJoe Perches		# If there were any defects found and not already fixing them
7322ef212196SJoe Perches		if (!$clean and !$fix) {
7323ef212196SJoe Perches			print << "EOM"
7324ef212196SJoe Perches
7325ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7326ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7327ef212196SJoe PerchesEOM
7328ef212196SJoe Perches		}
7329d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7330d2c0a235SAndy Whitcroft		# then suggest that.
7331d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7332b0781216SMike Frysinger			$rpt_cleaners = 0;
7333d8469f16SJoe Perches			print << "EOM"
7334d8469f16SJoe Perches
7335d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7336d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7337d8469f16SJoe PerchesEOM
7338d2c0a235SAndy Whitcroft		}
7339d2c0a235SAndy Whitcroft	}
7340d2c0a235SAndy Whitcroft
7341d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7342d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7343d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
73449624b8d6SJoe Perches		my $newfile = $filename;
73459624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
73463705ce5bSJoe Perches		my $linecount = 0;
73473705ce5bSJoe Perches		my $f;
73483705ce5bSJoe Perches
7349d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7350d752fcc8SJoe Perches
73513705ce5bSJoe Perches		open($f, '>', $newfile)
73523705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
73533705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
73543705ce5bSJoe Perches			$linecount++;
73553705ce5bSJoe Perches			if ($file) {
73563705ce5bSJoe Perches				if ($linecount > 3) {
73573705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
73583705ce5bSJoe Perches					print $f $fixed_line . "\n";
73593705ce5bSJoe Perches				}
73603705ce5bSJoe Perches			} else {
73613705ce5bSJoe Perches				print $f $fixed_line . "\n";
73623705ce5bSJoe Perches			}
73633705ce5bSJoe Perches		}
73643705ce5bSJoe Perches		close($f);
73653705ce5bSJoe Perches
73663705ce5bSJoe Perches		if (!$quiet) {
73673705ce5bSJoe Perches			print << "EOM";
7368d8469f16SJoe Perches
73693705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
73703705ce5bSJoe Perches
73713705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
73723705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
73733705ce5bSJoe Perches
73743705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
73753705ce5bSJoe PerchesNo warranties, expressed or implied...
73763705ce5bSJoe PerchesEOM
73773705ce5bSJoe Perches		}
73783705ce5bSJoe Perches	}
73793705ce5bSJoe Perches
7380d8469f16SJoe Perches	if ($quiet == 0) {
7381d8469f16SJoe Perches		print "\n";
7382d8469f16SJoe Perches		if ($clean == 1) {
7383d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7384d8469f16SJoe Perches		} else {
7385d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
73860a920b5bSAndy Whitcroft		}
73870a920b5bSAndy Whitcroft	}
73880a920b5bSAndy Whitcroft	return $clean;
73890a920b5bSAndy Whitcroft}
7390