xref: /linux-6.15/scripts/checkpatch.pl (revision 56ddc4cd)
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_)?
49058f02267SJoe Perches		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
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
510adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
511adb2da82SJoe Perches	[=-]*> |
512adb2da82SJoe Perches	<[=-]* |
513adb2da82SJoe Perches	\[ |
514adb2da82SJoe Perches	\] |
515adb2da82SJoe Perches	start |
516adb2da82SJoe Perches	called |
517adb2da82SJoe Perches	entered |
518adb2da82SJoe Perches	entry |
519adb2da82SJoe Perches	enter |
520adb2da82SJoe Perches	in |
521adb2da82SJoe Perches	inside |
522adb2da82SJoe Perches	here |
523adb2da82SJoe Perches	begin |
524adb2da82SJoe Perches	exit |
525adb2da82SJoe Perches	end |
526adb2da82SJoe Perches	done |
527adb2da82SJoe Perches	leave |
528adb2da82SJoe Perches	completed |
529adb2da82SJoe Perches	out |
530adb2da82SJoe Perches	return |
531adb2da82SJoe Perches	[\.\!:\s]*
532adb2da82SJoe Perches)};
533adb2da82SJoe 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
24565b8f82e1SSong Liusub exclude_global_initialisers {
24575b8f82e1SSong Liu	my ($realfile) = @_;
24585b8f82e1SSong Liu
24595b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
24605b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
24615b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
24625b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
24635b8f82e1SSong Liu}
24645b8f82e1SSong Liu
24650a920b5bSAndy Whitcroftsub process {
24660a920b5bSAndy Whitcroft	my $filename = shift;
24670a920b5bSAndy Whitcroft
24680a920b5bSAndy Whitcroft	my $linenr=0;
24690a920b5bSAndy Whitcroft	my $prevline="";
2470c2fdda0dSAndy Whitcroft	my $prevrawline="";
24710a920b5bSAndy Whitcroft	my $stashline="";
2472c2fdda0dSAndy Whitcroft	my $stashrawline="";
24730a920b5bSAndy Whitcroft
24744a0df2efSAndy Whitcroft	my $length;
24750a920b5bSAndy Whitcroft	my $indent;
24760a920b5bSAndy Whitcroft	my $previndent=0;
24770a920b5bSAndy Whitcroft	my $stashindent=0;
24780a920b5bSAndy Whitcroft
2479de7d4f0eSAndy Whitcroft	our $clean = 1;
24800a920b5bSAndy Whitcroft	my $signoff = 0;
2481cd261496SGeert Uytterhoeven	my $author = '';
2482cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
248348ca2d8aSDwaipayan Ray	my $author_sob = '';
24840a920b5bSAndy Whitcroft	my $is_patch = 0;
2485133712a2SRob Herring	my $is_binding_patch = -1;
248629ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
248715662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
248844d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2489ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2490490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2491bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
24922a076f40SJoe Perches	my $commit_log_long_line = 0;
2493e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
249413f1937eSJoe Perches	my $reported_maintainer_file = 0;
2495fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2496fa64205dSPasi Savanainen
2497365dd4eaSJoe Perches	my $last_blank_line = 0;
24985e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2499365dd4eaSJoe Perches
250013214adfSAndy Whitcroft	our @report = ();
25016c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
25026c72ffaaSAndy Whitcroft	our $cnt_error = 0;
25036c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
25046c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
25056c72ffaaSAndy Whitcroft
25060a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
25070a920b5bSAndy Whitcroft	my $realfile = '';
25080a920b5bSAndy Whitcroft	my $realline = 0;
25090a920b5bSAndy Whitcroft	my $realcnt = 0;
25100a920b5bSAndy Whitcroft	my $here = '';
251177cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
25120a920b5bSAndy Whitcroft	my $in_comment = 0;
2513c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
25140a920b5bSAndy Whitcroft	my $first_line = 0;
25151e855726SWolfram Sang	my $p1_prefix = '';
25160a920b5bSAndy Whitcroft
251713214adfSAndy Whitcroft	my $prev_values = 'E';
251813214adfSAndy Whitcroft
251913214adfSAndy Whitcroft	# suppression flags
2520773647a0SAndy Whitcroft	my %suppress_ifbraces;
2521170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
25222b474a1aSAndy Whitcroft	my %suppress_export;
25233e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2524653d4876SAndy Whitcroft
25257e51f197SJoe Perches	my %signatures = ();
2526323c1260SJoe Perches
2527c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2528de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2529c2fdda0dSAndy Whitcroft	#
2530de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2531de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2532773647a0SAndy Whitcroft
2533d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2534d8b07710SJoe Perches
25359f3a8992SRob Herring	my $checklicenseline = 1;
25369f3a8992SRob Herring
2537773647a0SAndy Whitcroft	sanitise_line_reset();
2538c2fdda0dSAndy Whitcroft	my $line;
2539c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2540773647a0SAndy Whitcroft		$linenr++;
2541773647a0SAndy Whitcroft		$line = $rawline;
2542c2fdda0dSAndy Whitcroft
25433705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
25443705ce5bSJoe Perches
2545773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2546de7d4f0eSAndy Whitcroft			$setup_docs = 0;
25472581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2548de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2549de7d4f0eSAndy Whitcroft			}
2550773647a0SAndy Whitcroft			#next;
2551de7d4f0eSAndy Whitcroft		}
255274fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2553773647a0SAndy Whitcroft			$realline=$1-1;
2554773647a0SAndy Whitcroft			if (defined $2) {
2555773647a0SAndy Whitcroft				$realcnt=$3+1;
2556773647a0SAndy Whitcroft			} else {
2557773647a0SAndy Whitcroft				$realcnt=1+1;
2558773647a0SAndy Whitcroft			}
2559c45dcabdSAndy Whitcroft			$in_comment = 0;
2560773647a0SAndy Whitcroft
2561773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2562773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2563773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2564773647a0SAndy Whitcroft			# at context start.
2565773647a0SAndy Whitcroft			my $edge;
256601fa9147SAndy Whitcroft			my $cnt = $realcnt;
256701fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
256801fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
256901fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
257001fa9147SAndy Whitcroft				$cnt--;
257101fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2572721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2573fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2574fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2575fae17daeSAndy Whitcroft					($edge) = $1;
2576fae17daeSAndy Whitcroft					last;
2577fae17daeSAndy Whitcroft				}
2578773647a0SAndy Whitcroft			}
2579773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2580773647a0SAndy Whitcroft				$in_comment = 1;
2581773647a0SAndy Whitcroft			}
2582773647a0SAndy Whitcroft
2583773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2584773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2585773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2586773647a0SAndy Whitcroft			if (!defined $edge &&
258783242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2588773647a0SAndy Whitcroft			{
2589773647a0SAndy Whitcroft				$in_comment = 1;
2590773647a0SAndy Whitcroft			}
2591773647a0SAndy Whitcroft
2592773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2593773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2594773647a0SAndy Whitcroft
2595171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2596773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2597171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2598773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2599773647a0SAndy Whitcroft		}
2600773647a0SAndy Whitcroft		push(@lines, $line);
2601773647a0SAndy Whitcroft
2602773647a0SAndy Whitcroft		if ($realcnt > 1) {
2603773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2604773647a0SAndy Whitcroft		} else {
2605773647a0SAndy Whitcroft			$realcnt = 0;
2606773647a0SAndy Whitcroft		}
2607773647a0SAndy Whitcroft
2608773647a0SAndy Whitcroft		#print "==>$rawline\n";
2609773647a0SAndy Whitcroft		#print "-->$line\n";
2610de7d4f0eSAndy Whitcroft
2611de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2612de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2613de7d4f0eSAndy Whitcroft		}
2614de7d4f0eSAndy Whitcroft	}
2615de7d4f0eSAndy Whitcroft
26166c72ffaaSAndy Whitcroft	$prefix = '';
26176c72ffaaSAndy Whitcroft
2618773647a0SAndy Whitcroft	$realcnt = 0;
2619773647a0SAndy Whitcroft	$linenr = 0;
2620194f66fcSJoe Perches	$fixlinenr = -1;
26210a920b5bSAndy Whitcroft	foreach my $line (@lines) {
26220a920b5bSAndy Whitcroft		$linenr++;
2623194f66fcSJoe Perches		$fixlinenr++;
26241b5539b1SJoe Perches		my $sline = $line;	#copy of $line
26251b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
26260a920b5bSAndy Whitcroft
2627c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2628f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
26296c72ffaaSAndy Whitcroft
263012c253abSJoe Perches# check if it's a mode change, rename or start of a patch
263112c253abSJoe Perches		if (!$in_commit_log &&
263212c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
263312c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
263412c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
263512c253abSJoe Perches			$is_patch = 1;
263612c253abSJoe Perches		}
263712c253abSJoe Perches
26380a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2639e518e9a5SJoe Perches		if (!$in_commit_log &&
264074fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
264174fd4f34SJoe Perches			my $context = $4;
26420a920b5bSAndy Whitcroft			$is_patch = 1;
26434a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
26440a920b5bSAndy Whitcroft			$realline=$1-1;
26450a920b5bSAndy Whitcroft			if (defined $2) {
26460a920b5bSAndy Whitcroft				$realcnt=$3+1;
26470a920b5bSAndy Whitcroft			} else {
26480a920b5bSAndy Whitcroft				$realcnt=1+1;
26490a920b5bSAndy Whitcroft			}
2650c2fdda0dSAndy Whitcroft			annotate_reset();
265113214adfSAndy Whitcroft			$prev_values = 'E';
265213214adfSAndy Whitcroft
2653773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2654170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
26552b474a1aSAndy Whitcroft			%suppress_export = ();
26563e469cdcSAndy Whitcroft			$suppress_statement = 0;
265774fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
265874fd4f34SJoe Perches				$context_function = $1;
265974fd4f34SJoe Perches			} else {
266074fd4f34SJoe Perches				undef $context_function;
266174fd4f34SJoe Perches			}
26620a920b5bSAndy Whitcroft			next;
26630a920b5bSAndy Whitcroft
26644a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
26654a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
26664a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2667773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
26680a920b5bSAndy Whitcroft			$realline++;
2669d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
26700a920b5bSAndy Whitcroft
26714a0df2efSAndy Whitcroft			# Measure the line length and indent.
2672c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
26730a920b5bSAndy Whitcroft
26740a920b5bSAndy Whitcroft			# Track the previous line.
26750a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
26760a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2677c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2678c2fdda0dSAndy Whitcroft
2679773647a0SAndy Whitcroft			#warn "line<$line>\n";
26806c72ffaaSAndy Whitcroft
2681d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2682d8aaf121SAndy Whitcroft			$realcnt--;
26830a920b5bSAndy Whitcroft		}
26840a920b5bSAndy Whitcroft
2685cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2686cc77cdcaSAndy Whitcroft
26876c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
26886c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2689773647a0SAndy Whitcroft
26902ac73b4fSJoe Perches		my $found_file = 0;
2691773647a0SAndy Whitcroft		# extract the filename as it passes
26923bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
26933bf9a009SRabin Vincent			$realfile = $1;
26942b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2695270c49a0SJoe Perches			$in_commit_log = 0;
26962ac73b4fSJoe Perches			$found_file = 1;
26973bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2698773647a0SAndy Whitcroft			$realfile = $1;
26992b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2700270c49a0SJoe Perches			$in_commit_log = 0;
27011e855726SWolfram Sang
27021e855726SWolfram Sang			$p1_prefix = $1;
2703e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2704e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2705000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2706000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
27071e855726SWolfram Sang			}
2708773647a0SAndy Whitcroft
2709c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2710000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2711000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2712773647a0SAndy Whitcroft			}
27132ac73b4fSJoe Perches			$found_file = 1;
27142ac73b4fSJoe Perches		}
27152ac73b4fSJoe Perches
271634d8815fSJoe Perches#make up the handle for any error we report on this line
271734d8815fSJoe Perches		if ($showfile) {
271834d8815fSJoe Perches			$prefix = "$realfile:$realline: "
271934d8815fSJoe Perches		} elsif ($emacs) {
27207d3a9f67SJoe Perches			if ($file) {
27217d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
27227d3a9f67SJoe Perches			} else {
272334d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
272434d8815fSJoe Perches			}
27257d3a9f67SJoe Perches		}
272634d8815fSJoe Perches
27272ac73b4fSJoe Perches		if ($found_file) {
272885b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
272985b0ee18SJoe Perches				WARN("OBSOLETE",
273085b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
273185b0ee18SJoe Perches			}
27327bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
27332ac73b4fSJoe Perches				$check = 1;
27342ac73b4fSJoe Perches			} else {
27352ac73b4fSJoe Perches				$check = $check_orig;
27362ac73b4fSJoe Perches			}
27379f3a8992SRob Herring			$checklicenseline = 1;
2738133712a2SRob Herring
2739133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2740133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2741133712a2SRob Herring
2742133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2743133712a2SRob Herring
2744133712a2SRob Herring				if (($last_binding_patch != -1) &&
2745133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2746133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2747858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2748133712a2SRob Herring				}
2749133712a2SRob Herring			}
2750133712a2SRob Herring
2751773647a0SAndy Whitcroft			next;
2752773647a0SAndy Whitcroft		}
2753773647a0SAndy Whitcroft
2754389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
27550a920b5bSAndy Whitcroft
2756c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2757c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2758c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
27590a920b5bSAndy Whitcroft
27606c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
27616c72ffaaSAndy Whitcroft
2762490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2763490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2764490b292cSJoe Perches		if ($in_commit_log) {
2765490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2766490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2767490b292cSJoe Perches			}
2768490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2769490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2770490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2771490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2772490b292cSJoe Perches		}
2773490b292cSJoe Perches
2774e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2775e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
277613e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
277713e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2778e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2779e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2780e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2781e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2782e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2783e518e9a5SJoe Perches		}
2784e518e9a5SJoe Perches
27853bf9a009SRabin Vincent# Check for incorrect file permissions
27863bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
27873bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
278804db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
278904db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2790000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2791000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
27923bf9a009SRabin Vincent			}
27933bf9a009SRabin Vincent		}
27943bf9a009SRabin Vincent
2795cd261496SGeert Uytterhoeven# Check the patch for a From:
2796cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2797cd261496SGeert Uytterhoeven			$author = $1;
2798e7f929f3SDwaipayan Ray			my $curline = $linenr;
2799e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2800e7f929f3SDwaipayan Ray				$author .= $1;
2801e7f929f3SDwaipayan Ray			}
2802cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2803cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2804dfa05c28SJoe Perches			$author = reformat_email($author);
2805cd261496SGeert Uytterhoeven		}
2806cd261496SGeert Uytterhoeven
280720112475SJoe Perches# Check the patch for a signoff:
2808dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
28094a0df2efSAndy Whitcroft			$signoff++;
281015662b3eSJoe Perches			$in_commit_log = 0;
281148ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2812fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2813cd261496SGeert Uytterhoeven					$authorsignoff = 1;
281448ca2d8aSDwaipayan Ray				} else {
281548ca2d8aSDwaipayan Ray					my $ctx = $1;
281648ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
281748ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
281848ca2d8aSDwaipayan Ray
281948ca2d8aSDwaipayan Ray					if ($email_address eq $author_address && $email_name eq $author_name) {
282048ca2d8aSDwaipayan Ray						$author_sob = $ctx;
282148ca2d8aSDwaipayan Ray						$authorsignoff = 2;
282248ca2d8aSDwaipayan Ray					} elsif ($email_address eq $author_address) {
282348ca2d8aSDwaipayan Ray						$author_sob = $ctx;
282448ca2d8aSDwaipayan Ray						$authorsignoff = 3;
282548ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
282648ca2d8aSDwaipayan Ray						$author_sob = $ctx;
282748ca2d8aSDwaipayan Ray						$authorsignoff = 4;
282848ca2d8aSDwaipayan Ray
282948ca2d8aSDwaipayan Ray						my $address1 = $email_address;
283048ca2d8aSDwaipayan Ray						my $address2 = $author_address;
283148ca2d8aSDwaipayan Ray
283248ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
283348ca2d8aSDwaipayan Ray							$address1 = "$1$2";
283448ca2d8aSDwaipayan Ray						}
283548ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
283648ca2d8aSDwaipayan Ray							$address2 = "$1$2";
283748ca2d8aSDwaipayan Ray						}
283848ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
283948ca2d8aSDwaipayan Ray							$authorsignoff = 5;
284048ca2d8aSDwaipayan Ray						}
284148ca2d8aSDwaipayan Ray					}
2842cd261496SGeert Uytterhoeven				}
2843cd261496SGeert Uytterhoeven			}
28440a920b5bSAndy Whitcroft		}
284520112475SJoe Perches
284644d303ebSJoe Perches# Check for patch separator
284744d303ebSJoe Perches		if ($line =~ /^---$/) {
284844d303ebSJoe Perches			$has_patch_separator = 1;
284944d303ebSJoe Perches			$in_commit_log = 0;
285044d303ebSJoe Perches		}
285144d303ebSJoe Perches
2852e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2853e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2854e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2855e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2856e0d975b1SJoe Perches		}
2857e0d975b1SJoe Perches
285820112475SJoe Perches# Check signature styles
2859270c49a0SJoe Perches		if (!$in_header_lines &&
2860ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
286120112475SJoe Perches			my $space_before = $1;
286220112475SJoe Perches			my $sign_off = $2;
286320112475SJoe Perches			my $space_after = $3;
286420112475SJoe Perches			my $email = $4;
286520112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
286620112475SJoe Perches
2867ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2868831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
2869831242abSAditya Srivastava				if ($suggested_signature eq "") {
2870ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
2871ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
2872831242abSAditya Srivastava				} else {
2873831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
2874831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
2875831242abSAditya Srivastava					    $fix) {
2876831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
2877831242abSAditya Srivastava					}
2878831242abSAditya Srivastava				}
2879ce0338dfSJoe Perches			}
288020112475SJoe Perches			if (defined $space_before && $space_before ne "") {
28813705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28823705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
28833705ce5bSJoe Perches				    $fix) {
2884194f66fcSJoe Perches					$fixed[$fixlinenr] =
28853705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
28863705ce5bSJoe Perches				}
288720112475SJoe Perches			}
288820112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
28893705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28903705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
28913705ce5bSJoe Perches				    $fix) {
2892194f66fcSJoe Perches					$fixed[$fixlinenr] =
28933705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
28943705ce5bSJoe Perches				}
28953705ce5bSJoe Perches
289620112475SJoe Perches			}
289720112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
28983705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
28993705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
29003705ce5bSJoe Perches				    $fix) {
2901194f66fcSJoe Perches					$fixed[$fixlinenr] =
29023705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
29033705ce5bSJoe Perches				}
290420112475SJoe Perches			}
290520112475SJoe Perches
2906dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
290748ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
290820112475SJoe Perches			if ($suggested_email eq "") {
2909000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2910000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
291120112475SJoe Perches			} else {
291220112475SJoe Perches				my $dequoted = $suggested_email;
291320112475SJoe Perches				$dequoted =~ s/^"//;
291420112475SJoe Perches				$dequoted =~ s/" </ </;
291520112475SJoe Perches				# Don't force email to have quotes
291620112475SJoe Perches				# Allow just an angle bracketed address
2917fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
2918fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2919fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
2920fccaebf0SDwaipayan Ray					    $fix) {
2921fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
2922fccaebf0SDwaipayan Ray					}
2923fccaebf0SDwaipayan Ray				}
2924fccaebf0SDwaipayan Ray
2925fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
2926fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
2927fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
2928fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
2929fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2930fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
2931fccaebf0SDwaipayan Ray					    $fix) {
2932fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
2933fccaebf0SDwaipayan Ray					}
2934fccaebf0SDwaipayan Ray				}
2935fccaebf0SDwaipayan Ray
2936fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
2937fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
2938fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
2939000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2940fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
2941fccaebf0SDwaipayan Ray				}
2942fccaebf0SDwaipayan Ray
2943fccaebf0SDwaipayan Ray
2944fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
2945e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
2946fccaebf0SDwaipayan Ray				# begin with a #
2947fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
2948fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
2949fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
2950fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
2951fccaebf0SDwaipayan Ray						my $new_comment = $comment;
2952fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
2953fccaebf0SDwaipayan Ray
2954fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
2955fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
2956fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
2957fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
2958fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
2959fccaebf0SDwaipayan Ray
2960fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
2961fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
2962fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
2963fccaebf0SDwaipayan Ray
2964fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
2965fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
2966fccaebf0SDwaipayan Ray						    $fix) {
2967fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
2968fccaebf0SDwaipayan Ray						}
2969fccaebf0SDwaipayan Ray					}
2970fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
2971fccaebf0SDwaipayan Ray					my $new_comment = $comment;
2972fccaebf0SDwaipayan Ray
2973fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
2974fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
2975fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
2976fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
2977fccaebf0SDwaipayan Ray
2978fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
2979fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
2980fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
2981fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
2982fccaebf0SDwaipayan Ray
2983fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
2984fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
2985fccaebf0SDwaipayan Ray					    $fix) {
2986fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
2987fccaebf0SDwaipayan Ray					}
298820112475SJoe Perches				}
29890a920b5bSAndy Whitcroft			}
29907e51f197SJoe Perches
29917e51f197SJoe Perches# Check for duplicate signatures
29927e51f197SJoe Perches			my $sig_nospace = $line;
29937e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
29947e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
29957e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
29967e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
29977e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
29987e51f197SJoe Perches			} else {
29997e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
30007e51f197SJoe Perches			}
30016c5d24eeSSean Christopherson
30026c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
30036c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
30046c5d24eeSSean Christopherson				if ($email eq $author) {
30056c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30066c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
30076c5d24eeSSean Christopherson				}
30086c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
30096c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30106c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
30116c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
30126c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30136c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
30146c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
30156c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
30166c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
30176c5d24eeSSean Christopherson				}
30186c5d24eeSSean Christopherson			}
30190a920b5bSAndy Whitcroft		}
30200a920b5bSAndy Whitcroft
3021a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3022a2fe16b9SJoe Perches		if ($in_header_lines &&
3023a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3024a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3025a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3026a2fe16b9SJoe Perches		}
3027a2fe16b9SJoe Perches
302844d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
302944d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
30307580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
30317580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
30327580c5b9SAditya Srivastava			    $fix) {
30337580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
30347580c5b9SAditya Srivastava			}
30357ebd05efSChristopher Covington		}
30367ebd05efSChristopher Covington
3037369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3038369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3039369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3040369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3041369c8dd3SJoe Perches					# timestamp
3042634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3043634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3044634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3045634cffccSJoe Perches					# stack dump address styles
3046369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3047369c8dd3SJoe Perches		}
3048369c8dd3SJoe Perches
30492a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
30502a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3051bf4daf12SJoe Perches		    length($line) > 75 &&
3052bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3053bf4daf12SJoe Perches					# file delta changes
3054bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
3055bf4daf12SJoe Perches					# filename then :
305627b379afSAditya Srivastava		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
305727b379afSAditya Srivastava					# A Fixes: or Link: line or signature tag line
3058bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
30592a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
30602a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
30612a076f40SJoe Perches			$commit_log_long_line = 1;
30622a076f40SJoe Perches		}
30632a076f40SJoe Perches
3064bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3065bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3066bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3067bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3068bf4daf12SJoe Perches		}
3069bf4daf12SJoe Perches
3070084a617aSDwaipayan Ray# Check for lines starting with a #
3071084a617aSDwaipayan Ray		if ($in_commit_log && $line =~ /^#/) {
3072084a617aSDwaipayan Ray			if (WARN("COMMIT_COMMENT_SYMBOL",
3073084a617aSDwaipayan Ray				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3074084a617aSDwaipayan Ray			    $fix) {
3075084a617aSDwaipayan Ray				$fixed[$fixlinenr] =~ s/^/ /;
3076084a617aSDwaipayan Ray			}
3077084a617aSDwaipayan Ray		}
3078084a617aSDwaipayan Ray
30790d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
3080369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3081a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3082e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
3083fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
3084aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3085369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3086bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3087fe043ea1SJoe Perches			my $init_char = "c";
3088fe043ea1SJoe Perches			my $orig_commit = "";
30890d7835fcSJoe Perches			my $short = 1;
30900d7835fcSJoe Perches			my $long = 0;
30910d7835fcSJoe Perches			my $case = 1;
30920d7835fcSJoe Perches			my $space = 1;
30930d7835fcSJoe Perches			my $hasdesc = 0;
309419c146a6SJoe Perches			my $hasparens = 0;
30950d7835fcSJoe Perches			my $id = '0123456789ab';
30960d7835fcSJoe Perches			my $orig_desc = "commit description";
30970d7835fcSJoe Perches			my $description = "";
30980d7835fcSJoe Perches
3099fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
3100fe043ea1SJoe Perches				$init_char = $1;
3101fe043ea1SJoe Perches				$orig_commit = lc($2);
3102fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
3103fe043ea1SJoe Perches				$orig_commit = lc($1);
3104fe043ea1SJoe Perches			}
3105fe043ea1SJoe Perches
31060d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
31070d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
31080d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
31090d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
31100d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
31110d7835fcSJoe Perches				$orig_desc = $1;
311219c146a6SJoe Perches				$hasparens = 1;
31130d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
31140d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
31150d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
31160d7835fcSJoe Perches				$orig_desc = $1;
311719c146a6SJoe Perches				$hasparens = 1;
3118b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
3119b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
3120b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
3121b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
3122b671fde0SJoe Perches				$orig_desc = $1;
3123b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
3124b671fde0SJoe Perches				$orig_desc .= " " . $1;
312519c146a6SJoe Perches				$hasparens = 1;
31260d7835fcSJoe Perches			}
31270d7835fcSJoe Perches
31280d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
31290d7835fcSJoe Perches							      $id, $orig_desc);
31300d7835fcSJoe Perches
3131948b133aSHeinrich Schuchardt			if (defined($id) &&
3132948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
3133d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
31340d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
31350d7835fcSJoe Perches			}
3136d311cd44SJoe Perches		}
3137d311cd44SJoe Perches
313813f1937eSJoe Perches# Check for added, moved or deleted files
313913f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
314013f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
314113f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
314213f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
314313f1937eSJoe Perches		      (defined($1) || defined($2))))) {
3144a82603a8SAndrew Jeffery			$is_patch = 1;
314513f1937eSJoe Perches			$reported_maintainer_file = 1;
314613f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
314713f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
314813f1937eSJoe Perches		}
314913f1937eSJoe Perches
3150e400edb1SRob Herring# Check for adding new DT bindings not in schema format
3151e400edb1SRob Herring		if (!$in_commit_log &&
3152e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3153e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3154e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
3155*56ddc4cdSMauro Carvalho Chehab			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3156e400edb1SRob Herring		}
3157e400edb1SRob Herring
315800df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
31598905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3160000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
3161000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
31626c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
3163de7d4f0eSAndy Whitcroft		}
3164de7d4f0eSAndy Whitcroft
3165de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3166de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3167171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
3168171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3169171ae1a4SAndy Whitcroft
3170171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
3171171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3172171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
3173171ae1a4SAndy Whitcroft
317434d99219SJoe Perches			CHK("INVALID_UTF8",
3175000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
317600df344fSAndy Whitcroft		}
31770a920b5bSAndy Whitcroft
317815662b3eSJoe Perches# Check if it's the start of a commit log
317915662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
318015662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
3181eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
3182eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
318315662b3eSJoe Perches			$in_header_lines = 0;
318415662b3eSJoe Perches			$in_commit_log = 1;
3185ed43c4e5SAllen Hubbe			$has_commit_log = 1;
318615662b3eSJoe Perches		}
318715662b3eSJoe Perches
3188fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
3189fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
3190fa64205dSPasi Savanainen		if ($in_header_lines &&
3191fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3192fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
3193fa64205dSPasi Savanainen			$non_utf8_charset = 1;
3194fa64205dSPasi Savanainen		}
3195fa64205dSPasi Savanainen
3196fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
319715662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3198fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
319915662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
320015662b3eSJoe Perches		}
320115662b3eSJoe Perches
3202d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3203d6430f71SJoe Perches		if ($tree && $in_commit_log) {
3204d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3205d6430f71SJoe Perches				my $file = $1;
3206d6430f71SJoe Perches
3207d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3208d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
3209d6430f71SJoe Perches					#
3210d6430f71SJoe Perches				} else {
3211d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
3212d6430f71SJoe Perches				}
3213d6430f71SJoe Perches			}
3214d6430f71SJoe Perches		}
3215d6430f71SJoe Perches
321666b47b4aSKees Cook# Check for various typo / spelling mistakes
321766d7a382SJoe Perches		if (defined($misspellings) &&
321866d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
32197da07c31SDwaipayan Ray			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
322066b47b4aSKees Cook				my $typo = $1;
32217da07c31SDwaipayan Ray				my $blank = copy_spacing($rawline);
32227da07c31SDwaipayan Ray				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
32237da07c31SDwaipayan Ray				my $hereptr = "$hereline$ptr\n";
322466b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
322566b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
322666b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
32270675a8fbSJean Delvare				my $msg_level = \&WARN;
32280675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
32290675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
32307da07c31SDwaipayan Ray						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
323166b47b4aSKees Cook				    $fix) {
323266b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
323366b47b4aSKees Cook				}
323466b47b4aSKees Cook			}
323566b47b4aSKees Cook		}
323666b47b4aSKees Cook
3237a8dd86bfSMatteo Croce# check for invalid commit id
3238a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3239a8dd86bfSMatteo Croce			my $id;
3240a8dd86bfSMatteo Croce			my $description;
3241a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
3242a8dd86bfSMatteo Croce			if (!defined($id)) {
3243a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
3244a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3245a8dd86bfSMatteo Croce			}
3246a8dd86bfSMatteo Croce		}
3247a8dd86bfSMatteo Croce
3248310cd06bSJoe Perches# check for repeated words separated by a single space
32498d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
32508d0325ccSAditya Srivastava		if (($rawline =~ /^\+/ || $in_commit_log) &&
32518d0325ccSAditya Srivastava		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
32521db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3253310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3254310cd06bSJoe Perches
3255310cd06bSJoe Perches				my $first = $1;
3256310cd06bSJoe Perches				my $second = $2;
32571db81a68SDwaipayan Ray				my $start_pos = $-[1];
32581db81a68SDwaipayan Ray				my $end_pos = $+[2];
3259310cd06bSJoe Perches				if ($first =~ /(?:struct|union|enum)/) {
3260310cd06bSJoe Perches					pos($rawline) += length($first) + length($second) + 1;
3261310cd06bSJoe Perches					next;
3262310cd06bSJoe Perches				}
3263310cd06bSJoe Perches
32641db81a68SDwaipayan Ray				next if (lc($first) ne lc($second));
3265310cd06bSJoe Perches				next if ($first eq 'long');
3266310cd06bSJoe Perches
32671db81a68SDwaipayan Ray				# check for character before and after the word matches
32681db81a68SDwaipayan Ray				my $start_char = '';
32691db81a68SDwaipayan Ray				my $end_char = '';
32701db81a68SDwaipayan Ray				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
32711db81a68SDwaipayan Ray				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
32721db81a68SDwaipayan Ray
32731db81a68SDwaipayan Ray				next if ($start_char =~ /^\S$/);
32741db81a68SDwaipayan Ray				next if (index(" \t.,;?!", $end_char) == -1);
32751db81a68SDwaipayan Ray
32768d0325ccSAditya Srivastava				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
32778d0325ccSAditya Srivastava				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
32788d0325ccSAditya Srivastava					next if (!exists($allow_repeated_words{lc($first)}));
32798d0325ccSAditya Srivastava				}
32808d0325ccSAditya Srivastava
3281310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3282310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3283310cd06bSJoe Perches				    $fix) {
3284310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3285310cd06bSJoe Perches				}
3286310cd06bSJoe Perches			}
3287310cd06bSJoe Perches
3288310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3289310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
3290310cd06bSJoe Perches			    $prevrawline =~ /($word_pattern)\s*$/) {
3291310cd06bSJoe Perches				my $last_word = $1;
3292310cd06bSJoe Perches				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3293310cd06bSJoe Perches					if (WARN("REPEATED_WORD",
3294310cd06bSJoe Perches						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3295310cd06bSJoe Perches					    $fix) {
3296310cd06bSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3297310cd06bSJoe Perches					}
3298310cd06bSJoe Perches				}
3299310cd06bSJoe Perches			}
3300310cd06bSJoe Perches		}
3301310cd06bSJoe Perches
330230670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
330330670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
330400df344fSAndy Whitcroft
33050a920b5bSAndy Whitcroft#trailing whitespace
33069c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
3307c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3308d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3309d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
3310d5e616fcSJoe Perches			    $fix) {
3311194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3312d5e616fcSJoe Perches			}
3313c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3314c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
33153705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
33163705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
33173705ce5bSJoe Perches			    $fix) {
3318194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
33193705ce5bSJoe Perches			}
33203705ce5bSJoe Perches
3321d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
33220a920b5bSAndy Whitcroft		}
33235368df20SAndy Whitcroft
33244783f894SJosh Triplett# Check for FSF mailing addresses.
3325109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
33261bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
33273e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
33283e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
33294783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
33300675a8fbSJean Delvare			my $msg_level = \&ERROR;
33310675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
33320675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
33334783f894SJosh 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)
33344783f894SJosh Triplett		}
33354783f894SJosh Triplett
33363354957aSAndi Kleen# check for Kconfig help text having a real description
33379fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
33389fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
33393354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3340678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3341678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3342678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3343678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
33443354957aSAndi Kleen			my $length = 0;
33459fe287d7SAndy Whitcroft			my $cnt = $realcnt;
33469fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
33479fe287d7SAndy Whitcroft			my $f;
3348a1385803SAndy Whitcroft			my $is_start = 0;
33499fe287d7SAndy Whitcroft			my $is_end = 0;
3350a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
33519fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
33529fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
33539fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
33549fe287d7SAndy Whitcroft
33559fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
33568d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3357a1385803SAndy Whitcroft
335886adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3359a1385803SAndy Whitcroft					$is_start = 1;
336022a4ac02SMasahiro Yamada				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
3361a1385803SAndy Whitcroft					$length = -1;
3362a1385803SAndy Whitcroft				}
3363a1385803SAndy Whitcroft
33649fe287d7SAndy Whitcroft				$f =~ s/^.//;
33653354957aSAndi Kleen				$f =~ s/#.*//;
33663354957aSAndi Kleen				$f =~ s/^\s+//;
33673354957aSAndi Kleen				next if ($f =~ /^$/);
3368678ae162SUlf Magnusson
3369678ae162SUlf Magnusson				# This only checks context lines in the patch
3370678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3371678ae162SUlf Magnusson				# positives, even though some of these are
3372678ae162SUlf Magnusson				# common words in help texts
3373678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3374678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
33759fe287d7SAndy Whitcroft					$is_end = 1;
33769fe287d7SAndy Whitcroft					last;
33779fe287d7SAndy Whitcroft				}
33783354957aSAndi Kleen				$length++;
33793354957aSAndi Kleen			}
338056193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3381000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
338256193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
338356193274SVadim Bendebury			}
3384a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
33853354957aSAndi Kleen		}
33863354957aSAndi Kleen
33877ccf41a8SJoe Perches# check MAINTAINERS entries
33887ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
33897ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
33907ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3391628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3392628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3393628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3394628f91a2SJoe Perches				    $fix) {
3395628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3396628f91a2SJoe Perches				}
3397628f91a2SJoe Perches			}
33987ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
33997ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
34007ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
34017ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
34027ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
34037ccf41a8SJoe Perches				my $cur = $1;
34047ccf41a8SJoe Perches				my $curval = $2;
34057ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
34067ccf41a8SJoe Perches				my $prev = $1;
34077ccf41a8SJoe Perches				my $prevval = $2;
34087ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
34097ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
34107ccf41a8SJoe Perches				if ($curindex < 0) {
34117ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
34127ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
34137ccf41a8SJoe Perches				} else {
34147ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
34157ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
34167ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
34177ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
34187ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
34197ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
34207ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
34217ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
34227ccf41a8SJoe Perches					}
34237ccf41a8SJoe Perches				}
34247ccf41a8SJoe Perches			}
34257ccf41a8SJoe Perches		}
3426628f91a2SJoe Perches
3427c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3428c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3429c68e5878SArnaud Lacombe			my $flag = $1;
3430c68e5878SArnaud Lacombe			my $replacement = {
3431c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3432c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3433c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3434c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3435c68e5878SArnaud Lacombe			};
3436c68e5878SArnaud Lacombe
3437c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3438c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3439c68e5878SArnaud Lacombe		}
3440c68e5878SArnaud Lacombe
3441bff5da43SRob Herring# check for DT compatible documentation
34427dd05b38SFlorian Vaussard		if (defined $root &&
34437dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
34447dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
34457dd05b38SFlorian Vaussard
3446bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3447bff5da43SRob Herring
3448cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3449852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3450cc93319bSFlorian Vaussard
3451bff5da43SRob Herring			foreach my $compat (@compats) {
3452bff5da43SRob Herring				my $compat2 = $compat;
3453185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3454185d566bSRob Herring				my $compat3 = $compat;
3455185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3456185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3457bff5da43SRob Herring				if ( $? >> 8 ) {
3458bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3459bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3460bff5da43SRob Herring				}
3461bff5da43SRob Herring
34624fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
34634fbf32a6SFlorian Vaussard				my $vendor = $1;
3464852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3465bff5da43SRob Herring				if ( $? >> 8 ) {
3466bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3467cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3468bff5da43SRob Herring				}
3469bff5da43SRob Herring			}
3470bff5da43SRob Herring		}
3471bff5da43SRob Herring
34729f3a8992SRob Herring# check for using SPDX license tag at beginning of files
34739f3a8992SRob Herring		if ($realline == $checklicenseline) {
34749f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
34759f3a8992SRob Herring				$checklicenseline = 2;
34769f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
34779f3a8992SRob Herring				my $comment = "";
34789f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
34799f3a8992SRob Herring					$comment = '/*';
34809f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
34819f3a8992SRob Herring					$comment = '//';
3482c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
34839f3a8992SRob Herring					$comment = '#';
34849f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
34859f3a8992SRob Herring					$comment = '..';
34869f3a8992SRob Herring				}
34879f3a8992SRob Herring
3488fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3489fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3490fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3491ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3492fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3493fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3494fdf13693SJoe Perches				}
3495fdf13693SJoe Perches
34969f3a8992SRob Herring				if ($comment !~ /^$/ &&
3497ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
34989f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
34999f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
35003b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
35013b6e8ac9SJoe Perches					my $spdx_license = $1;
35023b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
35033b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
35043b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
35053b6e8ac9SJoe Perches					}
350650c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
350750c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
350850c92900SLubomir Rintel						my $msg_level = \&WARN;
350950c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
351050c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
351150c92900SLubomir Rintel
351250c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
351350c92900SLubomir Rintel						    $fix) {
351450c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
351550c92900SLubomir Rintel						}
351650c92900SLubomir Rintel					}
35179f3a8992SRob Herring				}
35189f3a8992SRob Herring			}
35199f3a8992SRob Herring		}
35209f3a8992SRob Herring
3521a0154cdbSJoe Perches# check for embedded filenames
3522a0154cdbSJoe Perches		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3523a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3524a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3525a0154cdbSJoe Perches		}
3526a0154cdbSJoe Perches
35275368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3528d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
35295368df20SAndy Whitcroft
3530a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3531a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3532a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3533a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3534a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3535a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3536a8da38a9SJoe Perches		}
3537a8da38a9SJoe Perches
353847e0c88bSJoe Perches# line length limit (with some exclusions)
353947e0c88bSJoe Perches#
354047e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
354147e0c88bSJoe Perches#	logging functions like pr_info that end in a string
354247e0c88bSJoe Perches#	lines with a single string
354347e0c88bSJoe Perches#	#defines that are a single string
35442e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
354547e0c88bSJoe Perches#
354647e0c88bSJoe Perches# There are 3 different line length message types:
3547ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
354847e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
354947e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
355047e0c88bSJoe Perches#
355147e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
355247e0c88bSJoe Perches#
355347e0c88bSJoe Perches
3554b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
355547e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
355647e0c88bSJoe Perches
355747e0c88bSJoe Perches			# Check the allowed long line types first
355847e0c88bSJoe Perches
355947e0c88bSJoe Perches			# logging functions that end in a string that starts
356047e0c88bSJoe Perches			# before $max_line_length
356147e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
356247e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
356347e0c88bSJoe Perches				$msg_type = "";
356447e0c88bSJoe Perches
356547e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
356647e0c88bSJoe Perches			# #defines with only strings
356747e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
356847e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
356947e0c88bSJoe Perches				$msg_type = "";
357047e0c88bSJoe Perches
3571cc147506SJoe Perches			# More special cases
3572cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3573cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3574d560a5f8SJoe Perches				$msg_type = "";
3575d560a5f8SJoe Perches
35762e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
35772e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
35782e4bbbc5SAndreas Brauchli				$msg_type = "";
35792e4bbbc5SAndreas Brauchli
358047e0c88bSJoe Perches			# Otherwise set the alternate message types
358147e0c88bSJoe Perches
358247e0c88bSJoe Perches			# a comment starts before $max_line_length
358347e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
358447e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
358547e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
358647e0c88bSJoe Perches
358747e0c88bSJoe Perches			# a quoted string starts before $max_line_length
358847e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
358947e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
359047e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
359147e0c88bSJoe Perches			}
359247e0c88bSJoe Perches
359347e0c88bSJoe Perches			if ($msg_type ne "" &&
359447e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3595bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3596bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3597bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3598bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
35990a920b5bSAndy Whitcroft			}
360047e0c88bSJoe Perches		}
36010a920b5bSAndy Whitcroft
36028905a67cSAndy Whitcroft# check for adding lines without a newline.
36038905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
360447ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
360547ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
360647ca69b8STom Rix			    $fix) {
360747ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
360847ca69b8STom Rix			}
36098905a67cSAndy Whitcroft		}
36108905a67cSAndy Whitcroft
3611de93245cSAditya Srivastava# check for .L prefix local symbols in .S files
3612de93245cSAditya Srivastava		if ($realfile =~ /\.S$/ &&
3613de93245cSAditya Srivastava		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3614de93245cSAditya Srivastava			WARN("AVOID_L_PREFIX",
3615de93245cSAditya Srivastava			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\n" . $herecurr);
3616de93245cSAditya Srivastava		}
3617de93245cSAditya Srivastava
3618b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3619de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
36200a920b5bSAndy Whitcroft
36210a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3622713a09deSAntonio Borneo# more than $tabsize must use tabs.
3623c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3624c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3625c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3626d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
36273705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
36283705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
36293705ce5bSJoe Perches			    $fix) {
3630194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
36313705ce5bSJoe Perches			}
36320a920b5bSAndy Whitcroft		}
36330a920b5bSAndy Whitcroft
363408e44365SAlberto Panizzo# check for space before tabs.
363508e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
363608e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
36373705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
36383705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
36393705ce5bSJoe Perches			    $fix) {
3640194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3641713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3642194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3643c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
36443705ce5bSJoe Perches			}
364508e44365SAlberto Panizzo		}
364608e44365SAlberto Panizzo
36476a487211SJoe Perches# check for assignments on the start of a line
36486a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3649da7355abSAditya Srivastava			my $operator = $1;
3650da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3651da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3652da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3653da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3654da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3655da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3656da7355abSAditya Srivastava			}
36576a487211SJoe Perches		}
36586a487211SJoe Perches
3659d1fe9c09SJoe Perches# check for && or || at the start of a line
3660d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
36618e08f076SAditya Srivastava			my $operator = $1;
36628e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
36638e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
36648e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
36658e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
36668e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
36678e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
36688e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
36698e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
36708e08f076SAditya Srivastava			}
3671d1fe9c09SJoe Perches		}
3672d1fe9c09SJoe Perches
3673a91e8994SJoe Perches# check indentation starts on a tab stop
36745b57980dSJoe Perches		if ($perl_version_ok &&
3675bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3676a91e8994SJoe Perches			my $indent = length($1);
3677713a09deSAntonio Borneo			if ($indent % $tabsize) {
3678a91e8994SJoe Perches				if (WARN("TABSTOP",
3679a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3680a91e8994SJoe Perches				    $fix) {
3681713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3682a91e8994SJoe Perches				}
3683a91e8994SJoe Perches			}
3684a91e8994SJoe Perches		}
3685a91e8994SJoe Perches
3686d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
36875b57980dSJoe Perches		if ($perl_version_ok &&
3688fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3689d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3690d1fe9c09SJoe Perches			my $oldindent = $1;
3691d1fe9c09SJoe Perches			my $rest = $2;
3692d1fe9c09SJoe Perches
3693d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3694d1fe9c09SJoe Perches			if ($pos >= 0) {
3695b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3696b34a26f3SJoe Perches				my $newindent = $2;
3697d1fe9c09SJoe Perches
3698d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3699713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3700713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3701d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3702d1fe9c09SJoe Perches
3703d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3704d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
37053705ce5bSJoe Perches
37063705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
37073705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
37083705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3709194f66fcSJoe Perches						$fixed[$fixlinenr] =~
37103705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
37113705ce5bSJoe Perches					}
3712d1fe9c09SJoe Perches				}
3713d1fe9c09SJoe Perches			}
3714d1fe9c09SJoe Perches		}
3715d1fe9c09SJoe Perches
37166ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
37176ab3a970SJoe Perches# avoid checking a few false positives:
37186ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
37196ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
37206ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
37216ab3a970SJoe Perches#   multiline macros that define functions
37226ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
37236ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
37246ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
37253705ce5bSJoe Perches			if (CHK("SPACING",
3726f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
37273705ce5bSJoe Perches			    $fix) {
3728194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3729f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
37303705ce5bSJoe Perches			}
3731aad4f614SJoe Perches		}
3732aad4f614SJoe Perches
373386406b1cSJoe Perches# Block comment styles
373486406b1cSJoe Perches# Networking with an initial /*
373505880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3736fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
373785ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
3738c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
373905880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
374005880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
374105880600SJoe Perches		}
374205880600SJoe Perches
374386406b1cSJoe Perches# Block comments use * on subsequent lines
374486406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
374586406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3746a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
374761135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3748a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
374986406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
375086406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3751a605e32eSJoe Perches		}
3752a605e32eSJoe Perches
375386406b1cSJoe Perches# Block comments use */ on trailing lines
375486406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3755c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3756c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3757c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
375886406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
375986406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
376005880600SJoe Perches		}
376105880600SJoe Perches
376208eb9b80SJoe Perches# Block comment * alignment
376308eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3764af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3765af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3766af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
376708eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3768af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3769af207524SJoe Perches			my $oldindent;
377008eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3771af207524SJoe Perches			if (defined($1)) {
3772af207524SJoe Perches				$oldindent = expand_tabs($1);
3773af207524SJoe Perches			} else {
3774af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3775af207524SJoe Perches				$oldindent = expand_tabs($1);
3776af207524SJoe Perches			}
377708eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
377808eb9b80SJoe Perches			my $newindent = $1;
377908eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3780af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
378108eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
378208eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
378308eb9b80SJoe Perches			}
378408eb9b80SJoe Perches		}
378508eb9b80SJoe Perches
37867f619191SJoe Perches# check for missing blank lines after struct/union declarations
37877f619191SJoe Perches# with exceptions for various attributes and macros
37887f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
37897f619191SJoe Perches		    $line =~ /^\+/ &&
37907f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
37917f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
37927f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
37937f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
37947f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
37957f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
37967f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
37970bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
37987f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3799d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3800d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3801d752fcc8SJoe Perches			    $fix) {
3802f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3803d752fcc8SJoe Perches			}
38047f619191SJoe Perches		}
38057f619191SJoe Perches
3806365dd4eaSJoe Perches# check for multiple consecutive blank lines
3807365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3808365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3809365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3810d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3811d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3812d752fcc8SJoe Perches			    $fix) {
3813f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3814d752fcc8SJoe Perches			}
3815d752fcc8SJoe Perches
3816365dd4eaSJoe Perches			$last_blank_line = $linenr;
3817365dd4eaSJoe Perches		}
3818365dd4eaSJoe Perches
38193b617e3bSJoe Perches# check for missing blank lines after declarations
3820b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
3821b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
3822b5e8736aSJoe Perches			# use temporaries
3823b5e8736aSJoe Perches			my $sl = $sline;
3824b5e8736aSJoe Perches			my $pl = $prevline;
3825b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
3826b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3827b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
3828b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
38295a4e1fd3SJoe Perches			# function pointer declarations
3830b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
38313f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3832b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
38333f7bac03SJoe Perches			# known declaration macros
3834b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
38353f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
3836b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
38373f7bac03SJoe Perches			# other possible extensions of declaration lines
3838b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
38393f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
3840b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
38413f7bac03SJoe Perches			# looks like a declaration
3842b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
38435a4e1fd3SJoe Perches			# function pointer declarations
3844b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
38453f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
3846b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
38473f7bac03SJoe Perches			# known declaration macros
3848b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
38493f7bac03SJoe Perches			# start of struct or union or enum
3850b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
38513f7bac03SJoe Perches			# start or end of block or continuation of declaration
3852b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
38533f7bac03SJoe Perches			# bitfield continuation
3854b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
38553f7bac03SJoe Perches			# other possible extensions of declaration lines
3856b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
3857d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
3858d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
3859d752fcc8SJoe Perches				    $fix) {
3860f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
3861d752fcc8SJoe Perches				}
38623b617e3bSJoe Perches			}
3863b5e8736aSJoe Perches		}
38643b617e3bSJoe Perches
38655f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
38666b4c5bebSAndy Whitcroft# Exceptions:
38676b4c5bebSAndy Whitcroft#  1) within comments
38686b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
38696b4c5bebSAndy Whitcroft#  3) hanging labels
38703705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
38715f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
38723705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
38733705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
38743705ce5bSJoe Perches			    $fix) {
3875194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
38763705ce5bSJoe Perches			}
38775f7ddae6SRaffaele Recalcati		}
38785f7ddae6SRaffaele Recalcati
3879b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3880b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3881b9ea10d6SAndy Whitcroft
38825751a24eSJoe Perches# check for unusual line ending [ or (
38835751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
38845751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
38855751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
38865751a24eSJoe Perches		}
38875751a24eSJoe Perches
38884dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
38894dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
38904dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
38914dbed76fSJoe Perches			$context_function = $1;
38924dbed76fSJoe Perches		}
38934dbed76fSJoe Perches
38944dbed76fSJoe Perches# check if this appears to be the end of function declaration
38954dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
38964dbed76fSJoe Perches			undef $context_function;
38974dbed76fSJoe Perches		}
38984dbed76fSJoe Perches
3899032a4c0fSJoe Perches# check indentation of any line with a bare else
3900840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3901032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3902032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3903032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3904840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3905840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3906840080a0SJoe Perches			     defined $lines[$linenr] &&
3907840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3908032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3909032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3910032a4c0fSJoe Perches			}
3911032a4c0fSJoe Perches		}
3912032a4c0fSJoe Perches
3913c00df19aSJoe Perches# check indentation of a line with a break;
3914dc58bc55SJoe Perches# if the previous line is a goto, return or break
3915dc58bc55SJoe Perches# and is indented the same # of tabs
3916c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3917c00df19aSJoe Perches			my $tabs = $1;
3918dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
3919dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
3920dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
3921dc58bc55SJoe Perches				    $fix) {
3922dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
3923dc58bc55SJoe Perches				}
3924c00df19aSJoe Perches			}
3925c00df19aSJoe Perches		}
3926c00df19aSJoe Perches
3927c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3928cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3929000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3930000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3931c2fdda0dSAndy Whitcroft		}
393222f2a2efSAndy Whitcroft
393356e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
393456e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
393556e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
393656e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
393756e77d70SJoe Perches		}
393856e77d70SJoe Perches
39399c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
39402b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
39412b474a1aSAndy Whitcroft		    $realline_next);
39423e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3943ca819864SJoe Perches		if ($linenr > $suppress_statement &&
39441b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3945170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3946f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3947171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3948171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3949171ae1a4SAndy Whitcroft
39503e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
39513e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
39523e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
39533e469cdcSAndy Whitcroft			# until we hit end of it.
39543e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
39553e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
39563e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
39573e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
39583e469cdcSAndy Whitcroft			}
3959f74bd194SAndy Whitcroft
39602b474a1aSAndy Whitcroft			# Find the real next line.
39612b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
39622b474a1aSAndy Whitcroft			if (defined $realline_next &&
39632b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
39642b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
39652b474a1aSAndy Whitcroft				$realline_next++;
39662b474a1aSAndy Whitcroft			}
39672b474a1aSAndy Whitcroft
3968171ae1a4SAndy Whitcroft			my $s = $stat;
3969171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3970cf655043SAndy Whitcroft
3971c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3972171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3973c2fdda0dSAndy Whitcroft
3974c2fdda0dSAndy Whitcroft			# Ignore functions being called
3975171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3976c2fdda0dSAndy Whitcroft
3977463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3978463f2864SAndy Whitcroft
3979c45dcabdSAndy Whitcroft			# declarations always start with types
3980d2506586SAndy 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) {
3981c45dcabdSAndy Whitcroft				my $type = $1;
3982c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3983c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3984c45dcabdSAndy Whitcroft
39856c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3986a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3987c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3988c2fdda0dSAndy Whitcroft			}
39898905a67cSAndy Whitcroft
39906c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
399165863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3992c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
39939c0ca6f9SAndy Whitcroft			}
39948905a67cSAndy Whitcroft
39958905a67cSAndy Whitcroft			# Check for any sort of function declaration.
39968905a67cSAndy Whitcroft			# int foo(something bar, other baz);
39978905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3998171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
39998905a67cSAndy Whitcroft				my ($name_len) = length($1);
40008905a67cSAndy Whitcroft
4001cf655043SAndy Whitcroft				my $ctx = $s;
4002773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
40038905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
4004cf655043SAndy Whitcroft
40058905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4006c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
40078905a67cSAndy Whitcroft
4008c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
40098905a67cSAndy Whitcroft					}
40108905a67cSAndy Whitcroft				}
40118905a67cSAndy Whitcroft			}
40128905a67cSAndy Whitcroft
40139c0ca6f9SAndy Whitcroft		}
40149c0ca6f9SAndy Whitcroft
401500df344fSAndy Whitcroft#
401600df344fSAndy Whitcroft# Checks which may be anchored in the context.
401700df344fSAndy Whitcroft#
401800df344fSAndy Whitcroft
401900df344fSAndy Whitcroft# Check for switch () and associated case and default
402000df344fSAndy Whitcroft# statements should be at the same indent.
402100df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
402200df344fSAndy Whitcroft			my $err = '';
402300df344fSAndy Whitcroft			my $sep = '';
402400df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
402500df344fSAndy Whitcroft			shift(@ctx);
402600df344fSAndy Whitcroft			for my $ctx (@ctx) {
402700df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
402800df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
402900df344fSAndy Whitcroft							$indent != $cindent) {
403000df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
403100df344fSAndy Whitcroft					$sep = '';
403200df344fSAndy Whitcroft				} else {
403300df344fSAndy Whitcroft					$sep = "[...]\n";
403400df344fSAndy Whitcroft				}
403500df344fSAndy Whitcroft			}
403600df344fSAndy Whitcroft			if ($err ne '') {
4037000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4038000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4039de7d4f0eSAndy Whitcroft			}
4040de7d4f0eSAndy Whitcroft		}
4041de7d4f0eSAndy Whitcroft
4042de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4043de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
40440fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4045773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4046773647a0SAndy Whitcroft
40479c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
40488eef05ddSJoe Perches
40498eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
40508eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
40518eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
40528eef05ddSJoe Perches			}
40538eef05ddSJoe Perches
4054de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4055de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4056de7d4f0eSAndy Whitcroft
4057548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4058548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4059de7d4f0eSAndy Whitcroft
4060548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4061548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4062548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4063548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4064548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4065773647a0SAndy Whitcroft				$ctx_ln++;
4066773647a0SAndy Whitcroft			}
4067548596d5SAndy Whitcroft
406853210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
406953210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4070773647a0SAndy Whitcroft
4071773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4072000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4073000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
407401464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
407500df344fSAndy Whitcroft			}
4076773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4077773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4078773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4079773647a0SAndy Whitcroft			{
40809c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
40819c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4082000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4083000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
408401464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
40859c0ca6f9SAndy Whitcroft				}
40869c0ca6f9SAndy Whitcroft			}
408700df344fSAndy Whitcroft		}
408800df344fSAndy Whitcroft
40894d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4090f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
40913e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
40923e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
40933e469cdcSAndy Whitcroft					if (!defined $stat);
40944d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
40954d001e4dSAndy Whitcroft
40964d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
40974d001e4dSAndy Whitcroft
40989f5af480SJoe Perches			# remove inline comments
40999f5af480SJoe Perches			$s =~ s/$;/ /g;
41009f5af480SJoe Perches			$c =~ s/$;/ /g;
41014d001e4dSAndy Whitcroft
41024d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
41036f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
41046f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
41054d001e4dSAndy Whitcroft
41069f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
41079f5af480SJoe Perches			# none on the first line, and are going to readd them
41089f5af480SJoe Perches			# where necessary.
41099f5af480SJoe Perches			$s =~ s/\n./\n/gs;
41109f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
41119f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
41129f5af480SJoe Perches			}
41139f5af480SJoe Perches
41144d001e4dSAndy Whitcroft			# We want to check the first line inside the block
41154d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
41164d001e4dSAndy Whitcroft			#  1) any blank line termination
41174d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
41184d001e4dSAndy Whitcroft			#  3) any do (...) {
41194d001e4dSAndy Whitcroft			my $continuation = 0;
41204d001e4dSAndy Whitcroft			my $check = 0;
41214d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
41224d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
41234d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
41244d001e4dSAndy Whitcroft				$continuation = 1;
41254d001e4dSAndy Whitcroft			}
41269bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
41274d001e4dSAndy Whitcroft				$check = 1;
41284d001e4dSAndy Whitcroft				$cond_lines++;
41294d001e4dSAndy Whitcroft			}
41304d001e4dSAndy Whitcroft
41314d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
41324d001e4dSAndy Whitcroft			# preprocessor statement.
41334d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
41344d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
41354d001e4dSAndy Whitcroft				$check = 0;
41364d001e4dSAndy Whitcroft			}
41374d001e4dSAndy Whitcroft
41389bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4139740504c6SAndy Whitcroft			$continuation = 0;
41409bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
41419bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
41424d001e4dSAndy Whitcroft
4143f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4144f16fa28fSAndy Whitcroft				# is not linear.
4145f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4146f16fa28fSAndy Whitcroft					$check = 0;
4147f16fa28fSAndy Whitcroft				}
4148f16fa28fSAndy Whitcroft
41499bd49efeSAndy Whitcroft				# Ignore:
41509bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
41519bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
41529bd49efeSAndy Whitcroft				#  3) labels.
4153740504c6SAndy Whitcroft				if ($continuation ||
4154740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
41559bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
41569bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4157740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
415830dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
41599bd49efeSAndy Whitcroft						$cond_lines++;
41609bd49efeSAndy Whitcroft					}
41614d001e4dSAndy Whitcroft				}
416230dad6ebSAndy Whitcroft			}
41634d001e4dSAndy Whitcroft
41644d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
41654d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
41664d001e4dSAndy Whitcroft
41674d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
41684d001e4dSAndy Whitcroft			# this is not this patch's fault.
41694d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
41704d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
41714d001e4dSAndy Whitcroft				$check = 0;
41724d001e4dSAndy Whitcroft			}
41734d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
41744d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
41754d001e4dSAndy Whitcroft			}
41764d001e4dSAndy Whitcroft
41779bd49efeSAndy 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";
41784d001e4dSAndy Whitcroft
41799f5af480SJoe Perches			if ($check && $s ne '' &&
4180713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
41819f5af480SJoe Perches			     ($sindent < $indent) ||
4182f6950a73SJoe Perches			     ($sindent == $indent &&
4183f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4184713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4185000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4186000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
41874d001e4dSAndy Whitcroft			}
41884d001e4dSAndy Whitcroft		}
41894d001e4dSAndy Whitcroft
41906c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
41916c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
41921f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
41931f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
41946c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4195c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4196c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4197cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4198cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
41991f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4200c2fdda0dSAndy Whitcroft		}
42016c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
42026c72ffaaSAndy Whitcroft
420300df344fSAndy Whitcroft#ignore lines not being added
42043705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
420500df344fSAndy Whitcroft
420699ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
420799ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
420899ca38c2SJoe Perches#	struct foo bar = *(&(bar));
420999ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
421099ca38c2SJoe Perches			my $var = $1;
421199ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
421299ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
421399ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
421499ca38c2SJoe Perches			}
421599ca38c2SJoe Perches		}
421699ca38c2SJoe Perches
421711ca40a0SJoe Perches# check for dereferences that span multiple lines
421811ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
421911ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
422011ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
422111ca40a0SJoe Perches			my $ref = $1;
422211ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
422311ca40a0SJoe Perches			$ref .= $1;
422411ca40a0SJoe Perches			$ref =~ s/\s//g;
422511ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
422611ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
422711ca40a0SJoe Perches		}
422811ca40a0SJoe Perches
4229a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4230c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4231a1ce18e4SJoe Perches			my $type = $1;
4232a1ce18e4SJoe Perches			my $var = $2;
4233207a8e84SJoe Perches			$var = "" if (!defined $var);
4234207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4235a1ce18e4SJoe Perches				my $sign = $1;
4236a1ce18e4SJoe Perches				my $pointer = $2;
4237a1ce18e4SJoe Perches
4238a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4239a1ce18e4SJoe Perches
4240a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4241a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4242a1ce18e4SJoe Perches				    $fix) {
4243a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4244207a8e84SJoe Perches					my $comp_pointer = $pointer;
4245207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4246207a8e84SJoe Perches					$decl .= $comp_pointer;
4247207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4248207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4249a1ce18e4SJoe Perches				}
4250a1ce18e4SJoe Perches			}
4251a1ce18e4SJoe Perches		}
4252a1ce18e4SJoe Perches
4253653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
42547429c690SAndy Whitcroft		if ($dbg_type) {
42557429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4256000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4257000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
42587429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4259000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4260000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
42617429c690SAndy Whitcroft			}
4262653d4876SAndy Whitcroft			next;
4263653d4876SAndy Whitcroft		}
4264a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4265a1ef277eSAndy Whitcroft		if ($dbg_attr) {
42669360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4267000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4268000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
42699360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4270000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4271000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4272a1ef277eSAndy Whitcroft			}
4273a1ef277eSAndy Whitcroft			next;
4274a1ef277eSAndy Whitcroft		}
4275653d4876SAndy Whitcroft
4276f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
427799423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
427899423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4279d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4280d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4281f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4282f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4283f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4284d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4285d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4286f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4287d752fcc8SJoe Perches				$fixedline = $line;
42888d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4289f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4290d752fcc8SJoe Perches			}
4291f0a594c1SAndy Whitcroft		}
4292f0a594c1SAndy Whitcroft
429300df344fSAndy Whitcroft#
429400df344fSAndy Whitcroft# Checks which are anchored on the added line.
429500df344fSAndy Whitcroft#
429600df344fSAndy Whitcroft
4297653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4298c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4299653d4876SAndy Whitcroft			my $path = $1;
4300653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4301000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4302495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4303495e9d84SJoe Perches			}
4304495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4305495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4306495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4307653d4876SAndy Whitcroft			}
4308653d4876SAndy Whitcroft		}
4309653d4876SAndy Whitcroft
431000df344fSAndy Whitcroft# no C99 // comments
431100df344fSAndy Whitcroft		if ($line =~ m{//}) {
43123705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
43133705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
43143705ce5bSJoe Perches			    $fix) {
4315194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
43163705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
43173705ce5bSJoe Perches					my $comment = trim($1);
4318194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
43193705ce5bSJoe Perches				}
43203705ce5bSJoe Perches			}
432100df344fSAndy Whitcroft		}
432200df344fSAndy Whitcroft		# Remove C99 comments.
43230a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
43246c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
43250a920b5bSAndy Whitcroft
43262b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
43272b474a1aSAndy Whitcroft# the whole statement.
43282b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
43292b474a1aSAndy Whitcroft		if (defined $realline_next &&
43302b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
43312b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
433236794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
43333cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
43343cbf62dfSAndy Whitcroft			# a prefix:
43353cbf62dfSAndy Whitcroft			#   XXX(foo);
43363cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4337653d4876SAndy Whitcroft			my $name = $1;
433887a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
43393cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
43403cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
43413cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
43423cbf62dfSAndy Whitcroft
43433cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
43442b474a1aSAndy Whitcroft				\n.}\s*$|
434548012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
434648012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
434748012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
43482b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
43492b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
435048012058SAndy Whitcroft			    )/x) {
43512b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
43522b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
43532b474a1aSAndy Whitcroft			} else {
43542b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
43550a920b5bSAndy Whitcroft			}
43560a920b5bSAndy Whitcroft		}
43572b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
43582b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
435936794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
43602b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
43612b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
43622b474a1aSAndy Whitcroft		}
43632b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
43642b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4365000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4366000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
43672b474a1aSAndy Whitcroft		}
43680a920b5bSAndy Whitcroft
43695150bda4SJoe Eloff# check for global initialisers.
43705b8f82e1SSong Liu		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
43715b8f82e1SSong Liu		    !exclude_global_initialisers($realfile)) {
4372d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
43736d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4374d5e616fcSJoe Perches			    $fix) {
43756d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4376d5e616fcSJoe Perches			}
4377f0a594c1SAndy Whitcroft		}
43780a920b5bSAndy Whitcroft# check for static initialisers.
43796d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4380d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
43816d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4382d5e616fcSJoe Perches				      $herecurr) &&
4383d5e616fcSJoe Perches			    $fix) {
43846d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4385d5e616fcSJoe Perches			}
43860a920b5bSAndy Whitcroft		}
43870a920b5bSAndy Whitcroft
43881813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
43891813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
43901813087dSJoe Perches			my $tmp = trim($1);
43911813087dSJoe Perches			WARN("MISORDERED_TYPE",
43921813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
43931813087dSJoe Perches		}
43941813087dSJoe Perches
4395809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4396809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4397809e082eSJoe Perches			my $type = trim($1);
4398809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4399809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4400809e082eSJoe Perches			my $new_type = $type;
4401809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4402809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4403809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4404809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4405809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4406809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4407809e082eSJoe Perches			$new_type = trim($new_type);
4408809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4409809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4410809e082eSJoe Perches			    $fix) {
4411809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4412809e082eSJoe Perches			}
4413809e082eSJoe Perches		}
4414809e082eSJoe Perches
4415cb710ecaSJoe Perches# check for static const char * arrays.
4416cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4417000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4418000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4419cb710ecaSJoe Perches				$herecurr);
4420cb710ecaSJoe Perches		}
4421cb710ecaSJoe Perches
442277b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
442377b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
442477b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
442577b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
442677b8c0a8SJoe Perches			    $fix) {
442777b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
442877b8c0a8SJoe Perches			}
442977b8c0a8SJoe Perches		}
443077b8c0a8SJoe Perches
4431cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4432cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4433000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4434000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4435cb710ecaSJoe Perches				$herecurr);
4436cb710ecaSJoe Perches		}
4437cb710ecaSJoe Perches
4438ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4439ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4440ab7e23f3SJoe Perches			my $found = $1;
4441ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4442ab7e23f3SJoe Perches				WARN("CONST_CONST",
4443ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4444ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4445ab7e23f3SJoe Perches				WARN("CONST_CONST",
4446ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4447ab7e23f3SJoe Perches			}
4448ab7e23f3SJoe Perches		}
4449ab7e23f3SJoe Perches
445073169765SJoe Perches# check for const static or static <non ptr type> const declarations
445173169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
445273169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
445373169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
445473169765SJoe Perches			if (WARN("STATIC_CONST",
445573169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
445673169765SJoe Perches			    $fix) {
445773169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
445873169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
445973169765SJoe Perches			}
446073169765SJoe Perches		}
446173169765SJoe Perches
44629b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
44639b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
44649b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
44659b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
44669b0fa60dSJoe Perches				$herecurr);
44679b0fa60dSJoe Perches		}
44689b0fa60dSJoe Perches
4469b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4470b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4471b598b670SJoe Perches			my $array = $1;
4472b598b670SJoe 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*\))@) {
4473b598b670SJoe Perches				my $array_div = $1;
4474b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4475b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4476b598b670SJoe Perches				    $fix) {
4477b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4478b598b670SJoe Perches				}
4479b598b670SJoe Perches			}
4480b598b670SJoe Perches		}
4481b598b670SJoe Perches
4482b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
448316b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4484b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4485b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4486b36190c5SJoe Perches			    $fix) {
4487194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4488b36190c5SJoe Perches			}
4489b36190c5SJoe Perches		}
4490b36190c5SJoe Perches
4491653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4492653d4876SAndy Whitcroft# make sense.
4493653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
44948054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4495c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
44968ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
449746d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4498000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4499000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
45000a920b5bSAndy Whitcroft		}
45010a920b5bSAndy Whitcroft
45020a920b5bSAndy Whitcroft# * goes on variable not on type
450365863862SAndy Whitcroft		# (char*[ const])
4504bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4505bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
45063705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4507d8aaf121SAndy Whitcroft
450865863862SAndy Whitcroft			# Should start with a space.
450965863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
451065863862SAndy Whitcroft			# Should not end with a space.
451165863862SAndy Whitcroft			$to =~ s/\s+$//;
451265863862SAndy Whitcroft			# '*'s should not have spaces between.
4513f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
451465863862SAndy Whitcroft			}
4515d8aaf121SAndy Whitcroft
45163705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
451765863862SAndy Whitcroft			if ($from ne $to) {
45183705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
45193705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
45203705ce5bSJoe Perches				    $fix) {
45213705ce5bSJoe Perches					my $sub_from = $ident;
45223705ce5bSJoe Perches					my $sub_to = $ident;
45233705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4524194f66fcSJoe Perches					$fixed[$fixlinenr] =~
45253705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
45263705ce5bSJoe Perches				}
452765863862SAndy Whitcroft			}
4528bfcb2cc7SAndy Whitcroft		}
4529bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4530bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
45313705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4532d8aaf121SAndy Whitcroft
453365863862SAndy Whitcroft			# Should start with a space.
453465863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
453565863862SAndy Whitcroft			# Should not end with a space.
453665863862SAndy Whitcroft			$to =~ s/\s+$//;
453765863862SAndy Whitcroft			# '*'s should not have spaces between.
4538f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
453965863862SAndy Whitcroft			}
454065863862SAndy Whitcroft			# Modifiers should have spaces.
454165863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
454265863862SAndy Whitcroft
45433705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4544667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
45453705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
45463705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
45473705ce5bSJoe Perches				    $fix) {
45483705ce5bSJoe Perches
45493705ce5bSJoe Perches					my $sub_from = $match;
45503705ce5bSJoe Perches					my $sub_to = $match;
45513705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4552194f66fcSJoe Perches					$fixed[$fixlinenr] =~
45533705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
45543705ce5bSJoe Perches				}
455565863862SAndy Whitcroft			}
45560a920b5bSAndy Whitcroft		}
45570a920b5bSAndy Whitcroft
45589d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
45599d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
45600675a8fbSJean Delvare			my $msg_level = \&WARN;
45610675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
45620675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
45639d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
45649d3e3c70SJoe Perches		}
45650a920b5bSAndy Whitcroft
45669d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
45678905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4568000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4569000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
45708905a67cSAndy Whitcroft		}
45718905a67cSAndy Whitcroft
457217441227SJoe Perches# check for uses of printk_ratelimit
457317441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4574000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4575000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
457617441227SJoe Perches		}
457717441227SJoe Perches
4578eeef5733SJoe Perches# printk should use KERN_* levels
4579eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4580000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4581eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
458200df344fSAndy Whitcroft		}
45830a920b5bSAndy Whitcroft
4584f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4585f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4586f5eea3b0SJoe Perches			my $printk = $1;
4587f5eea3b0SJoe Perches			my $modifier = $2;
4588f5eea3b0SJoe Perches			my $orig = $3;
4589f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4590243f3803SJoe Perches			my $level = lc($orig);
4591243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
45928f26b837SJoe Perches			my $level2 = $level;
45938f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4594f5eea3b0SJoe Perches			$level .= $modifier;
4595f5eea3b0SJoe Perches			$level2 .= $modifier;
4596243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4597f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4598243f3803SJoe Perches		}
4599243f3803SJoe Perches
4600f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4601dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4602dc139313SJoe Perches			my $orig = $1;
4603dc139313SJoe Perches			my $level = lc($orig);
4604dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4605dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4606dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4607dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4608dc139313SJoe Perches		}
4609dc139313SJoe Perches
46108020b253SNicolas Boichat# trace_printk should not be used in production code.
46118020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
46128020b253SNicolas Boichat			WARN("TRACE_PRINTK",
46138020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
46148020b253SNicolas Boichat		}
46158020b253SNicolas Boichat
461691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
461791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
461891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
461991c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
462091c9afafSAndy Lutomirski			WARN("ENOSYS",
462191c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
462291c9afafSAndy Lutomirski		}
462391c9afafSAndy Lutomirski
46246b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
46256b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
46266b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
46276b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
46286b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
46296b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
46306b9ea5ffSJakub Kicinski			    $fix) {
46316b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
46326b9ea5ffSJakub Kicinski			}
46336b9ea5ffSJakub Kicinski		}
46346b9ea5ffSJakub Kicinski
4635653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4636653d4876SAndy Whitcroft# or if closed on same line
46375b57980dSJoe Perches		if ($perl_version_ok &&
46382d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
46392d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
46402d453e3bSJoe Perches		    $sline !~ /}/) {
46418d182478SJoe Perches			if (ERROR("OPEN_BRACE",
46422d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
46438d182478SJoe Perches			    $fix) {
46448d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46458d182478SJoe Perches				my $fixed_line = $rawline;
464603f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
46478d182478SJoe Perches				my $line1 = $1;
46488d182478SJoe Perches				my $line2 = $2;
46498d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
46508d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
46518d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
46528d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
46538d182478SJoe Perches				}
46548d182478SJoe Perches			}
46550a920b5bSAndy Whitcroft		}
4656653d4876SAndy Whitcroft
46578905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
46588905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
46598905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
46608d182478SJoe Perches			if (ERROR("OPEN_BRACE",
46618d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
46628d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46638d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46648d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46658d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
46668d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46678d182478SJoe Perches				$fixedline = $rawline;
46688d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
46698d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46708d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46718d182478SJoe Perches				}
46728d182478SJoe Perches			}
46738905a67cSAndy Whitcroft		}
46748905a67cSAndy Whitcroft
46750c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
46763705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
46773705ce5bSJoe Perches			if (WARN("SPACING",
46783705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
46793705ce5bSJoe Perches			    $fix) {
4680194f66fcSJoe Perches				$fixed[$fixlinenr] =~
46813705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
46823705ce5bSJoe Perches			}
46830c73b4ebSAndy Whitcroft		}
46840c73b4ebSAndy Whitcroft
468531070b5dSJoe Perches# Function pointer declarations
468631070b5dSJoe Perches# check spacing between type, funcptr, and args
468731070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
468891f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
468931070b5dSJoe Perches			my $declare = $1;
469031070b5dSJoe Perches			my $pre_pointer_space = $2;
469131070b5dSJoe Perches			my $post_pointer_space = $3;
469231070b5dSJoe Perches			my $funcname = $4;
469331070b5dSJoe Perches			my $post_funcname_space = $5;
469431070b5dSJoe Perches			my $pre_args_space = $6;
469531070b5dSJoe Perches
469691f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
469791f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
469891f72e9cSJoe Perches# don't need a space so don't warn for those.
469991f72e9cSJoe Perches			my $post_declare_space = "";
470091f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
470191f72e9cSJoe Perches				$post_declare_space = $1;
470291f72e9cSJoe Perches				$declare = rtrim($declare);
470391f72e9cSJoe Perches			}
470491f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
470531070b5dSJoe Perches				WARN("SPACING",
470631070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
470791f72e9cSJoe Perches				$post_declare_space = " ";
470831070b5dSJoe Perches			}
470931070b5dSJoe Perches
471031070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
471191f72e9cSJoe Perches# This test is not currently implemented because these declarations are
471291f72e9cSJoe Perches# equivalent to
471391f72e9cSJoe Perches#	int  foo(int bar, ...)
471491f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
471591f72e9cSJoe Perches#
471691f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
471791f72e9cSJoe Perches#				WARN("SPACING",
471891f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
471991f72e9cSJoe Perches#			}
472031070b5dSJoe Perches
472131070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
472231070b5dSJoe Perches			if (defined $pre_pointer_space &&
472331070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
472431070b5dSJoe Perches				WARN("SPACING",
472531070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
472631070b5dSJoe Perches			}
472731070b5dSJoe Perches
472831070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
472931070b5dSJoe Perches			if (defined $post_pointer_space &&
473031070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
473131070b5dSJoe Perches				WARN("SPACING",
473231070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
473331070b5dSJoe Perches			}
473431070b5dSJoe Perches
473531070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
473631070b5dSJoe Perches			if (defined $post_funcname_space &&
473731070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
473831070b5dSJoe Perches				WARN("SPACING",
473931070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
474031070b5dSJoe Perches			}
474131070b5dSJoe Perches
474231070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
474331070b5dSJoe Perches			if (defined $pre_args_space &&
474431070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
474531070b5dSJoe Perches				WARN("SPACING",
474631070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
474731070b5dSJoe Perches			}
474831070b5dSJoe Perches
474931070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4750194f66fcSJoe Perches				$fixed[$fixlinenr] =~
475191f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
475231070b5dSJoe Perches			}
475331070b5dSJoe Perches		}
475431070b5dSJoe Perches
47558d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
47568d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4757fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4758fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
47598d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
47608d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
47618d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4762fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
476338dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
47643705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
47653705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
47663705ce5bSJoe Perches				    $fix) {
4767194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
47683705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
47693705ce5bSJoe Perches				}
47708d31cfceSAndy Whitcroft			}
47718d31cfceSAndy Whitcroft		}
47728d31cfceSAndy Whitcroft
4773f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
47746c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4775c2fdda0dSAndy Whitcroft			my $name = $1;
4776773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4777773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4778c2fdda0dSAndy Whitcroft
4779c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4780773647a0SAndy Whitcroft			if ($name =~ /^(?:
4781773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4782773647a0SAndy Whitcroft				volatile|__volatile__|
4783773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4784773647a0SAndy Whitcroft				asm|__asm__)$/x)
4785773647a0SAndy Whitcroft			{
4786c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4787c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4788c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4789c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4790773647a0SAndy Whitcroft
4791773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4792c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4793c2fdda0dSAndy Whitcroft
4794c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4795c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4796773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4797c2fdda0dSAndy Whitcroft
4798c2fdda0dSAndy Whitcroft			} else {
47993705ce5bSJoe Perches				if (WARN("SPACING",
48003705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
48013705ce5bSJoe Perches					     $fix) {
4802194f66fcSJoe Perches					$fixed[$fixlinenr] =~
48033705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
48043705ce5bSJoe Perches				}
4805f0a594c1SAndy Whitcroft			}
48066c72ffaaSAndy Whitcroft		}
48079a4cad4eSEric Nelson
4808653d4876SAndy Whitcroft# Check operator spacing.
48090a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
48103705ce5bSJoe Perches			my $fixed_line = "";
48113705ce5bSJoe Perches			my $line_fixed = 0;
48123705ce5bSJoe Perches
48139c0ca6f9SAndy Whitcroft			my $ops = qr{
48149c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
48159c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
48169c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
48171f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
481884731623SJoe Perches				\?:|\?|:
48199c0ca6f9SAndy Whitcroft			}x;
4820cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
48213705ce5bSJoe Perches
48223705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
48233705ce5bSJoe Perches##			foreach my $el (@elements) {
48243705ce5bSJoe Perches##				print("el: <$el>\n");
48253705ce5bSJoe Perches##			}
48263705ce5bSJoe Perches
48273705ce5bSJoe Perches			my @fix_elements = ();
482800df344fSAndy Whitcroft			my $off = 0;
48296c72ffaaSAndy Whitcroft
48303705ce5bSJoe Perches			foreach my $el (@elements) {
48313705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
48323705ce5bSJoe Perches				$off += length($el);
48333705ce5bSJoe Perches			}
48343705ce5bSJoe Perches
48353705ce5bSJoe Perches			$off = 0;
48363705ce5bSJoe Perches
48376c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4838b34c648bSJoe Perches			my $last_after = -1;
48396c72ffaaSAndy Whitcroft
48400a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
48413705ce5bSJoe Perches
48423705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
48433705ce5bSJoe Perches
48443705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
48453705ce5bSJoe Perches
48464a0df2efSAndy Whitcroft				$off += length($elements[$n]);
48474a0df2efSAndy Whitcroft
484825985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4849773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4850773647a0SAndy Whitcroft				my $cc = '';
4851773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4852773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4853773647a0SAndy Whitcroft				}
4854773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4855773647a0SAndy Whitcroft
48564a0df2efSAndy Whitcroft				my $a = '';
48574a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
48584a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4859cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
48604a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
48614a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4862773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
48634a0df2efSAndy Whitcroft
48640a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
48654a0df2efSAndy Whitcroft
48664a0df2efSAndy Whitcroft				my $c = '';
48670a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
48684a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
48694a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4870cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
48714a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
48724a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
48738b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
48744a0df2efSAndy Whitcroft				} else {
48754a0df2efSAndy Whitcroft					$c = 'E';
48760a920b5bSAndy Whitcroft				}
48770a920b5bSAndy Whitcroft
48784a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
48794a0df2efSAndy Whitcroft
48804a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
48814a0df2efSAndy Whitcroft
48826c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4883de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
48840a920b5bSAndy Whitcroft
488574048ed8SAndy Whitcroft				# Pull out the value of this operator.
48866c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
48870a920b5bSAndy Whitcroft
48881f65f947SAndy Whitcroft				# Get the full operator variant.
48891f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
48901f65f947SAndy Whitcroft
489113214adfSAndy Whitcroft				# Ignore operators passed as parameters.
489213214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4893d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
489413214adfSAndy Whitcroft
4895cf655043SAndy Whitcroft#				# Ignore comments
4896cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
489713214adfSAndy Whitcroft
4898d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
489913214adfSAndy Whitcroft				} elsif ($op eq ';') {
4900cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4901cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
49023705ce5bSJoe Perches						if (ERROR("SPACING",
49033705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4904b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
49053705ce5bSJoe Perches							$line_fixed = 1;
49063705ce5bSJoe Perches						}
4907d8aaf121SAndy Whitcroft					}
4908d8aaf121SAndy Whitcroft
4909d8aaf121SAndy Whitcroft				# // is a comment
4910d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
49110a920b5bSAndy Whitcroft
4912b00e4814SJoe Perches				#   :   when part of a bitfield
4913b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4914b00e4814SJoe Perches					# skip the bitfield test for now
4915b00e4814SJoe Perches
49161f65f947SAndy Whitcroft				# No spaces for:
49171f65f947SAndy Whitcroft				#   ->
4918b00e4814SJoe Perches				} elsif ($op eq '->') {
49194a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
49203705ce5bSJoe Perches						if (ERROR("SPACING",
49213705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4922b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
49233705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
49243705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
49253705ce5bSJoe Perches							}
4926b34c648bSJoe Perches							$line_fixed = 1;
49273705ce5bSJoe Perches						}
49280a920b5bSAndy Whitcroft					}
49290a920b5bSAndy Whitcroft
49302381097bSJoe Perches				# , must not have a space before and must have a space on the right.
49310a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
49322381097bSJoe Perches					my $rtrim_before = 0;
49332381097bSJoe Perches					my $space_after = 0;
49342381097bSJoe Perches					if ($ctx =~ /Wx./) {
49352381097bSJoe Perches						if (ERROR("SPACING",
49362381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
49372381097bSJoe Perches							$line_fixed = 1;
49382381097bSJoe Perches							$rtrim_before = 1;
49392381097bSJoe Perches						}
49402381097bSJoe Perches					}
4941cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
49423705ce5bSJoe Perches						if (ERROR("SPACING",
49433705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
49443705ce5bSJoe Perches							$line_fixed = 1;
4945b34c648bSJoe Perches							$last_after = $n;
49462381097bSJoe Perches							$space_after = 1;
49472381097bSJoe Perches						}
49482381097bSJoe Perches					}
49492381097bSJoe Perches					if ($rtrim_before || $space_after) {
49502381097bSJoe Perches						if ($rtrim_before) {
49512381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
49522381097bSJoe Perches						} else {
49532381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
49542381097bSJoe Perches						}
49552381097bSJoe Perches						if ($space_after) {
49562381097bSJoe Perches							$good .= " ";
49573705ce5bSJoe Perches						}
49580a920b5bSAndy Whitcroft					}
49590a920b5bSAndy Whitcroft
49609c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
496174048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
49629c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
49639c0ca6f9SAndy Whitcroft
49649c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
49659c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
49669c0ca6f9SAndy Whitcroft				# unary operator, or a cast
49679c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
496874048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
49690d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4970cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
49713705ce5bSJoe Perches						if (ERROR("SPACING",
49723705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4973b34c648bSJoe Perches							if ($n != $last_after + 2) {
4974b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
49753705ce5bSJoe Perches								$line_fixed = 1;
49763705ce5bSJoe Perches							}
49770a920b5bSAndy Whitcroft						}
4978b34c648bSJoe Perches					}
4979a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4980171ae1a4SAndy Whitcroft						# A unary '*' may be const
4981171ae1a4SAndy Whitcroft
4982171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
49833705ce5bSJoe Perches						if (ERROR("SPACING",
49843705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4985b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
49863705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
49873705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
49883705ce5bSJoe Perches							}
4989b34c648bSJoe Perches							$line_fixed = 1;
49903705ce5bSJoe Perches						}
49910a920b5bSAndy Whitcroft					}
49920a920b5bSAndy Whitcroft
49930a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
49940a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4995773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
49963705ce5bSJoe Perches						if (ERROR("SPACING",
49973705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4998b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
49993705ce5bSJoe Perches							$line_fixed = 1;
50003705ce5bSJoe Perches						}
50010a920b5bSAndy Whitcroft					}
5002773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
5003773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
50043705ce5bSJoe Perches						if (ERROR("SPACING",
50053705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5006b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50073705ce5bSJoe Perches							$line_fixed = 1;
50083705ce5bSJoe Perches						}
5009653d4876SAndy Whitcroft					}
5010773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
50113705ce5bSJoe Perches						if (ERROR("SPACING",
50123705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5013b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
50143705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
50153705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5016773647a0SAndy Whitcroft							}
5017b34c648bSJoe Perches							$line_fixed = 1;
50183705ce5bSJoe Perches						}
50193705ce5bSJoe Perches					}
50200a920b5bSAndy Whitcroft
50210a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
50229c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
50239c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
50249c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5025c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5026c2fdda0dSAndy Whitcroft					 $op eq '%')
50270a920b5bSAndy Whitcroft				{
5028d2e025f3SJoe Perches					if ($check) {
5029d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5030d2e025f3SJoe Perches							if (CHK("SPACING",
5031d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5032d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5033d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5034d2e025f3SJoe Perches								$line_fixed = 1;
5035d2e025f3SJoe Perches							}
5036d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5037d2e025f3SJoe Perches							if (CHK("SPACING",
5038d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5039d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5040d2e025f3SJoe Perches								$line_fixed = 1;
5041d2e025f3SJoe Perches							}
5042d2e025f3SJoe Perches						}
5043d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
50443705ce5bSJoe Perches						if (ERROR("SPACING",
50453705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5046b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5047b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5048b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5049b34c648bSJoe Perches							}
50503705ce5bSJoe Perches							$line_fixed = 1;
50513705ce5bSJoe Perches						}
50520a920b5bSAndy Whitcroft					}
50530a920b5bSAndy Whitcroft
50541f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
50551f65f947SAndy Whitcroft				# terminating a case value or a label.
50561f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
5057263afd39SChris Down					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
50583705ce5bSJoe Perches						if (ERROR("SPACING",
50593705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5060b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
50613705ce5bSJoe Perches							$line_fixed = 1;
50623705ce5bSJoe Perches						}
50631f65f947SAndy Whitcroft					}
50641f65f947SAndy Whitcroft
50650a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5066cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
50671f65f947SAndy Whitcroft					my $ok = 0;
50681f65f947SAndy Whitcroft
506922f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
50701f65f947SAndy Whitcroft					if (($op eq '<' &&
50711f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
50721f65f947SAndy Whitcroft					    ($op eq '>' &&
50731f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
50741f65f947SAndy Whitcroft					{
50751f65f947SAndy Whitcroft						$ok = 1;
50761f65f947SAndy Whitcroft					}
50771f65f947SAndy Whitcroft
5078e0df7e1fSJoe Perches					# for asm volatile statements
5079e0df7e1fSJoe Perches					# ignore a colon with another
5080e0df7e1fSJoe Perches					# colon immediately before or after
5081e0df7e1fSJoe Perches					if (($op eq ':') &&
5082e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5083e0df7e1fSJoe Perches						$ok = 1;
5084e0df7e1fSJoe Perches					}
5085e0df7e1fSJoe Perches
508684731623SJoe Perches					# messages are ERROR, but ?: are CHK
50871f65f947SAndy Whitcroft					if ($ok == 0) {
50880675a8fbSJean Delvare						my $msg_level = \&ERROR;
50890675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
509084731623SJoe Perches
50910675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
50923705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5093b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5094b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5095b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5096b34c648bSJoe Perches							}
50973705ce5bSJoe Perches							$line_fixed = 1;
50983705ce5bSJoe Perches						}
50990a920b5bSAndy Whitcroft					}
510022f2a2efSAndy Whitcroft				}
51014a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
51023705ce5bSJoe Perches
51033705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
51043705ce5bSJoe Perches
51053705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
51060a920b5bSAndy Whitcroft			}
51073705ce5bSJoe Perches
51083705ce5bSJoe Perches			if (($#elements % 2) == 0) {
51093705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
51103705ce5bSJoe Perches			}
51113705ce5bSJoe Perches
5112194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5113194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
51143705ce5bSJoe Perches			}
51153705ce5bSJoe Perches
51163705ce5bSJoe Perches
51170a920b5bSAndy Whitcroft		}
51180a920b5bSAndy Whitcroft
5119786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5120d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5121786b6326SJoe Perches			if (WARN("SPACING",
5122786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5123786b6326SJoe Perches			    $fix) {
5124194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5125786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5126786b6326SJoe Perches			}
5127786b6326SJoe Perches		}
5128786b6326SJoe Perches
5129f0a594c1SAndy Whitcroft# check for multiple assignments
5130f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5131000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5132000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5133f0a594c1SAndy Whitcroft		}
5134f0a594c1SAndy Whitcroft
513522f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
513622f2a2efSAndy Whitcroft## # continuation.
513722f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
513822f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
513922f2a2efSAndy Whitcroft##
514022f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5141e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
514222f2a2efSAndy Whitcroft## 			my $ln = $line;
514322f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
514422f2a2efSAndy Whitcroft## 			}
514522f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5146000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5147000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
514822f2a2efSAndy Whitcroft## 			}
514922f2a2efSAndy Whitcroft## 		}
5150f0a594c1SAndy Whitcroft
51510a920b5bSAndy Whitcroft#need space before brace following if, while, etc
51526b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
51536ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
51543705ce5bSJoe Perches			if (ERROR("SPACING",
51553705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
51563705ce5bSJoe Perches			    $fix) {
51576ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
51583705ce5bSJoe Perches			}
5159de7d4f0eSAndy Whitcroft		}
5160de7d4f0eSAndy Whitcroft
5161c4a62ef9SJoe Perches## # check for blank lines before declarations
5162c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5163c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5164c4a62ef9SJoe Perches##			WARN("SPACING",
5165c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5166c4a62ef9SJoe Perches##		}
5167c4a62ef9SJoe Perches##
5168c4a62ef9SJoe Perches
5169de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5170de7d4f0eSAndy Whitcroft# on the line
517194fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5172d5e616fcSJoe Perches			if (ERROR("SPACING",
5173d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5174d5e616fcSJoe Perches			    $fix) {
5175194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5176d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5177d5e616fcSJoe Perches			}
51780a920b5bSAndy Whitcroft		}
51790a920b5bSAndy Whitcroft
518022f2a2efSAndy Whitcroft# check spacing on square brackets
518122f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
51823705ce5bSJoe Perches			if (ERROR("SPACING",
51833705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
51843705ce5bSJoe Perches			    $fix) {
5185194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51863705ce5bSJoe Perches				    s/\[\s+/\[/;
51873705ce5bSJoe Perches			}
518822f2a2efSAndy Whitcroft		}
518922f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
51903705ce5bSJoe Perches			if (ERROR("SPACING",
51913705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
51923705ce5bSJoe Perches			    $fix) {
5193194f66fcSJoe Perches				$fixed[$fixlinenr] =~
51943705ce5bSJoe Perches				    s/\s+\]/\]/;
51953705ce5bSJoe Perches			}
519622f2a2efSAndy Whitcroft		}
519722f2a2efSAndy Whitcroft
5198c45dcabdSAndy Whitcroft# check spacing on parentheses
51999c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
52009c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
52013705ce5bSJoe Perches			if (ERROR("SPACING",
52023705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
52033705ce5bSJoe Perches			    $fix) {
5204194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52053705ce5bSJoe Perches				    s/\(\s+/\(/;
52063705ce5bSJoe Perches			}
520722f2a2efSAndy Whitcroft		}
520813214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5209c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5210c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
52113705ce5bSJoe Perches			if (ERROR("SPACING",
52123705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
52133705ce5bSJoe Perches			    $fix) {
5214194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52153705ce5bSJoe Perches				    s/\s+\)/\)/;
52163705ce5bSJoe Perches			}
521722f2a2efSAndy Whitcroft		}
521822f2a2efSAndy Whitcroft
5219e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5220e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5221e2826fd0SJoe Perches
5222e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5223ea4acbb1SJoe Perches			my $var = $1;
5224ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5225ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5226ea4acbb1SJoe Perches			    $fix) {
5227ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5228ea4acbb1SJoe Perches			}
5229ea4acbb1SJoe Perches		}
5230ea4acbb1SJoe Perches
5231ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5232ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5233ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5234ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5235ea4acbb1SJoe Perches			my $var = $2;
5236ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5237ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5238ea4acbb1SJoe Perches			    $fix) {
5239ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5240ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5241ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5242ea4acbb1SJoe Perches			}
5243e2826fd0SJoe Perches		}
5244e2826fd0SJoe Perches
524563b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5246a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5247a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
52485b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
524963b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
525063b7c73eSJoe Perches			my $if_stat = $1;
525163b7c73eSJoe Perches			my $test = substr($2, 1, -1);
525263b7c73eSJoe Perches			my $herectx;
525363b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
525463b7c73eSJoe Perches				my $match = $1;
525563b7c73eSJoe Perches				# avoid parentheses around potential macro args
525663b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
525763b7c73eSJoe Perches				if (!defined($herectx)) {
525863b7c73eSJoe Perches					$herectx = $here . "\n";
525963b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
526063b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
526163b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
526263b7c73eSJoe Perches						$herectx .=  $rl . "\n";
526363b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
526463b7c73eSJoe Perches					}
526563b7c73eSJoe Perches				}
526663b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
526763b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
526863b7c73eSJoe Perches			}
526963b7c73eSJoe Perches		}
527063b7c73eSJoe Perches
52710a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
52724a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
52730a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
52743705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
52753705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
52763705ce5bSJoe Perches			    $fix) {
5277194f66fcSJoe Perches				$fixed[$fixlinenr] =~
52783705ce5bSJoe Perches				    s/^(.)\s+/$1/;
52793705ce5bSJoe Perches			}
52800a920b5bSAndy Whitcroft		}
52810a920b5bSAndy Whitcroft
528240873abaSJoe Perches# check if a statement with a comma should be two statements like:
528340873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
528440873abaSJoe Perches#	bar = baz();
528540873abaSJoe Perches		if (defined($stat) &&
528640873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
528740873abaSJoe Perches			my $cnt = statement_rawlines($stat);
528840873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
528940873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
529040873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
529140873abaSJoe Perches		}
529240873abaSJoe Perches
52935b9553abSJoe Perches# return is not a function
5294507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5295c45dcabdSAndy Whitcroft			my $spacing = $1;
52965b57980dSJoe Perches			if ($perl_version_ok &&
52975b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
52985b9553abSJoe Perches				my $value = $1;
52995b9553abSJoe Perches				$value = deparenthesize($value);
53005b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5301000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5302000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
53035b9553abSJoe Perches				}
5304c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5305000d1cc1SJoe Perches				ERROR("SPACING",
5306000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5307c45dcabdSAndy Whitcroft			}
5308c45dcabdSAndy Whitcroft		}
5309507e5141SJoe Perches
5310b43ae21bSJoe Perches# unnecessary return in a void function
5311b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5312b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5313b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5314b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5315b43ae21bSJoe Perches		    $linenr >= 3 &&
5316b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5317b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
53189819cf25SJoe Perches			WARN("RETURN_VOID",
5319b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
53209819cf25SJoe Perches		}
53219819cf25SJoe Perches
5322189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
53235b57980dSJoe Perches		if ($perl_version_ok &&
5324189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5325189248d8SJoe Perches			my $openparens = $1;
5326189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5327189248d8SJoe Perches			my $msg = "";
5328189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5329189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5330189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5331189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5332189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5333189248d8SJoe Perches			}
5334189248d8SJoe Perches		}
5335189248d8SJoe Perches
5336c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5337c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5338c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5339c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
53405b57980dSJoe Perches		if ($perl_version_ok &&
5341c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5342c5595fa2SJoe Perches			my $lead = $1;
5343c5595fa2SJoe Perches			my $const = $2;
5344c5595fa2SJoe Perches			my $comp = $3;
5345c5595fa2SJoe Perches			my $to = $4;
5346c5595fa2SJoe Perches			my $newcomp = $comp;
5347f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5348c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5349c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5350c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5351c5595fa2SJoe Perches			    $fix) {
5352c5595fa2SJoe Perches				if ($comp eq "<") {
5353c5595fa2SJoe Perches					$newcomp = ">";
5354c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5355c5595fa2SJoe Perches					$newcomp = ">=";
5356c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5357c5595fa2SJoe Perches					$newcomp = "<";
5358c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5359c5595fa2SJoe Perches					$newcomp = "<=";
5360c5595fa2SJoe Perches				}
5361c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5362c5595fa2SJoe Perches			}
5363c5595fa2SJoe Perches		}
5364c5595fa2SJoe Perches
5365f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5366f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
536753a3c448SAndy Whitcroft			my $name = $1;
536853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
5369000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5370f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
537153a3c448SAndy Whitcroft			}
537253a3c448SAndy Whitcroft		}
5373c45dcabdSAndy Whitcroft
53740a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
53754a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
53763705ce5bSJoe Perches			if (ERROR("SPACING",
53773705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
53783705ce5bSJoe Perches			    $fix) {
5379194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53803705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
53813705ce5bSJoe Perches			}
53820a920b5bSAndy Whitcroft		}
53830a920b5bSAndy Whitcroft
5384f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5385f5fe35ddSAndy Whitcroft# statements after the conditional.
5386170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
53873e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
53883e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
53893e469cdcSAndy Whitcroft					if (!defined $stat);
5390170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5391170d3a22SAndy Whitcroft						$remain_next, $off_next);
5392170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5393170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5394170d3a22SAndy Whitcroft
5395170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5396170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5397170d3a22SAndy Whitcroft				# then count those as offsets.
5398170d3a22SAndy Whitcroft				my ($whitespace) =
5399170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5400170d3a22SAndy Whitcroft				my $offset =
5401170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5402170d3a22SAndy Whitcroft
5403170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5404170d3a22SAndy Whitcroft								$offset} = 1;
5405170d3a22SAndy Whitcroft			}
5406170d3a22SAndy Whitcroft		}
5407170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5408c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5409170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5410171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
54118905a67cSAndy Whitcroft
5412b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
541365b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
541465b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
541565b64b3bSJoe Perches				    $fix && $perl_version_ok) {
541665b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
541765b64b3bSJoe Perches						my $space = $1;
541865b64b3bSJoe Perches						my $not = $2;
541965b64b3bSJoe Perches						my $statement = $3;
542065b64b3bSJoe Perches						my $assigned = $4;
542165b64b3bSJoe Perches						my $test = $8;
542265b64b3bSJoe Perches						my $against = $9;
542365b64b3bSJoe Perches						my $brace = $15;
542465b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
542565b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
542665b64b3bSJoe Perches						my $newline = "${space}if (";
542765b64b3bSJoe Perches						$newline .= '!' if defined($not);
542865b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
542965b64b3bSJoe Perches						$newline .= "$assigned";
543065b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
543165b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
543265b64b3bSJoe Perches						$newline .= ')';
543365b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
543465b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
543565b64b3bSJoe Perches					}
543665b64b3bSJoe Perches				}
54378905a67cSAndy Whitcroft			}
54388905a67cSAndy Whitcroft
54398905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
54408905a67cSAndy Whitcroft			# conditional.
5441773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
54428905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
544313214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
544453210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
544553210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5446773647a0SAndy Whitcroft			{
5447bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5448bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5449bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
545042bdf74cSHidetoshi Seto				my $stat_real = '';
5451bb44ad39SAndy Whitcroft
545242bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
545342bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5454bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5455bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5456bb44ad39SAndy Whitcroft				}
5457bb44ad39SAndy Whitcroft
5458000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5459000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
54608905a67cSAndy Whitcroft			}
54618905a67cSAndy Whitcroft		}
54628905a67cSAndy Whitcroft
546313214adfSAndy Whitcroft# Check for bitwise tests written as boolean
546413214adfSAndy Whitcroft		if ($line =~ /
546513214adfSAndy Whitcroft			(?:
546613214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
546713214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
546813214adfSAndy Whitcroft				(?:\&\&|\|\|)
546913214adfSAndy Whitcroft			|
547013214adfSAndy Whitcroft				(?:\&\&|\|\|)
547113214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
547213214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
547313214adfSAndy Whitcroft			)/x)
547413214adfSAndy Whitcroft		{
5475000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5476000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
547713214adfSAndy Whitcroft		}
547813214adfSAndy Whitcroft
54798905a67cSAndy Whitcroft# if and else should not have general statements after it
548013214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
548113214adfSAndy Whitcroft			my $s = $1;
548213214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
548313214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5484000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5485000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
54860a920b5bSAndy Whitcroft			}
548713214adfSAndy Whitcroft		}
548839667782SAndy Whitcroft# if should not continue a brace
548939667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5490000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5491048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
549239667782SAndy Whitcroft				$herecurr);
549339667782SAndy Whitcroft		}
5494a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5495a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5496a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
54973fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5498a1080bf8SAndy Whitcroft			\s*return\s+
5499a1080bf8SAndy Whitcroft		    )/xg)
5500a1080bf8SAndy Whitcroft		{
5501000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5502000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5503a1080bf8SAndy Whitcroft		}
55040a920b5bSAndy Whitcroft
55050a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
55060a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
55078b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
55080a920b5bSAndy Whitcroft		    $previndent == $indent) {
55098b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
55108b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
55118b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
55128b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
55138b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
55148b8856f4SJoe Perches				my $fixedline = $prevrawline;
55158b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
55168b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
55178b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55188b8856f4SJoe Perches				}
55198b8856f4SJoe Perches				$fixedline = $rawline;
55208b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
55218b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
55228b8856f4SJoe Perches			}
55230a920b5bSAndy Whitcroft		}
55240a920b5bSAndy Whitcroft
55258b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5526c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5527c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5528c2fdda0dSAndy Whitcroft
5529c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5530c2fdda0dSAndy Whitcroft			# conditional.
5531773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5532c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5533c2fdda0dSAndy Whitcroft
5534c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
55358b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
55368b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
55378b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
55388b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
55398b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
55408b8856f4SJoe Perches					my $fixedline = $prevrawline;
55418b8856f4SJoe Perches					my $trailing = $rawline;
55428b8856f4SJoe Perches					$trailing =~ s/^\+//;
55438b8856f4SJoe Perches					$trailing = trim($trailing);
55448b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
55458b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55468b8856f4SJoe Perches				}
5547c2fdda0dSAndy Whitcroft			}
5548c2fdda0dSAndy Whitcroft		}
5549c2fdda0dSAndy Whitcroft
555095e2c602SJoe Perches#Specific variable tests
5551323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5552323c1260SJoe Perches			my $var = $1;
555395e2c602SJoe Perches
555495e2c602SJoe Perches#CamelCase
5555807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5556be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
55574104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
55584104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
555922735ce8SJoe Perches#Ignore Page<foo> variants
5560807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5561d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5562d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5563d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5564f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5565f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
55667e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
55677e781f67SJoe Perches					my $word = $1;
55687e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5569d8b07710SJoe Perches					if ($check) {
5570d8b07710SJoe Perches						seed_camelcase_includes();
5571d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5572d8b07710SJoe Perches							seed_camelcase_file($realfile);
5573d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5574d8b07710SJoe Perches						}
5575d8b07710SJoe Perches					}
55767e781f67SJoe Perches					if (!defined $camelcase{$word}) {
55777e781f67SJoe Perches						$camelcase{$word} = 1;
5578be79794bSJoe Perches						CHK("CAMELCASE",
55797e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
55807e781f67SJoe Perches					}
5581323c1260SJoe Perches				}
5582323c1260SJoe Perches			}
55833445686aSJoe Perches		}
55840a920b5bSAndy Whitcroft
55850a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5586d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5587d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5588d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5589d5e616fcSJoe Perches			    $fix) {
5590194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5591d5e616fcSJoe Perches			}
55920a920b5bSAndy Whitcroft		}
55930a920b5bSAndy Whitcroft
55940e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
55950e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5596c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5597e09dec48SAndy Whitcroft			my $file = "$1.h";
5598e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5599e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5600e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
56017840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5602c45dcabdSAndy Whitcroft			{
56030e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
56040e212e0aSFabian Frederick				if ($asminclude > 0) {
5605e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5606000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5607000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5608e09dec48SAndy Whitcroft					} else {
5609000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5610000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5611e09dec48SAndy Whitcroft					}
56120a920b5bSAndy Whitcroft				}
56130a920b5bSAndy Whitcroft			}
56140e212e0aSFabian Frederick		}
56150a920b5bSAndy Whitcroft
5616653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5617653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5618cf655043SAndy Whitcroft# in a known good container
5619b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5620b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5621d8aaf121SAndy Whitcroft			my $ln = $linenr;
5622d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5623c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5624c45dcabdSAndy Whitcroft			my $ctx = '';
562508a2843eSJoe Perches			my $has_flow_statement = 0;
562608a2843eSJoe Perches			my $has_arg_concat = 0;
5627c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5628f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5629f74bd194SAndy Whitcroft			$ctx = $dstat;
5630c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5631a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5632c45dcabdSAndy Whitcroft
563308a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
563462e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
563508a2843eSJoe Perches
5636f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5637f59b64bfSJoe Perches			my $define_args = $1;
5638f59b64bfSJoe Perches			my $define_stmt = $dstat;
5639f59b64bfSJoe Perches			my @def_args = ();
5640f59b64bfSJoe Perches
5641f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5642f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5643f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
56448c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5645f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5646f59b64bfSJoe Perches			}
5647f59b64bfSJoe Perches
5648292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5649c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5650c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5651c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5652c45dcabdSAndy Whitcroft
5653c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
56542e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
56552e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
56562e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5657bf30d6edSAndy Whitcroft			{
5658c45dcabdSAndy Whitcroft			}
5659c45dcabdSAndy Whitcroft
5660342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
566133acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
566233acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5663e45bab8eSAndy Whitcroft			{
5664e45bab8eSAndy Whitcroft			}
5665e45bab8eSAndy Whitcroft
566642e15293SJoe Perches			# Make asm volatile uses seem like a generic function
566742e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
566842e15293SJoe Perches
5669c45dcabdSAndy Whitcroft			my $exceptions = qr{
5670c45dcabdSAndy Whitcroft				$Declare|
5671c45dcabdSAndy Whitcroft				module_param_named|
5672a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5673c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5674c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5675383099fdSAndy Whitcroft				__typeof__\(|
567622fd2d3eSStefani Seibold				union|
567722fd2d3eSStefani Seibold				struct|
5678ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
56796b10df42SVladimir Zapolskiy				^\"|\"$|
56806b10df42SVladimir Zapolskiy				^\[
5681c45dcabdSAndy Whitcroft			}x;
56825eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5683f59b64bfSJoe Perches
5684f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5685f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5686e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5687f59b64bfSJoe Perches
5688f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5689f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5690f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
56913cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5692356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5693f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5694f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5695e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
569672f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
56972e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5698f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5699f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5700f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
57014e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5702f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5703c45dcabdSAndy Whitcroft			{
5704e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5705e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5706e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5707e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5708f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5709f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5710f74bd194SAndy Whitcroft				} else {
5711000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5712388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5713d8aaf121SAndy Whitcroft				}
5714f59b64bfSJoe Perches
5715f59b64bfSJoe Perches			}
57165207649bSJoe Perches
57175207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
57185207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
57195207649bSJoe Perches			my $first = 1;
57205207649bSJoe Perches			$define_stmt = "";
57215207649bSJoe Perches			foreach my $l (@stmt_array) {
57225207649bSJoe Perches				$l =~ s/\\$//;
57235207649bSJoe Perches				if ($first) {
57245207649bSJoe Perches					$define_stmt = $l;
57255207649bSJoe Perches					$first = 0;
57265207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
57275207649bSJoe Perches					$define_stmt .= substr($l, 1);
57285207649bSJoe Perches				}
57295207649bSJoe Perches			}
57305207649bSJoe Perches			$define_stmt =~ s/$;//g;
57315207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
57325207649bSJoe Perches			$define_stmt = trim($define_stmt);
57335207649bSJoe Perches
5734f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5735f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5736f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
57379192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
57387fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
57396dba824eSBrendan Jackman				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
57407fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
57417fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5742d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5743f59b64bfSJoe Perches				if ($use_cnt > 1) {
5744f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5745f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5746f59b64bfSJoe Perches				    }
57479192d41aSJoe Perches# check if any macro arguments may have other precedence issues
57487fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
57499192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
57509192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
57519192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
57529192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
57539192d41aSJoe Perches				}
57540a920b5bSAndy Whitcroft			}
57555023d347SJoe Perches
575608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
575708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
575808a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
575908a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5760e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
576108a2843eSJoe Perches
576208a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
576308a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
576408a2843eSJoe Perches			}
576508a2843eSJoe Perches
5766481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
57675023d347SJoe Perches
57685023d347SJoe Perches		} else {
57695023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5770481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5771481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
57725023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
57735023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
57745023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
57755023d347SJoe Perches			}
5776653d4876SAndy Whitcroft		}
57770a920b5bSAndy Whitcroft
5778b13edf7fSJoe Perches# do {} while (0) macro tests:
5779b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5780b13edf7fSJoe Perches# macro should not end with a semicolon
57815b57980dSJoe Perches		if ($perl_version_ok &&
5782b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5783b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5784b13edf7fSJoe Perches			my $ln = $linenr;
5785b13edf7fSJoe Perches			my $cnt = $realcnt;
5786b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5787b13edf7fSJoe Perches			my $ctx = '';
5788b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5789b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5790b13edf7fSJoe Perches			$ctx = $dstat;
5791b13edf7fSJoe Perches
5792b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
57931b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5794b13edf7fSJoe Perches
5795b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5796b13edf7fSJoe Perches				my $stmts = $2;
5797b13edf7fSJoe Perches				my $semis = $3;
5798b13edf7fSJoe Perches
5799b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5800b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5801e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5802b13edf7fSJoe Perches
5803ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5804ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5805b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5806b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5807b13edf7fSJoe Perches				}
5808b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5809b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5810b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5811b13edf7fSJoe Perches				}
5812f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5813f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5814f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5815e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5816f5ef95b1SJoe Perches
5817f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5818f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5819b13edf7fSJoe Perches			}
5820b13edf7fSJoe Perches		}
5821b13edf7fSJoe Perches
5822f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
582313214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
582413214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5825cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
582613214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5827cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5828cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5829aad4f614SJoe Perches				my @allowed = ();
5830aad4f614SJoe Perches				my $allow = 0;
583113214adfSAndy Whitcroft				my $seen = 0;
5832773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5833cf655043SAndy Whitcroft				my $ln = $linenr - 1;
583413214adfSAndy Whitcroft				for my $chunk (@chunks) {
583513214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
583613214adfSAndy Whitcroft
5837773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5838773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5839773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5840773647a0SAndy Whitcroft
5841aad4f614SJoe Perches					$allowed[$allow] = 0;
5842773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5843773647a0SAndy Whitcroft
5844773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5845773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5846773647a0SAndy Whitcroft
5847773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5848cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5849cf655043SAndy Whitcroft
5850773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
585113214adfSAndy Whitcroft
585213214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
585313214adfSAndy Whitcroft
5854aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5855cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5856cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5857aad4f614SJoe Perches						$allowed[$allow] = 1;
585813214adfSAndy Whitcroft					}
585913214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5860cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5861aad4f614SJoe Perches						$allowed[$allow] = 1;
586213214adfSAndy Whitcroft					}
5863cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5864cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5865aad4f614SJoe Perches						$allowed[$allow] = 1;
586613214adfSAndy Whitcroft					}
5867aad4f614SJoe Perches					$allow++;
586813214adfSAndy Whitcroft				}
5869aad4f614SJoe Perches				if ($seen) {
5870aad4f614SJoe Perches					my $sum_allowed = 0;
5871aad4f614SJoe Perches					foreach (@allowed) {
5872aad4f614SJoe Perches						$sum_allowed += $_;
5873aad4f614SJoe Perches					}
5874aad4f614SJoe Perches					if ($sum_allowed == 0) {
5875000d1cc1SJoe Perches						WARN("BRACES",
5876000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5877aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5878aad4f614SJoe Perches						 $seen != $allow) {
5879aad4f614SJoe Perches						CHK("BRACES",
5880aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5881aad4f614SJoe Perches					}
588213214adfSAndy Whitcroft				}
588313214adfSAndy Whitcroft			}
588413214adfSAndy Whitcroft		}
5885773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
588613214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5887cf655043SAndy Whitcroft			my $allowed = 0;
5888f0a594c1SAndy Whitcroft
5889cf655043SAndy Whitcroft			# Check the pre-context.
5890cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5891cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5892cf655043SAndy Whitcroft				$allowed = 1;
5893f0a594c1SAndy Whitcroft			}
5894773647a0SAndy Whitcroft
5895773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5896773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5897773647a0SAndy Whitcroft
5898cf655043SAndy Whitcroft			# Check the condition.
5899cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5900773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5901cf655043SAndy Whitcroft			if (defined $cond) {
5902773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5903cf655043SAndy Whitcroft			}
5904cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5905cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5906cf655043SAndy Whitcroft				$allowed = 1;
5907cf655043SAndy Whitcroft			}
5908cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5909cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5910cf655043SAndy Whitcroft				$allowed = 1;
5911cf655043SAndy Whitcroft			}
5912cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5913cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5914cf655043SAndy Whitcroft				$allowed = 1;
5915cf655043SAndy Whitcroft			}
5916cf655043SAndy Whitcroft			# Check the post-context.
5917cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5918cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5919cf655043SAndy Whitcroft				if (defined $cond) {
5920773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5921cf655043SAndy Whitcroft				}
5922cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5923cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5924cf655043SAndy Whitcroft					$allowed = 1;
5925cf655043SAndy Whitcroft				}
5926cf655043SAndy Whitcroft			}
5927cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5928f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5929e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5930cf655043SAndy Whitcroft
5931000d1cc1SJoe Perches				WARN("BRACES",
5932000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5933f0a594c1SAndy Whitcroft			}
5934f0a594c1SAndy Whitcroft		}
5935f0a594c1SAndy Whitcroft
5936e4c5babdSJoe Perches# check for single line unbalanced braces
593795330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
593895330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5939e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5940e4c5babdSJoe Perches		}
5941e4c5babdSJoe Perches
59420979ae66SJoe Perches# check for unnecessary blank lines around braces
594377b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5944f8e58219SJoe Perches			if (CHK("BRACES",
5945f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5946f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5947f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5948f8e58219SJoe Perches			}
59490979ae66SJoe Perches		}
595077b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5951f8e58219SJoe Perches			if (CHK("BRACES",
5952f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5953f8e58219SJoe Perches			    $fix) {
5954f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5955f8e58219SJoe Perches			}
59560979ae66SJoe Perches		}
59570979ae66SJoe Perches
59584a0df2efSAndy Whitcroft# no volatiles please
59596c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
59606c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5961000d1cc1SJoe Perches			WARN("VOLATILE",
59628c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
59634a0df2efSAndy Whitcroft		}
59644a0df2efSAndy Whitcroft
59655e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
59665e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
59675e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
59685e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
596933acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
59705e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
59715e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
59725e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
59735e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
59745e4f6ba5SJoe Perches				     $fix &&
59755e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
59765e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
59775e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
59785e4f6ba5SJoe Perches				my $comma_close = "";
59795e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
59805e4f6ba5SJoe Perches					$comma_close = $1;
59815e4f6ba5SJoe Perches				}
59825e4f6ba5SJoe Perches
59835e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
59845e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
59855e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
59865e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
59875e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
59885e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
59895e4f6ba5SJoe Perches				$fixedline = $rawline;
59905e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
59915e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
59925e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
59935e4f6ba5SJoe Perches				}
59945e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
59955e4f6ba5SJoe Perches			}
59965e4f6ba5SJoe Perches		}
59975e4f6ba5SJoe Perches
59985e4f6ba5SJoe Perches# check for missing a space in a string concatenation
59995e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
60005e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
60015e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
60025e4f6ba5SJoe Perches		}
60035e4f6ba5SJoe Perches
600477cb8546SJoe Perches# check for an embedded function name in a string when the function is known
6005e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
6006e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
6007e4b7d309SJoe Perches# function declarations
600877cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
600977cb8546SJoe Perches		    defined($context_function) &&
6010e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6011e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
601277cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
6013e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
601477cb8546SJoe Perches		}
601577cb8546SJoe Perches
6016adb2da82SJoe Perches# check for unnecessary function tracing like uses
6017adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6018adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6019adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6020adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6021adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6022adb2da82SJoe Perches			    $fix) {
6023adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6024adb2da82SJoe Perches			}
6025adb2da82SJoe Perches		}
6026adb2da82SJoe Perches
60275e4f6ba5SJoe Perches# check for spaces before a quoted newline
60285e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
60295e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
60305e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
60315e4f6ba5SJoe Perches			    $fix) {
60325e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
60335e4f6ba5SJoe Perches			}
60345e4f6ba5SJoe Perches
60355e4f6ba5SJoe Perches		}
60365e4f6ba5SJoe Perches
6037f17dba4fSJoe Perches# concatenated string without spaces between elements
603879682c0cSJoe Perches		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
603979682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
604079682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
604179682c0cSJoe Perches			    $fix) {
604279682c0cSJoe Perches				while ($line =~ /($String)/g) {
604379682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
604479682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
604579682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
604679682c0cSJoe Perches				}
604779682c0cSJoe Perches			}
6048f17dba4fSJoe Perches		}
6049f17dba4fSJoe Perches
605090ad30e5SJoe Perches# uncoalesced string fragments
605133acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
605279682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
605379682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
605479682c0cSJoe Perches			    $fix) {
605579682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
605679682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
605779682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
605879682c0cSJoe Perches				}
605979682c0cSJoe Perches			}
606090ad30e5SJoe Perches		}
606190ad30e5SJoe Perches
6062522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6063522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6064522b837cSAlexey Dobriyan		my $show_Z = 1;
60655e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6066522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
60675e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6068522b837cSAlexey Dobriyan			# check for %L
6069522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
60705e4f6ba5SJoe Perches				WARN("PRINTF_L",
6071522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6072522b837cSAlexey Dobriyan				$show_L = 0;
60735e4f6ba5SJoe Perches			}
6074522b837cSAlexey Dobriyan			# check for %Z
6075522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6076522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6077522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6078522b837cSAlexey Dobriyan				$show_Z = 0;
6079522b837cSAlexey Dobriyan			}
6080522b837cSAlexey Dobriyan			# check for 0x<decimal>
6081522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6082522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
60836e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
60846e300757SJoe Perches			}
60855e4f6ba5SJoe Perches		}
60865e4f6ba5SJoe Perches
60875e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
60883f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
60895e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
60905e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
60915e4f6ba5SJoe Perches		}
60925e4f6ba5SJoe Perches
609300df344fSAndy Whitcroft# warn about #if 0
6094c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
609560f89010SPrakruthi Deepak Heragu			WARN("IF_0",
609660f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
609760f89010SPrakruthi Deepak Heragu		}
609860f89010SPrakruthi Deepak Heragu
609960f89010SPrakruthi Deepak Heragu# warn about #if 1
610060f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
610160f89010SPrakruthi Deepak Heragu			WARN("IF_1",
610260f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
61034a0df2efSAndy Whitcroft		}
61044a0df2efSAndy Whitcroft
610503df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
610603df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6107100425deSJoe Perches			my $tested = quotemeta($1);
6108100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6109100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6110100425deSJoe Perches				my $func = $1;
6111100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6112100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6113100425deSJoe Perches				    $fix) {
6114100425deSJoe Perches					my $do_fix = 1;
6115100425deSJoe Perches					my $leading_tabs = "";
6116100425deSJoe Perches					my $new_leading_tabs = "";
6117100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6118100425deSJoe Perches						$leading_tabs = $1;
6119100425deSJoe Perches					} else {
6120100425deSJoe Perches						$do_fix = 0;
6121100425deSJoe Perches					}
6122100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6123100425deSJoe Perches						$new_leading_tabs = $1;
6124100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6125100425deSJoe Perches							$do_fix = 0;
6126100425deSJoe Perches						}
6127100425deSJoe Perches					} else {
6128100425deSJoe Perches						$do_fix = 0;
6129100425deSJoe Perches					}
6130100425deSJoe Perches					if ($do_fix) {
6131100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6132100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6133100425deSJoe Perches					}
6134100425deSJoe Perches				}
61354c432a8fSGreg Kroah-Hartman			}
61364c432a8fSGreg Kroah-Hartman		}
6137f0a594c1SAndy Whitcroft
6138ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6139ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6140ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6141ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6142ebfdc409SJoe Perches		    $linenr > 3) {
6143ebfdc409SJoe Perches			my $testval = $2;
6144ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6145ebfdc409SJoe Perches
6146ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6147ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6148ebfdc409SJoe Perches
6149e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6150e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6151ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6152ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6153ebfdc409SJoe Perches			}
6154ebfdc409SJoe Perches		}
6155ebfdc409SJoe Perches
6156f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6157dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6158f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6159f78d98f6SJoe Perches			my $level = $1;
6160f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6161f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6162f78d98f6SJoe Perches			    $fix) {
6163f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6164f78d98f6SJoe Perches			}
6165f78d98f6SJoe Perches		}
6166f78d98f6SJoe Perches
616745c55e92SJoe Perches# check for logging continuations
616845c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
616945c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
617045c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
617145c55e92SJoe Perches		}
617245c55e92SJoe Perches
617370eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
617470eb2275SDwaipayan Ray		if (defined $stat &&
617570eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
617670eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
617770eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
617870eb2275SDwaipayan Ray			$lc = $lc + $linenr;
617970eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
618070eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
618170eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
618270eb2275SDwaipayan Ray				my $pspec = $1;
618370eb2275SDwaipayan Ray				my $h = $2;
618470eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
618570eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
618670eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
618770eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
618870eb2275SDwaipayan Ray					my $nspec = $pspec;
618970eb2275SDwaipayan Ray					$nspec =~ s/h//g;
619070eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
619170eb2275SDwaipayan Ray				}
619270eb2275SDwaipayan Ray			}
619370eb2275SDwaipayan Ray		}
619470eb2275SDwaipayan Ray
6195abb08a53SJoe Perches# check for mask then right shift without a parentheses
61965b57980dSJoe Perches		if ($perl_version_ok &&
6197abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6198abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6199abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6200abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6201abb08a53SJoe Perches		}
6202abb08a53SJoe Perches
6203b75ac618SJoe Perches# check for pointer comparisons to NULL
62045b57980dSJoe Perches		if ($perl_version_ok) {
6205b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6206b75ac618SJoe Perches				my $val = $1;
6207b75ac618SJoe Perches				my $equal = "!";
6208b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6209b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6210b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6211b75ac618SJoe Perches					    $fix) {
6212b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6213b75ac618SJoe Perches				}
6214b75ac618SJoe Perches			}
6215b75ac618SJoe Perches		}
6216b75ac618SJoe Perches
62178716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
62188716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
62198716de38SJoe Perches			my $attr = $1;
62208716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
62218716de38SJoe Perches				my $ptr = $1;
62228716de38SJoe Perches				my $var = $2;
62238716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
62248716de38SJoe Perches				      ERROR("MISPLACED_INIT",
62258716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
62268716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
62278716de38SJoe Perches				      WARN("MISPLACED_INIT",
62288716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
62298716de38SJoe Perches				    $fix) {
6230194f66fcSJoe 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;
62318716de38SJoe Perches				}
62328716de38SJoe Perches			}
62338716de38SJoe Perches		}
62348716de38SJoe Perches
6235e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6236e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6237e970b884SJoe Perches			my $attr = $1;
6238e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6239e970b884SJoe Perches			my $attr_prefix = $1;
6240e970b884SJoe Perches			my $attr_type = $2;
6241e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6242e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6243e970b884SJoe Perches			    $fix) {
6244194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6245e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6246e970b884SJoe Perches			}
6247e970b884SJoe Perches		}
6248e970b884SJoe Perches
6249e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6250e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6251e970b884SJoe Perches			my $attr = $1;
6252e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6253e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6254e970b884SJoe Perches			    $fix) {
6255194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6256e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6257e970b884SJoe Perches				$lead = rtrim($1);
6258e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6259e970b884SJoe Perches				$lead = "${lead}const ";
6260194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6261e970b884SJoe Perches			}
6262e970b884SJoe Perches		}
6263e970b884SJoe Perches
6264c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6265c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6266c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6267c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6268c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6269c17893c7SJoe Perches			    $fix) {
6270c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6271c17893c7SJoe Perches			}
6272c17893c7SJoe Perches		}
6273c17893c7SJoe Perches
6274fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6275fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6276fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6277fbdb8138SJoe Perches			my $constant_func = $1;
6278fbdb8138SJoe Perches			my $func = $constant_func;
6279fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6280fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6281fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6282fbdb8138SJoe Perches			    $fix) {
6283194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6284fbdb8138SJoe Perches			}
6285fbdb8138SJoe Perches		}
6286fbdb8138SJoe Perches
62871a15a250SPatrick Pannuto# prefer usleep_range over udelay
628837581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
628943c1d77cSJoe Perches			my $delay = $1;
62901a15a250SPatrick Pannuto			# ignore udelay's < 10, however
629143c1d77cSJoe Perches			if (! ($delay < 10) ) {
6292000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6293458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
629443c1d77cSJoe Perches			}
629543c1d77cSJoe Perches			if ($delay > 2000) {
629643c1d77cSJoe Perches				WARN("LONG_UDELAY",
629743c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
62981a15a250SPatrick Pannuto			}
62991a15a250SPatrick Pannuto		}
63001a15a250SPatrick Pannuto
630109ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
630209ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
630309ef8725SPatrick Pannuto			if ($1 < 20) {
6304000d1cc1SJoe Perches				WARN("MSLEEP",
6305458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
630609ef8725SPatrick Pannuto			}
630709ef8725SPatrick Pannuto		}
630809ef8725SPatrick Pannuto
630936ec1939SJoe Perches# check for comparisons of jiffies
631036ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
631136ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
631236ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
631336ec1939SJoe Perches		}
631436ec1939SJoe Perches
63159d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
63169d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
63179d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
63189d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
63199d7a34a5SJoe Perches		}
63209d7a34a5SJoe Perches
632100df344fSAndy Whitcroft# warn about #ifdefs in C files
6322c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
632300df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
632400df344fSAndy Whitcroft#			print "$herecurr";
632500df344fSAndy Whitcroft#			$clean = 0;
632600df344fSAndy Whitcroft#		}
632700df344fSAndy Whitcroft
632822f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6329c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
63303705ce5bSJoe Perches			if (ERROR("SPACING",
63313705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
63323705ce5bSJoe Perches			    $fix) {
6333194f66fcSJoe Perches				$fixed[$fixlinenr] =~
63343705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
63353705ce5bSJoe Perches			}
63363705ce5bSJoe Perches
633722f2a2efSAndy Whitcroft		}
633822f2a2efSAndy Whitcroft
63394a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6340171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6341171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
63424a0df2efSAndy Whitcroft			my $which = $1;
63434a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6344000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6345000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
63464a0df2efSAndy Whitcroft			}
63474a0df2efSAndy Whitcroft		}
63484a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6349402c2553SMichael S. Tsirkin
6350402c2553SMichael S. Tsirkin		my $barriers = qr{
6351402c2553SMichael S. Tsirkin			mb|
6352402c2553SMichael S. Tsirkin			rmb|
6353ad83ec6cSWill Deacon			wmb
6354402c2553SMichael S. Tsirkin		}x;
6355402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6356402c2553SMichael S. Tsirkin			mb__before_atomic|
6357402c2553SMichael S. Tsirkin			mb__after_atomic|
6358402c2553SMichael S. Tsirkin			store_release|
6359402c2553SMichael S. Tsirkin			load_acquire|
6360402c2553SMichael S. Tsirkin			store_mb|
6361402c2553SMichael S. Tsirkin			(?:$barriers)
6362402c2553SMichael S. Tsirkin		}x;
6363402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6364402c2553SMichael S. Tsirkin			(?:$barriers)|
636543e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
636643e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6367402c2553SMichael S. Tsirkin		}x;
6368402c2553SMichael S. Tsirkin
6369402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
63704a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6371c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6372000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
63734a0df2efSAndy Whitcroft			}
63744a0df2efSAndy Whitcroft		}
63753ad81779SPaul E. McKenney
6376f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6377f4073b0fSMichael S. Tsirkin
6378f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6379f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6380f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6381f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6382f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6383f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6384f4073b0fSMichael S. Tsirkin		}
6385f4073b0fSMichael S. Tsirkin
6386cb426e99SJoe Perches# check for waitqueue_active without a comment.
6387cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6388cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6389cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6390cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6391cb426e99SJoe Perches			}
6392cb426e99SJoe Perches		}
63933ad81779SPaul E. McKenney
63945099a722SMarco Elver# check for data_race without a comment.
63955099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
63965099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
63975099a722SMarco Elver				WARN("DATA_RACE",
63985099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
63995099a722SMarco Elver			}
64005099a722SMarco Elver		}
64015099a722SMarco Elver
64024a0df2efSAndy Whitcroft# check of hardware specific defines
6403c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6404000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6405000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
64060a920b5bSAndy Whitcroft		}
6407653d4876SAndy Whitcroft
6408596ed45bSJoe Perches# check that the storage class is not after a type
6409596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6410000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6411596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6412596ed45bSJoe Perches		}
6413596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6414596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6415596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6416596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6417596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6418596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6419596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6420d4977c78STobias Klauser		}
6421d4977c78STobias Klauser
6422de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6423de7d4f0eSAndy Whitcroft# storage class and type.
64249c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
64259c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6426000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6427000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6428de7d4f0eSAndy Whitcroft		}
6429de7d4f0eSAndy Whitcroft
64308905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
64312b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
64322b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6433d5e616fcSJoe Perches			if (WARN("INLINE",
6434d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6435d5e616fcSJoe Perches			    $fix) {
6436194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6437d5e616fcSJoe Perches
6438d5e616fcSJoe Perches			}
64398905a67cSAndy Whitcroft		}
64408905a67cSAndy Whitcroft
64417ebe1d17SDwaipayan Ray# Check for compiler attributes
64422b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
64437ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
64447ebe1d17SDwaipayan Ray			my $attr = $1;
64457ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
64467ebe1d17SDwaipayan Ray
64477ebe1d17SDwaipayan Ray			my %attr_list = (
64480830aab0SJoe Perches				"alias"				=> "__alias",
64497ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
64507ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
64517ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
64527ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
64537ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
64547ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
64557ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
64567ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
64577ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
64587ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
64597ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
64607ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
64617ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
64627ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
64637ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
64647ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
64657ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
64667ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
64677ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6468339f29d9SJoe Perches				"section"			=> "__section",
64690830aab0SJoe Perches				"used"				=> "__used",
64700830aab0SJoe Perches				"weak"				=> "__weak"
64717ebe1d17SDwaipayan Ray			);
64727ebe1d17SDwaipayan Ray
64737ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6474339f29d9SJoe Perches				my $orig_attr = $1;
64757ebe1d17SDwaipayan Ray				my $params = '';
64767ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6477339f29d9SJoe Perches				my $curr_attr = $orig_attr;
64787ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
64797ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6480339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
64817ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
64827ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6483339f29d9SJoe Perches						$new = "__$1\($2";
64847ebe1d17SDwaipayan Ray					} else {
6485339f29d9SJoe Perches						$new = "$new$params";
64867ebe1d17SDwaipayan Ray					}
64877ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6488339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
64897ebe1d17SDwaipayan Ray					    $fix) {
6490339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6491339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6492339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6493339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6494339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
64957ebe1d17SDwaipayan Ray					}
649639b7e287SJoe Perches				}
6497462811d9SJoe Perches			}
6498462811d9SJoe Perches
64997ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
65007ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
65017ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
65027ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6503d5e616fcSJoe Perches			}
65046061d949SJoe Perches		}
65056061d949SJoe Perches
6506619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
65075b57980dSJoe Perches		if ($perl_version_ok &&
6508619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6509619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6510619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6511619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6512619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6513619a908aSJoe Perches		}
6514619a908aSJoe Perches
6515fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6516e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6517fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6518e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6519e6176fa4SJoe Perches			my $type = $1;
6520e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6521e6176fa4SJoe Perches				$type = $1;
6522e6176fa4SJoe Perches				my $kernel_type = 'u';
6523e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6524e6176fa4SJoe Perches				$type =~ /(\d+)/;
6525e6176fa4SJoe Perches				$kernel_type .= $1;
6526e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6527e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6528e6176fa4SJoe Perches				    $fix) {
6529e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6530e6176fa4SJoe Perches				}
6531e6176fa4SJoe Perches			}
6532e6176fa4SJoe Perches		}
6533e6176fa4SJoe Perches
6534938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6535938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6536938224b5SJoe Perches			my $cast = $1;
6537938224b5SJoe Perches			my $const = $2;
6538938224b5SJoe Perches			my $suffix = "";
6539938224b5SJoe Perches			my $newconst = $const;
6540938224b5SJoe Perches			$newconst =~ s/${Int_type}$//;
6541938224b5SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6542938224b5SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6543938224b5SJoe Perches			    $suffix .= 'LL';
6544938224b5SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6545938224b5SJoe Perches			    $suffix .= 'L';
6546938224b5SJoe Perches			}
65470972b8bfSJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
65480972b8bfSJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
65490972b8bfSJoe Perches			    $fix) {
6550938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6551938224b5SJoe Perches			}
6552938224b5SJoe Perches		}
6553938224b5SJoe Perches
65548f53a9b8SJoe Perches# check for sizeof(&)
65558f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6556000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6557000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
65588f53a9b8SJoe Perches		}
65598f53a9b8SJoe Perches
656066c80b60SJoe Perches# check for sizeof without parenthesis
656166c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6562d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6563d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6564d5e616fcSJoe Perches			    $fix) {
6565194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6566d5e616fcSJoe Perches			}
656766c80b60SJoe Perches		}
656866c80b60SJoe Perches
656988982feaSJoe Perches# check for struct spinlock declarations
657088982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
657188982feaSJoe Perches			WARN("USE_SPINLOCK_T",
657288982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
657388982feaSJoe Perches		}
657488982feaSJoe Perches
6575a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
657606668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6577a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6578caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6579caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6580d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6581d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6582d5e616fcSJoe Perches				    $fix) {
6583194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6584d5e616fcSJoe Perches				}
6585a6962d72SJoe Perches			}
6586a6962d72SJoe Perches		}
6587a6962d72SJoe Perches
65880b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
65895b57980dSJoe Perches		if ($perl_version_ok &&
65900b523769SJoe Perches		    defined $stat &&
65910b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
65920b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6593e3c6bc95STobin C. Harding			my $stat_real;
6594e3c6bc95STobin C. Harding
65950b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
65960b523769SJoe Perches			$lc = $lc + $linenr;
65970b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6598ffe07513SJoe Perches				my $specifier;
6599ffe07513SJoe Perches				my $extension;
66003bd32d6aSSakari Ailus				my $qualifier;
6601ffe07513SJoe Perches				my $bad_specifier = "";
66020b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
66030b523769SJoe Perches				$fmt =~ s/%%//g;
6604e3c6bc95STobin C. Harding
66053bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6606e3c6bc95STobin C. Harding					$specifier = $1;
6607e3c6bc95STobin C. Harding					$extension = $2;
66083bd32d6aSSakari Ailus					$qualifier = $3;
6609361b0d28SLinus Torvalds					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
66103bd32d6aSSakari Ailus					    ($extension eq "f" &&
66113bd32d6aSSakari Ailus					     defined $qualifier && $qualifier !~ /^w/)) {
6612e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
66130b523769SJoe Perches						last;
66140b523769SJoe Perches					}
6615e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6616e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6617e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
66180b523769SJoe Perches						}
6619e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6620e3c6bc95STobin 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");
6621e3c6bc95STobin C. Harding					}
6622e3c6bc95STobin C. Harding				}
6623e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
66242a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
66251df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
66261df7338aSSergey Senozhatsky					my $use = "";
6627e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
66281df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6629e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
66301df7338aSSergey Senozhatsky					}
66312a9f9d85STobin C. Harding
66320b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6633e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6634e3c6bc95STobin C. Harding				}
66350b523769SJoe Perches			}
66360b523769SJoe Perches		}
66370b523769SJoe Perches
6638554e165cSAndy Whitcroft# Check for misused memsets
66395b57980dSJoe Perches		if ($perl_version_ok &&
6640d1fe9c09SJoe Perches		    defined $stat &&
66419e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6642554e165cSAndy Whitcroft
6643d7c76ba7SJoe Perches			my $ms_addr = $2;
6644d1fe9c09SJoe Perches			my $ms_val = $7;
6645d1fe9c09SJoe Perches			my $ms_size = $12;
6646d7c76ba7SJoe Perches
6647554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6648554e165cSAndy Whitcroft				ERROR("MEMSET",
6649d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6650554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6651554e165cSAndy Whitcroft				WARN("MEMSET",
6652d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6653d7c76ba7SJoe Perches			}
6654d7c76ba7SJoe Perches		}
6655d7c76ba7SJoe Perches
665698a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
66575b57980dSJoe Perches#		if ($perl_version_ok &&
6658f333195dSJoe Perches#		    defined $stat &&
6659f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6660f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6661f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6662f333195dSJoe Perches#			    $fix) {
6663f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6664f333195dSJoe Perches#			}
6665f333195dSJoe Perches#		}
666698a9bba5SJoe Perches
6667b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
66685b57980dSJoe Perches#		if ($perl_version_ok &&
6669f333195dSJoe Perches#		    defined $stat &&
6670f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6671f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6672f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6673f333195dSJoe Perches#		}
6674b6117d17SMateusz Kulikowski
66758617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
66768617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
66775b57980dSJoe Perches#		if ($perl_version_ok &&
6678f333195dSJoe Perches#		    defined $stat &&
6679f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6680f333195dSJoe Perches#
6681f333195dSJoe Perches#			my $ms_val = $7;
6682f333195dSJoe Perches#
6683f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6684f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6685f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6686f333195dSJoe Perches#				    $fix) {
6687f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6688f333195dSJoe Perches#				}
6689f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6690f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6691f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6692f333195dSJoe Perches#				    $fix) {
6693f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6694f333195dSJoe Perches#				}
6695f333195dSJoe Perches#			}
6696f333195dSJoe Perches#		}
66978617cd09SMateusz Kulikowski
66985dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
66995dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
67005dbdb2d8SJoe Perches			WARN("STRLCPY",
67015dbdb2d8SJoe Perches			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
67025dbdb2d8SJoe Perches		}
67035dbdb2d8SJoe Perches
6704d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
67055b57980dSJoe Perches		if ($perl_version_ok &&
6706d1fe9c09SJoe Perches		    defined $stat &&
6707d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6708d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6709d7c76ba7SJoe Perches				my $call = $1;
6710d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6711d7c76ba7SJoe Perches				my $arg1 = $3;
6712d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6713d1fe9c09SJoe Perches				my $arg2 = $8;
6714d7c76ba7SJoe Perches				my $cast;
6715d7c76ba7SJoe Perches
6716d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6717d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6718d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6719d7c76ba7SJoe Perches					$cast = $cast1;
6720d7c76ba7SJoe Perches				} else {
6721d7c76ba7SJoe Perches					$cast = $cast2;
6722d7c76ba7SJoe Perches				}
6723d7c76ba7SJoe Perches				WARN("MINMAX",
6724d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6725554e165cSAndy Whitcroft			}
6726554e165cSAndy Whitcroft		}
6727554e165cSAndy Whitcroft
67284a273195SJoe Perches# check usleep_range arguments
67295b57980dSJoe Perches		if ($perl_version_ok &&
67304a273195SJoe Perches		    defined $stat &&
67314a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
67324a273195SJoe Perches			my $min = $1;
67334a273195SJoe Perches			my $max = $7;
67344a273195SJoe Perches			if ($min eq $max) {
67354a273195SJoe Perches				WARN("USLEEP_RANGE",
6736458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
67374a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
67384a273195SJoe Perches				 $min > $max) {
67394a273195SJoe Perches				WARN("USLEEP_RANGE",
6740458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
67414a273195SJoe Perches			}
67424a273195SJoe Perches		}
67434a273195SJoe Perches
6744823b794cSJoe Perches# check for naked sscanf
67455b57980dSJoe Perches		if ($perl_version_ok &&
6746823b794cSJoe Perches		    defined $stat &&
67476c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6748823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6749823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6750823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6751823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6752823b794cSJoe Perches			$lc = $lc + $linenr;
67532a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6754823b794cSJoe Perches			WARN("NAKED_SSCANF",
6755823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6756823b794cSJoe Perches		}
6757823b794cSJoe Perches
6758afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
67595b57980dSJoe Perches		if ($perl_version_ok &&
6760afc819abSJoe Perches		    defined $stat &&
6761afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6762afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6763afc819abSJoe Perches			$lc = $lc + $linenr;
67642a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6765afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6766afc819abSJoe Perches				my $format = $6;
6767afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6768afc819abSJoe Perches				if ($count == 1 &&
6769afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6770afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6771afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6772afc819abSJoe Perches				}
6773afc819abSJoe Perches			}
6774afc819abSJoe Perches		}
6775afc819abSJoe Perches
677670dc8a48SJoe Perches# check for new externs in .h files.
677770dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
677870dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6779d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
678070dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
678170dc8a48SJoe Perches			    $fix) {
6782194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
678370dc8a48SJoe Perches			}
678470dc8a48SJoe Perches		}
678570dc8a48SJoe Perches
6786de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6787171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6788c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6789171ae1a4SAndy Whitcroft		{
6790c45dcabdSAndy Whitcroft			my $function_name = $1;
6791c45dcabdSAndy Whitcroft			my $paren_space = $2;
6792171ae1a4SAndy Whitcroft
6793171ae1a4SAndy Whitcroft			my $s = $stat;
6794171ae1a4SAndy Whitcroft			if (defined $cond) {
6795171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6796171ae1a4SAndy Whitcroft			}
6797d8b44b58SKees Cook			if ($s =~ /^\s*;/)
6798c45dcabdSAndy Whitcroft			{
6799000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6800000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6801de7d4f0eSAndy Whitcroft			}
6802de7d4f0eSAndy Whitcroft
6803171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6804000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6805000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6806171ae1a4SAndy Whitcroft			}
68079c9ba34eSAndy Whitcroft
68089c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
68099c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
68109c9ba34eSAndy Whitcroft		{
6811000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6812000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6813171ae1a4SAndy Whitcroft		}
6814171ae1a4SAndy Whitcroft
6815a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
6816a0ad7596SJoe Perches		if (defined $stat &&
6817d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6818d8b44b58SKees Cook		    $1 ne "void") {
6819d8b44b58SKees Cook			my $args = trim($1);
6820ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6821ca0d8929SJoe Perches				my $arg = trim($1);
6822d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6823ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6824ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6825ca0d8929SJoe Perches				}
6826ca0d8929SJoe Perches			}
6827ca0d8929SJoe Perches		}
6828ca0d8929SJoe Perches
6829a0ad7596SJoe Perches# check for function definitions
68305b57980dSJoe Perches		if ($perl_version_ok &&
6831a0ad7596SJoe Perches		    defined $stat &&
6832a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6833a0ad7596SJoe Perches			$context_function = $1;
6834a0ad7596SJoe Perches
6835a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6836a0ad7596SJoe Perches			my $ok = 0;
6837a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6838a0ad7596SJoe Perches			my $herectx = $here . "\n";
6839a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6840a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6841a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6842a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6843a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6844a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6845a0ad7596SJoe Perches			}
6846a0ad7596SJoe Perches			if (!$ok) {
6847a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6848a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6849a0ad7596SJoe Perches			}
6850a0ad7596SJoe Perches		}
6851a0ad7596SJoe Perches
6852de7d4f0eSAndy Whitcroft# checks for new __setup's
6853de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6854de7d4f0eSAndy Whitcroft			my $name = $1;
6855de7d4f0eSAndy Whitcroft
6856de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6857000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
68582581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
6859de7d4f0eSAndy Whitcroft			}
6860653d4876SAndy Whitcroft		}
68619c0ca6f9SAndy Whitcroft
6862e29a70f1SJoe Perches# check for pointless casting of alloc functions
6863e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6864000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6865000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
68669c0ca6f9SAndy Whitcroft		}
686713214adfSAndy Whitcroft
6868a640d25cSJoe Perches# alloc style
6869a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
68705b57980dSJoe Perches		if ($perl_version_ok &&
6871e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6872a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6873a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6874a640d25cSJoe Perches		}
6875a640d25cSJoe Perches
687660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
68775b57980dSJoe Perches		if ($perl_version_ok &&
68781b4a2ed4SJoe Perches		    defined $stat &&
68791b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
688060a55369SJoe Perches			my $oldfunc = $3;
688160a55369SJoe Perches			my $a1 = $4;
688260a55369SJoe Perches			my $a2 = $10;
688360a55369SJoe Perches			my $newfunc = "kmalloc_array";
688460a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
688560a55369SJoe Perches			my $r1 = $a1;
688660a55369SJoe Perches			my $r2 = $a2;
688760a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
688860a55369SJoe Perches				$r1 = $a2;
688960a55369SJoe Perches				$r2 = $a1;
689060a55369SJoe Perches			}
6891e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6892e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
68931b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6894e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6895e3d95a2aSTobin C. Harding
6896e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
68971b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
68981b4a2ed4SJoe Perches				    $cnt == 1 &&
6899e367455aSJoe Perches				    $fix) {
6900194f66fcSJoe 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;
690160a55369SJoe Perches				}
690260a55369SJoe Perches			}
690360a55369SJoe Perches		}
690460a55369SJoe Perches
6905972fdea2SJoe Perches# check for krealloc arg reuse
69065b57980dSJoe Perches		if ($perl_version_ok &&
69074cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
69084cab63ceSJoe Perches		    $1 eq $3) {
6909972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
6910972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6911972fdea2SJoe Perches		}
6912972fdea2SJoe Perches
69135ce59ae0SJoe Perches# check for alloc argument mismatch
69145ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
69155ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
69165ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
69175ce59ae0SJoe Perches		}
69185ce59ae0SJoe Perches
6919caf2a54fSJoe Perches# check for multiple semicolons
6920caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6921d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6922d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6923d5e616fcSJoe Perches			    $fix) {
6924194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6925d5e616fcSJoe Perches			}
6926d1e2ad07SJoe Perches		}
6927d1e2ad07SJoe Perches
6928cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6929cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6930cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
69310ab90191SJoe Perches			my $ull = "";
69320ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
69330ab90191SJoe Perches			if (CHK("BIT_MACRO",
69340ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
69350ab90191SJoe Perches			    $fix) {
69360ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
69370ab90191SJoe Perches			}
69380ab90191SJoe Perches		}
69390ab90191SJoe Perches
694050161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
69413e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
694250161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
69433e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
694450161266SJoe Perches		}
694550161266SJoe Perches
69462d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
69473e89ad85SJerome 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*$/) {
69482d632745SJoe Perches			my $config = $1;
69492d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
69503e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
69512d632745SJoe Perches			    $fix) {
69522d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
69532d632745SJoe Perches			}
69542d632745SJoe Perches		}
69552d632745SJoe Perches
6956f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
6957f36d3eb8SJoe Perches		my @fallthroughs = (
6958f36d3eb8SJoe Perches			'fallthrough',
6959f36d3eb8SJoe Perches			'@fallthrough@',
6960f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
6961f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6962f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6963f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6964f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6965f36d3eb8SJoe Perches		    );
6966f36d3eb8SJoe Perches		if ($raw_comment ne '') {
6967f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
6968f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
6969f36d3eb8SJoe Perches					my $msg_level = \&WARN;
6970f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
6971f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
6972f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6973f36d3eb8SJoe Perches					last;
6974f36d3eb8SJoe Perches				}
6975f36d3eb8SJoe Perches			}
6976f36d3eb8SJoe Perches		}
6977f36d3eb8SJoe Perches
6978d1e2ad07SJoe Perches# check for switch/default statements without a break;
69795b57980dSJoe Perches		if ($perl_version_ok &&
6980d1e2ad07SJoe Perches		    defined $stat &&
6981d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6982d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6983e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
6984e3d95a2aSTobin C. Harding
6985d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6986d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6987caf2a54fSJoe Perches		}
6988caf2a54fSJoe Perches
698913214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6990d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6991d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6992d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6993d5e616fcSJoe Perches			    $fix) {
6994194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6995d5e616fcSJoe Perches			}
699613214adfSAndy Whitcroft		}
6997773647a0SAndy Whitcroft
699862ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
699962ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
700062ec818fSJoe Perches			ERROR("DATE_TIME",
700162ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
700262ec818fSJoe Perches		}
700362ec818fSJoe Perches
70042c92488aSJoe Perches# check for use of yield()
70052c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
70062c92488aSJoe Perches			WARN("YIELD",
70072c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
70082c92488aSJoe Perches		}
70092c92488aSJoe Perches
7010179f8f40SJoe Perches# check for comparisons against true and false
7011179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7012179f8f40SJoe Perches			my $lead = $1;
7013179f8f40SJoe Perches			my $arg = $2;
7014179f8f40SJoe Perches			my $test = $3;
7015179f8f40SJoe Perches			my $otype = $4;
7016179f8f40SJoe Perches			my $trail = $5;
7017179f8f40SJoe Perches			my $op = "!";
7018179f8f40SJoe Perches
7019179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7020179f8f40SJoe Perches
7021179f8f40SJoe Perches			my $type = lc($otype);
7022179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7023179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7024179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7025179f8f40SJoe Perches					$op = "";
7026179f8f40SJoe Perches				}
7027179f8f40SJoe Perches
7028179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7029179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7030179f8f40SJoe Perches
7031179f8f40SJoe Perches## maybe suggesting a correct construct would better
7032179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7033179f8f40SJoe Perches
7034179f8f40SJoe Perches			}
7035179f8f40SJoe Perches		}
7036179f8f40SJoe Perches
70374882720bSThomas Gleixner# check for semaphores initialized locked
70384882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7039000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7040000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7041773647a0SAndy Whitcroft		}
70426712d858SJoe Perches
704367d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
704467d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7045000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
704667d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7047773647a0SAndy Whitcroft		}
70486712d858SJoe Perches
7049ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7050f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7051000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7052ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7053f3db6639SMichael Ellerman		}
70546712d858SJoe Perches
70553d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
70563d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
70573d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
70583d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
70593d709ab5SPaul E. McKenney		}
70603d709ab5SPaul E. McKenney
70619189c7e7SJoe Perches# check for deprecated apis
70629189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
70639189c7e7SJoe Perches			my $deprecated_api = $1;
70649189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
70659189c7e7SJoe Perches			WARN("DEPRECATED_API",
70669189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
70679189c7e7SJoe Perches		}
70689189c7e7SJoe Perches
70690f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7070d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7071ced69da1SQuentin Monnet		if (defined($const_structs) &&
7072ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7073d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7074000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7075d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
70762b6db5cbSAndy Whitcroft		}
7077773647a0SAndy Whitcroft
7078773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7079773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
708035cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7081773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7082c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7083c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7084171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7085171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
708635cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
708735cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7088773647a0SAndy Whitcroft		{
7089000d1cc1SJoe Perches			WARN("NR_CPUS",
7090000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7091773647a0SAndy Whitcroft		}
70929c9ba34eSAndy Whitcroft
709352ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
709452ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
709552ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
709652ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
709752ea8506SJoe Perches		}
709852ea8506SJoe Perches
7099acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
71005b57980dSJoe Perches		if ($perl_version_ok &&
7101acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7102acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7103acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7104acd9362cSJoe Perches		}
7105acd9362cSJoe Perches
7106de3f186fSDenis Efremov# nested likely/unlikely calls
7107de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7108de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7109de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7110de3f186fSDenis Efremov		}
7111de3f186fSDenis Efremov
7112691d77b6SAndy Whitcroft# whine mightly about in_atomic
7113691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7114691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7115000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7116000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7117f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7118000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7119000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7120691d77b6SAndy Whitcroft			}
7121691d77b6SAndy Whitcroft		}
71221704f47bSPeter Zijlstra
71231704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
71241704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
71251704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
71261704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
71271704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
71281704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7129000d1cc1SJoe Perches				ERROR("LOCKDEP",
7130000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
71311704f47bSPeter Zijlstra			}
71321704f47bSPeter Zijlstra		}
713388f8831cSDave Jones
7134b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7135b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7136000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7137000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
713888f8831cSDave Jones		}
71392435880fSJoe Perches
714000180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
714100180468SJoe Perches# and whether or not function naming is typical and if
714200180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
71435b57980dSJoe Perches		if ($perl_version_ok &&
714400180468SJoe Perches		    defined $stat &&
714500180468SJoe 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*\)/) {
714600180468SJoe Perches			my $var = $1;
714700180468SJoe Perches			my $perms = $2;
714800180468SJoe Perches			my $show = $3;
714900180468SJoe Perches			my $store = $4;
715000180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
715100180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
715200180468SJoe Perches			    $store =~ /^${var}_store$/ &&
715300180468SJoe Perches			    $octal_perms eq "0644") {
715400180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
715500180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
715600180468SJoe Perches				    $fix) {
715700180468SJoe 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})/;
715800180468SJoe Perches				}
715900180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
716000180468SJoe Perches				 $store =~ /^NULL$/ &&
716100180468SJoe Perches				 $octal_perms eq "0444") {
716200180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
716300180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
716400180468SJoe Perches				    $fix) {
716500180468SJoe 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})/;
716600180468SJoe Perches				}
716700180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
716800180468SJoe Perches				 $store =~ /^${var}_store$/ &&
716900180468SJoe Perches				 $octal_perms eq "0200") {
717000180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
717100180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
717200180468SJoe Perches				    $fix) {
717300180468SJoe 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})/;
717400180468SJoe Perches				}
717500180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
717600180468SJoe Perches				 $octal_perms eq "0444" ||
717700180468SJoe Perches				 $octal_perms eq "0200") {
717800180468SJoe Perches				my $newshow = "$show";
717900180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
718000180468SJoe Perches				my $newstore = $store;
718100180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
718200180468SJoe Perches				my $rename = "";
718300180468SJoe Perches				if ($show ne $newshow) {
718400180468SJoe Perches					$rename .= " '$show' to '$newshow'";
718500180468SJoe Perches				}
718600180468SJoe Perches				if ($store ne $newstore) {
718700180468SJoe Perches					$rename .= " '$store' to '$newstore'";
718800180468SJoe Perches				}
718900180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
719000180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
719100180468SJoe Perches			} else {
719200180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
719300180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
719400180468SJoe Perches			}
719500180468SJoe Perches		}
719600180468SJoe Perches
7197515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7198515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
719973121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
720073121534SJoe Perches#   specific definition of not visible in sysfs.
720173121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
720273121534SJoe Perches#   use the default permissions
72035b57980dSJoe Perches		if ($perl_version_ok &&
7204459cf0aeSJoe Perches		    defined $stat &&
7205515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
72062435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
72072435880fSJoe Perches				my $func = $entry->[0];
72082435880fSJoe Perches				my $arg_pos = $entry->[1];
72092435880fSJoe Perches
7210459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7211459cf0aeSJoe Perches				$lc = $lc + $linenr;
72122a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7213459cf0aeSJoe Perches
72142435880fSJoe Perches				my $skip_args = "";
72152435880fSJoe Perches				if ($arg_pos > 1) {
72162435880fSJoe Perches					$arg_pos--;
72172435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
72182435880fSJoe Perches				}
7219f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7220459cf0aeSJoe Perches				if ($stat =~ /$test/) {
72212435880fSJoe Perches					my $val = $1;
72222435880fSJoe Perches					$val = $6 if ($skip_args ne "");
722373121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
722473121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
722573121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
72262435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7227459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7228f90774e1SJoe Perches					}
7229f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7230c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7231459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
72322435880fSJoe Perches					}
7233459cf0aeSJoe Perches				}
7234459cf0aeSJoe Perches			}
7235459cf0aeSJoe Perches		}
7236459cf0aeSJoe Perches
7237459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7238bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
723900180468SJoe Perches			my $oval = $1;
724000180468SJoe Perches			my $octal = perms_to_octal($oval);
7241f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7242459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7243f90774e1SJoe Perches			    $fix) {
724400180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
72452435880fSJoe Perches			}
724613214adfSAndy Whitcroft		}
72475a6d20ceSBjorn Andersson
72485a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
72495a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
72505a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
72515a6d20ceSBjorn Andersson			my $valid_licenses = qr{
72525a6d20ceSBjorn Andersson						GPL|
72535a6d20ceSBjorn Andersson						GPL\ v2|
72545a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
72555a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
72565a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
72575a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
72585a6d20ceSBjorn Andersson						Proprietary
72595a6d20ceSBjorn Andersson					}x;
72605a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
72615a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
72625a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
72635a6d20ceSBjorn Andersson			}
72645a6d20ceSBjorn Andersson		}
72656a8d76cbSMatteo Croce
72666a8d76cbSMatteo Croce# check for sysctl duplicate constants
72676a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
72686a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
72696a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
72706a8d76cbSMatteo Croce		}
7271515a235eSJoe Perches	}
727213214adfSAndy Whitcroft
727313214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
727413214adfSAndy Whitcroft	# so just keep quiet.
727513214adfSAndy Whitcroft	if ($#rawlines == -1) {
727613214adfSAndy Whitcroft		exit(0);
72770a920b5bSAndy Whitcroft	}
72780a920b5bSAndy Whitcroft
72798905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
72808905a67cSAndy Whitcroft	# things that appear to be patches.
72818905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
72828905a67cSAndy Whitcroft		exit(0);
72838905a67cSAndy Whitcroft	}
72848905a67cSAndy Whitcroft
7285e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
72868905a67cSAndy Whitcroft	# just keep quiet.
72878905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
72888905a67cSAndy Whitcroft		exit(0);
72898905a67cSAndy Whitcroft	}
72908905a67cSAndy Whitcroft
7291a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7292000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7293000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
72940a920b5bSAndy Whitcroft	}
7295cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7296cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7297000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7298000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
729948ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
730048ca2d8aSDwaipayan Ray			# authorsignoff values:
730148ca2d8aSDwaipayan Ray			# 0 -> missing sign off
730248ca2d8aSDwaipayan Ray			# 1 -> sign off identical
730348ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
730448ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
730548ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
730648ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
730748ca2d8aSDwaipayan Ray
730848ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
730948ca2d8aSDwaipayan Ray
731048ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
731148ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7312cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
731348ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
731448ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
731548ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
731648ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
731748ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
731848ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
731948ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
732048ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
732148ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
732248ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
732348ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
732448ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
732548ca2d8aSDwaipayan Ray			}
7326cd261496SGeert Uytterhoeven		}
73270a920b5bSAndy Whitcroft	}
73280a920b5bSAndy Whitcroft
7329f0a594c1SAndy Whitcroft	print report_dump();
733013214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
733113214adfSAndy Whitcroft		print "$filename " if ($summary_file);
73326c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
73336c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
73346c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
73356c72ffaaSAndy Whitcroft	}
73368905a67cSAndy Whitcroft
7337d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7338ef212196SJoe Perches		# If there were any defects found and not already fixing them
7339ef212196SJoe Perches		if (!$clean and !$fix) {
7340ef212196SJoe Perches			print << "EOM"
7341ef212196SJoe Perches
7342ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7343ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7344ef212196SJoe PerchesEOM
7345ef212196SJoe Perches		}
7346d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7347d2c0a235SAndy Whitcroft		# then suggest that.
7348d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7349b0781216SMike Frysinger			$rpt_cleaners = 0;
7350d8469f16SJoe Perches			print << "EOM"
7351d8469f16SJoe Perches
7352d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7353d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7354d8469f16SJoe PerchesEOM
7355d2c0a235SAndy Whitcroft		}
7356d2c0a235SAndy Whitcroft	}
7357d2c0a235SAndy Whitcroft
7358d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7359d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7360d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
73619624b8d6SJoe Perches		my $newfile = $filename;
73629624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
73633705ce5bSJoe Perches		my $linecount = 0;
73643705ce5bSJoe Perches		my $f;
73653705ce5bSJoe Perches
7366d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7367d752fcc8SJoe Perches
73683705ce5bSJoe Perches		open($f, '>', $newfile)
73693705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
73703705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
73713705ce5bSJoe Perches			$linecount++;
73723705ce5bSJoe Perches			if ($file) {
73733705ce5bSJoe Perches				if ($linecount > 3) {
73743705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
73753705ce5bSJoe Perches					print $f $fixed_line . "\n";
73763705ce5bSJoe Perches				}
73773705ce5bSJoe Perches			} else {
73783705ce5bSJoe Perches				print $f $fixed_line . "\n";
73793705ce5bSJoe Perches			}
73803705ce5bSJoe Perches		}
73813705ce5bSJoe Perches		close($f);
73823705ce5bSJoe Perches
73833705ce5bSJoe Perches		if (!$quiet) {
73843705ce5bSJoe Perches			print << "EOM";
7385d8469f16SJoe Perches
73863705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
73873705ce5bSJoe Perches
73883705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
73893705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
73903705ce5bSJoe Perches
73913705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
73923705ce5bSJoe PerchesNo warranties, expressed or implied...
73933705ce5bSJoe PerchesEOM
73943705ce5bSJoe Perches		}
73953705ce5bSJoe Perches	}
73963705ce5bSJoe Perches
7397d8469f16SJoe Perches	if ($quiet == 0) {
7398d8469f16SJoe Perches		print "\n";
7399d8469f16SJoe Perches		if ($clean == 1) {
7400d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7401d8469f16SJoe Perches		} else {
7402d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
74030a920b5bSAndy Whitcroft		}
74040a920b5bSAndy Whitcroft	}
74050a920b5bSAndy Whitcroft	return $clean;
74060a920b5bSAndy Whitcroft}
7407