xref: /linux-6.15/scripts/checkpatch.pl (revision bd17e036)
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;
2652178ce0SDwaipayan Raymy $verbose = 0;
2752178ce0SDwaipayan Raymy %verbose_messages = ();
2852178ce0SDwaipayan Raymy %verbose_emitted = ();
290a920b5bSAndy Whitcroftmy $tree = 1;
300a920b5bSAndy Whitcroftmy $chk_signoff = 1;
310a920b5bSAndy Whitcroftmy $chk_patch = 1;
32773647a0SAndy Whitcroftmy $tst_only;
336c72ffaaSAndy Whitcroftmy $emacs = 0;
348905a67cSAndy Whitcroftmy $terse = 0;
3534d8815fSJoe Perchesmy $showfile = 0;
366c72ffaaSAndy Whitcroftmy $file = 0;
374a593c34SDu, Changbinmy $git = 0;
380dea9f1eSJoe Perchesmy %git_commits = ();
396c72ffaaSAndy Whitcroftmy $check = 0;
402ac73b4fSJoe Perchesmy $check_orig = 0;
418905a67cSAndy Whitcroftmy $summary = 1;
428905a67cSAndy Whitcroftmy $mailback = 0;
4313214adfSAndy Whitcroftmy $summary_file = 0;
44000d1cc1SJoe Perchesmy $show_types = 0;
453beb42ecSJoe Perchesmy $list_types = 0;
463705ce5bSJoe Perchesmy $fix = 0;
479624b8d6SJoe Perchesmy $fix_inplace = 0;
486c72ffaaSAndy Whitcroftmy $root;
490f7f635bSJoe Perchesmy $gitroot = $ENV{'GIT_DIR'};
500f7f635bSJoe Perches$gitroot = ".git" if !defined($gitroot);
51c2fdda0dSAndy Whitcroftmy %debug;
523445686aSJoe Perchesmy %camelcase = ();
5391bfe484SJoe Perchesmy %use_type = ();
5491bfe484SJoe Perchesmy @use = ();
5591bfe484SJoe Perchesmy %ignore_type = ();
56000d1cc1SJoe Perchesmy @ignore = ();
5777f5b10aSHannes Edermy $help = 0;
58000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
59bdc48fa1SJoe Perchesmy $max_line_length = 100;
60d62a201fSDave Hansenmy $ignore_perl_version = 0;
61d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
6256193274SVadim Bendeburymy $min_conf_desc_length = 4;
6366b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
64ebfd7d62SJoe Perchesmy $codespell = 0;
65f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
660ee3e7b8SPeter Ujfalusimy $user_codespellfile = "";
67bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
6852178ce0SDwaipayan Raymy $docsfile = "$D/../Documentation/dev-tools/checkpatch.rst";
69ced69da1SQuentin Monnetmy $typedefsfile;
70737c0767SJohn Brooksmy $color = "auto";
7198005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
72dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
73dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
74713a09deSAntonio Borneomy $tabsize = 8;
753e89ad85SJerome Forissiermy ${CONFIG_} = "CONFIG_";
7677f5b10aSHannes Eder
7777f5b10aSHannes Edersub help {
7877f5b10aSHannes Eder	my ($exitcode) = @_;
7977f5b10aSHannes Eder
8077f5b10aSHannes Eder	print << "EOM";
8177f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
8277f5b10aSHannes EderVersion: $V
8377f5b10aSHannes Eder
8477f5b10aSHannes EderOptions:
8577f5b10aSHannes Eder  -q, --quiet                quiet
8652178ce0SDwaipayan Ray  -v, --verbose              verbose mode
8777f5b10aSHannes Eder  --no-tree                  run without a kernel tree
8877f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
8977f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
9077f5b10aSHannes Eder  --emacs                    emacs compile window format
9177f5b10aSHannes Eder  --terse                    one line per report
9234d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
934a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
944a593c34SDu, Changbin                             single git commit with:
954a593c34SDu, Changbin                               <rev>
964a593c34SDu, Changbin                               <rev>^
974a593c34SDu, Changbin                               <rev>~n
984a593c34SDu, Changbin                             multiple git commits with:
994a593c34SDu, Changbin                               <rev1>..<rev2>
1004a593c34SDu, Changbin                               <rev1>...<rev2>
1014a593c34SDu, Changbin                               <rev>-<count>
1024a593c34SDu, Changbin                             git merges are ignored
10377f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
10477f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
1053beb42ecSJoe Perches  --list-types               list the possible message types
10691bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
107000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1083beb42ecSJoe Perches  --show-types               show the specific message type in the output
109bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
110bdc48fa1SJoe Perches                             if exceeded, warn on patches
111bdc48fa1SJoe Perches                             requires --strict for use with --file
11256193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
113bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
11477f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
11577f5b10aSHannes Eder  --no-summary               suppress the per-file summary
11677f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
11777f5b10aSHannes Eder  --summary-file             include the filename in summary
11877f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
11977f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
12077f5b10aSHannes Eder                             is all off)
12177f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
12277f5b10aSHannes Eder                             literally
1233705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1243705ce5bSJoe Perches                             If correctable single-line errors exist, create
1253705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1263705ce5bSJoe Perches                             with potential errors corrected to the preferred
1273705ce5bSJoe Perches                             checkpatch style
1289624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1299624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1309624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
131d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
132d62a201fSDave Hansen                             runtime errors.
133ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
1340ee3e7b8SPeter Ujfalusi                             (default:$codespellfile)
135ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
13675ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
137737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
138737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
1393e89ad85SJerome Forissier  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1403e89ad85SJerome Forissier                             ${CONFIG_})
14177f5b10aSHannes Eder  -h, --help, --version      display this help and exit
14277f5b10aSHannes Eder
14377f5b10aSHannes EderWhen FILE is - read standard input.
14477f5b10aSHannes EderEOM
14577f5b10aSHannes Eder
14677f5b10aSHannes Eder	exit($exitcode);
14777f5b10aSHannes Eder}
14877f5b10aSHannes Eder
1493beb42ecSJoe Perchessub uniq {
1503beb42ecSJoe Perches	my %seen;
1513beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1523beb42ecSJoe Perches}
1533beb42ecSJoe Perches
1543beb42ecSJoe Perchessub list_types {
1553beb42ecSJoe Perches	my ($exitcode) = @_;
1563beb42ecSJoe Perches
1573beb42ecSJoe Perches	my $count = 0;
1583beb42ecSJoe Perches
1593beb42ecSJoe Perches	local $/ = undef;
1603beb42ecSJoe Perches
1613beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1623beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1633beb42ecSJoe Perches
1643beb42ecSJoe Perches	my $text = <$script>;
1653beb42ecSJoe Perches	close($script);
1663beb42ecSJoe Perches
16752178ce0SDwaipayan Ray	my %types = ();
1680547fa58SJean Delvare	# Also catch when type or level is passed through a variable
16952178ce0SDwaipayan Ray	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
17052178ce0SDwaipayan Ray		if (defined($1)) {
17152178ce0SDwaipayan Ray			if (exists($types{$2})) {
17252178ce0SDwaipayan Ray				$types{$2} .= ",$1" if ($types{$2} ne $1);
17352178ce0SDwaipayan Ray			} else {
17452178ce0SDwaipayan Ray				$types{$2} = $1;
1753beb42ecSJoe Perches			}
17652178ce0SDwaipayan Ray		} else {
17752178ce0SDwaipayan Ray			$types{$2} = "UNDETERMINED";
17852178ce0SDwaipayan Ray		}
17952178ce0SDwaipayan Ray	}
18052178ce0SDwaipayan Ray
1813beb42ecSJoe Perches	print("#\tMessage type\n\n");
18252178ce0SDwaipayan Ray	if ($color) {
18352178ce0SDwaipayan Ray		print(" ( Color coding: ");
18452178ce0SDwaipayan Ray		print(RED . "ERROR" . RESET);
18552178ce0SDwaipayan Ray		print(" | ");
18652178ce0SDwaipayan Ray		print(YELLOW . "WARNING" . RESET);
18752178ce0SDwaipayan Ray		print(" | ");
18852178ce0SDwaipayan Ray		print(GREEN . "CHECK" . RESET);
18952178ce0SDwaipayan Ray		print(" | ");
19052178ce0SDwaipayan Ray		print("Multiple levels / Undetermined");
19152178ce0SDwaipayan Ray		print(" )\n\n");
19252178ce0SDwaipayan Ray	}
19352178ce0SDwaipayan Ray
19452178ce0SDwaipayan Ray	foreach my $type (sort keys %types) {
19552178ce0SDwaipayan Ray		my $orig_type = $type;
19652178ce0SDwaipayan Ray		if ($color) {
19752178ce0SDwaipayan Ray			my $level = $types{$type};
19852178ce0SDwaipayan Ray			if ($level eq "ERROR") {
19952178ce0SDwaipayan Ray				$type = RED . $type . RESET;
20052178ce0SDwaipayan Ray			} elsif ($level eq "WARN") {
20152178ce0SDwaipayan Ray				$type = YELLOW . $type . RESET;
20252178ce0SDwaipayan Ray			} elsif ($level eq "CHK") {
20352178ce0SDwaipayan Ray				$type = GREEN . $type . RESET;
20452178ce0SDwaipayan Ray			}
20552178ce0SDwaipayan Ray		}
2063beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
20752178ce0SDwaipayan Ray		if ($verbose && exists($verbose_messages{$orig_type})) {
20852178ce0SDwaipayan Ray			my $message = $verbose_messages{$orig_type};
20952178ce0SDwaipayan Ray			$message =~ s/\n/\n\t/g;
21052178ce0SDwaipayan Ray			print("\t" . $message . "\n\n");
21152178ce0SDwaipayan Ray		}
2123beb42ecSJoe Perches	}
2133beb42ecSJoe Perches
2143beb42ecSJoe Perches	exit($exitcode);
2153beb42ecSJoe Perches}
2163beb42ecSJoe Perches
217000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
218000d1cc1SJoe Perchesif (-f $conf) {
219000d1cc1SJoe Perches	my @conf_args;
220000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
221000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
222000d1cc1SJoe Perches
223000d1cc1SJoe Perches	while (<$conffile>) {
224000d1cc1SJoe Perches		my $line = $_;
225000d1cc1SJoe Perches
226000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
227000d1cc1SJoe Perches		$line =~ s/^\s*//g;
228000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
229000d1cc1SJoe Perches
230000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
231000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
232000d1cc1SJoe Perches
233000d1cc1SJoe Perches		my @words = split(" ", $line);
234000d1cc1SJoe Perches		foreach my $word (@words) {
235000d1cc1SJoe Perches			last if ($word =~ m/^#/);
236000d1cc1SJoe Perches			push (@conf_args, $word);
237000d1cc1SJoe Perches		}
238000d1cc1SJoe Perches	}
239000d1cc1SJoe Perches	close($conffile);
240000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
241000d1cc1SJoe Perches}
242000d1cc1SJoe Perches
24352178ce0SDwaipayan Raysub load_docs {
24452178ce0SDwaipayan Ray	open(my $docs, '<', "$docsfile")
24552178ce0SDwaipayan Ray	    or warn "$P: Can't read the documentation file $docsfile $!\n";
24652178ce0SDwaipayan Ray
24752178ce0SDwaipayan Ray	my $type = '';
24852178ce0SDwaipayan Ray	my $desc = '';
24952178ce0SDwaipayan Ray	my $in_desc = 0;
25052178ce0SDwaipayan Ray
25152178ce0SDwaipayan Ray	while (<$docs>) {
25252178ce0SDwaipayan Ray		chomp;
25352178ce0SDwaipayan Ray		my $line = $_;
25452178ce0SDwaipayan Ray		$line =~ s/\s+$//;
25552178ce0SDwaipayan Ray
25652178ce0SDwaipayan Ray		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
25752178ce0SDwaipayan Ray			if ($desc ne '') {
25852178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
25952178ce0SDwaipayan Ray			}
26052178ce0SDwaipayan Ray			$type = $1;
26152178ce0SDwaipayan Ray			$desc = '';
26252178ce0SDwaipayan Ray			$in_desc = 1;
26352178ce0SDwaipayan Ray		} elsif ($in_desc) {
26452178ce0SDwaipayan Ray			if ($line =~ /^(?:\s{4,}|$)/) {
26552178ce0SDwaipayan Ray				$line =~ s/^\s{4}//;
26652178ce0SDwaipayan Ray				$desc .= $line;
26752178ce0SDwaipayan Ray				$desc .= "\n";
26852178ce0SDwaipayan Ray			} else {
26952178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
27052178ce0SDwaipayan Ray				$type = '';
27152178ce0SDwaipayan Ray				$desc = '';
27252178ce0SDwaipayan Ray				$in_desc = 0;
27352178ce0SDwaipayan Ray			}
27452178ce0SDwaipayan Ray		}
27552178ce0SDwaipayan Ray	}
27652178ce0SDwaipayan Ray
27752178ce0SDwaipayan Ray	if ($desc ne '') {
27852178ce0SDwaipayan Ray		$verbose_messages{$type} = trim($desc);
27952178ce0SDwaipayan Ray	}
28052178ce0SDwaipayan Ray	close($docs);
28152178ce0SDwaipayan Ray}
28252178ce0SDwaipayan Ray
283737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
284737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
285737c0767SJohn Brooksforeach (@ARGV) {
286737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
287737c0767SJohn Brooks		$_ = "--color=$color";
288737c0767SJohn Brooks	}
289737c0767SJohn Brooks}
290737c0767SJohn Brooks
2910a920b5bSAndy WhitcroftGetOptions(
2926c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
29352178ce0SDwaipayan Ray	'v|verbose!'	=> \$verbose,
2940a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2950a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2960a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2976c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2988905a67cSAndy Whitcroft	'terse!'	=> \$terse,
29934d8815fSJoe Perches	'showfile!'	=> \$showfile,
30077f5b10aSHannes Eder	'f|file!'	=> \$file,
3014a593c34SDu, Changbin	'g|git!'	=> \$git,
3026c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
3036c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
304000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
30591bfe484SJoe Perches	'types=s'	=> \@use,
306000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
3073beb42ecSJoe Perches	'list-types!'	=> \$list_types,
3086cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
30956193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
310713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
3116c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
3128905a67cSAndy Whitcroft	'summary!'	=> \$summary,
3138905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
31413214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
3153705ce5bSJoe Perches	'fix!'		=> \$fix,
3169624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
317d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
318c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
319773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
320ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
3210ee3e7b8SPeter Ujfalusi	'codespellfile=s'	=> \$user_codespellfile,
32275ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
323737c0767SJohn Brooks	'color=s'	=> \$color,
324737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
325737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
3263e89ad85SJerome Forissier	'kconfig-prefix=s'	=> \${CONFIG_},
32777f5b10aSHannes Eder	'h|help'	=> \$help,
32877f5b10aSHannes Eder	'version'	=> \$help
3290ee3e7b8SPeter Ujfalusi) or $help = 2;
33077f5b10aSHannes Eder
3310ee3e7b8SPeter Ujfalusiif ($user_codespellfile) {
3320ee3e7b8SPeter Ujfalusi	# Use the user provided codespell file unconditionally
3330ee3e7b8SPeter Ujfalusi	$codespellfile = $user_codespellfile;
3340ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) {
3350ee3e7b8SPeter Ujfalusi	# If /usr/share/codespell/dictionary.txt is not present, try to find it
3360ee3e7b8SPeter Ujfalusi	# under codespell's install directory: <codespell_root>/data/dictionary.txt
337c882c6b1SSagar Patel	if (($codespell || $help) && which("python3") ne "") {
3380ee3e7b8SPeter Ujfalusi		my $python_codespell_dict = << "EOF";
3390ee3e7b8SPeter Ujfalusi
3400ee3e7b8SPeter Ujfalusiimport os.path as op
3410ee3e7b8SPeter Ujfalusiimport codespell_lib
3420ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__)
3430ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
3440ee3e7b8SPeter Ujfalusiprint(codespell_file, end='')
3450ee3e7b8SPeter UjfalusiEOF
3460ee3e7b8SPeter Ujfalusi
347c882c6b1SSagar Patel		my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`;
3480ee3e7b8SPeter Ujfalusi		$codespellfile = $codespell_dict if (-f $codespell_dict);
3490ee3e7b8SPeter Ujfalusi	}
3500ee3e7b8SPeter Ujfalusi}
3510ee3e7b8SPeter Ujfalusi
3520ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0
3530ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1
3540ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help);
3550a920b5bSAndy Whitcroft
35652178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
35752178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
35852178ce0SDwaipayan Ray
35952178ce0SDwaipayan Rayif ($color =~ /^[01]$/) {
36052178ce0SDwaipayan Ray	$color = !$color;
36152178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) {
36252178ce0SDwaipayan Ray	$color = 1;
36352178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) {
36452178ce0SDwaipayan Ray	$color = 0;
36552178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) {
36652178ce0SDwaipayan Ray	$color = (-t STDOUT);
36752178ce0SDwaipayan Ray} else {
36852178ce0SDwaipayan Ray	die "$P: Invalid color mode: $color\n";
36952178ce0SDwaipayan Ray}
37052178ce0SDwaipayan Ray
37152178ce0SDwaipayan Rayload_docs() if ($verbose);
3723beb42ecSJoe Percheslist_types(0) if ($list_types);
3733beb42ecSJoe Perches
3749624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
3752ac73b4fSJoe Perches$check_orig = $check;
3769624b8d6SJoe Perches
3770a920b5bSAndy Whitcroftmy $exit = 0;
3780a920b5bSAndy Whitcroft
3795b57980dSJoe Perchesmy $perl_version_ok = 1;
380d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
3815b57980dSJoe Perches	$perl_version_ok = 0;
382d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
3835b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
384d62a201fSDave Hansen}
385d62a201fSDave Hansen
38645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
3870a920b5bSAndy Whitcroftif ($#ARGV < 0) {
38845107ff6SAllen Hubbe	push(@ARGV, '-');
3890a920b5bSAndy Whitcroft}
3900a920b5bSAndy Whitcroft
391713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
39232f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
393713a09deSAntonio Borneo
39491bfe484SJoe Perchessub hash_save_array_words {
39591bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
39691bfe484SJoe Perches
39791bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
39891bfe484SJoe Perches	foreach my $word (@array) {
399000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
400000d1cc1SJoe Perches		$word =~ s/^\s*//g;
401000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
402000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
403000d1cc1SJoe Perches
404000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
405000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
406000d1cc1SJoe Perches
40791bfe484SJoe Perches		$hashRef->{$word}++;
408000d1cc1SJoe Perches	}
40991bfe484SJoe Perches}
41091bfe484SJoe Perches
41191bfe484SJoe Perchessub hash_show_words {
41291bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
41391bfe484SJoe Perches
4143c816e49SJoe Perches	if (keys %$hashRef) {
415d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
41658cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
41791bfe484SJoe Perches			print " $word";
41891bfe484SJoe Perches		}
419d8469f16SJoe Perches		print "\n";
42091bfe484SJoe Perches	}
42191bfe484SJoe Perches}
42291bfe484SJoe Perches
42391bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
42491bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
425000d1cc1SJoe Perches
426c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
427c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
4287429c690SAndy Whitcroftmy $dbg_type = 0;
429a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
430c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
43121caa13cSAndy Whitcroft	## no critic
43221caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
43321caa13cSAndy Whitcroft	die "$@" if ($@);
434c2fdda0dSAndy Whitcroft}
435c2fdda0dSAndy Whitcroft
436d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
437d2c0a235SAndy Whitcroft
4388905a67cSAndy Whitcroftif ($terse) {
4398905a67cSAndy Whitcroft	$emacs = 1;
4408905a67cSAndy Whitcroft	$quiet++;
4418905a67cSAndy Whitcroft}
4428905a67cSAndy Whitcroft
4436c72ffaaSAndy Whitcroftif ($tree) {
4446c72ffaaSAndy Whitcroft	if (defined $root) {
4456c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
4466c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
4476c72ffaaSAndy Whitcroft		}
4486c72ffaaSAndy Whitcroft	} else {
4496c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
4506c72ffaaSAndy Whitcroft			$root = '.';
4516c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
4526c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
4536c72ffaaSAndy Whitcroft			$root = $1;
4546c72ffaaSAndy Whitcroft		}
4556c72ffaaSAndy Whitcroft	}
4566c72ffaaSAndy Whitcroft
4576c72ffaaSAndy Whitcroft	if (!defined $root) {
4580a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
4590a920b5bSAndy Whitcroft		exit(2);
4600a920b5bSAndy Whitcroft	}
4616c72ffaaSAndy Whitcroft}
4626c72ffaaSAndy Whitcroft
4636c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
4646c72ffaaSAndy Whitcroft
4652ceb532bSAndy Whitcroftour $Ident	= qr{
4662ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
4672ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
4682ceb532bSAndy Whitcroft		}x;
4696c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
4706c72ffaaSAndy Whitcroftour $Sparse	= qr{
4716c72ffaaSAndy Whitcroft			__user|
4726c72ffaaSAndy Whitcroft			__kernel|
4736c72ffaaSAndy Whitcroft			__force|
4746c72ffaaSAndy Whitcroft			__iomem|
4756c72ffaaSAndy Whitcroft			__must_check|
476417495edSAndy Whitcroft			__kprobes|
477165e72a6SSven Eckelmann			__ref|
47833aa4597SGeert Uytterhoeven			__refconst|
47933aa4597SGeert Uytterhoeven			__refdata|
480ad315455SBoqun Feng			__rcu|
481ad315455SBoqun Feng			__private
4826c72ffaaSAndy Whitcroft		}x;
483e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
484e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
485e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
486e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
487e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
4888716de38SJoe Perches
48952131292SWolfram Sang# Notes to $Attribute:
49052131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
4916c72ffaaSAndy Whitcroftour $Attribute	= qr{
4926c72ffaaSAndy Whitcroft			const|
493b5e8736aSJoe Perches			volatile|
49403f1df7dSJoe Perches			__percpu|
49503f1df7dSJoe Perches			__nocast|
49603f1df7dSJoe Perches			__safe|
49746d832f5SMichael S. Tsirkin			__bitwise|
49803f1df7dSJoe Perches			__packed__|
49903f1df7dSJoe Perches			__packed2__|
50003f1df7dSJoe Perches			__naked|
50103f1df7dSJoe Perches			__maybe_unused|
50203f1df7dSJoe Perches			__always_unused|
50303f1df7dSJoe Perches			__noreturn|
50403f1df7dSJoe Perches			__used|
50503f1df7dSJoe Perches			__cold|
506e23ef1f3SJoe Perches			__pure|
50703f1df7dSJoe Perches			__noclone|
50803f1df7dSJoe Perches			__deprecated|
5096c72ffaaSAndy Whitcroft			__read_mostly|
510c5967e98SJoe Perches			__ro_after_init|
5116c72ffaaSAndy Whitcroft			__kprobes|
5128716de38SJoe Perches			$InitAttribute|
51324e1d81aSAndy Whitcroft			____cacheline_aligned|
51424e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
5155fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
51686cffecdSKees Cook			__weak|
51786cffecdSKees Cook			__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
5186c72ffaaSAndy Whitcroft		  }x;
519c45dcabdSAndy Whitcroftour $Modifier;
52091cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
5216c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
5226c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
5236c72ffaaSAndy Whitcroft
52495e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
52595e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
52695e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
52795e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
5282435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
529d2af5aa6SJoe Perchesour $String	= qr{(?:\b[Lu])?"[X\t]*"};
530326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
531326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
532326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
53374349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
5342435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
535326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
536447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
53723f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
5386c72ffaaSAndy Whitcroftour $Operators	= qr{
5396c72ffaaSAndy Whitcroft			<=|>=|==|!=|
5406c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
54123f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
5426c72ffaaSAndy Whitcroft		  }x;
5436c72ffaaSAndy Whitcroft
54491cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
54591cb5195SJoe Perches
546ab7e23f3SJoe Perchesour $BasicType;
5478905a67cSAndy Whitcroftour $NonptrType;
5481813087dSJoe Perchesour $NonptrTypeMisordered;
5498716de38SJoe Perchesour $NonptrTypeWithAttr;
5508905a67cSAndy Whitcroftour $Type;
5511813087dSJoe Perchesour $TypeMisordered;
5528905a67cSAndy Whitcroftour $Declare;
5531813087dSJoe Perchesour $DeclareMisordered;
5548905a67cSAndy Whitcroft
55515662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
55615662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
557171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
558171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
559171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
560171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
561171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
562171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
563171ae1a4SAndy Whitcroft}x;
564171ae1a4SAndy Whitcroft
56515662b3eSJoe Perchesour $UTF8	= qr{
56615662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
56715662b3eSJoe Perches	| $NON_ASCII_UTF8
56815662b3eSJoe Perches}x;
56915662b3eSJoe Perches
570e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
571021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
572021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
573021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
574021158b4SJoe Perches)};
575e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
576fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
5778ed22cadSAndy Whitcroft	atomic_t
5788ed22cadSAndy Whitcroft)};
5798ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x:
5808ea0114eSMickaël Salaün	FILE
5818ea0114eSMickaël Salaün)};
582e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
583e6176fa4SJoe Perches	$typeC99Typedefs\b|
584e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
5858ea0114eSMickaël Salaün	$typeKernelTypedefs\b|
5868ea0114eSMickaël Salaün	$typeStdioTypedefs\b
587e6176fa4SJoe Perches)};
5888ed22cadSAndy Whitcroft
5896d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
5906d32f7a3SJoe Perches
591691e669bSJoe Perchesour $logFunctions = qr{(?x:
592758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
5937d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
59487bd499aSJoe Perches	TP_printk|
5956e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
596b0531722SJoe Perches	panic|
59706668727SJoe Perches	MODULE_[A-Z_]+|
59806668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
599691e669bSJoe Perches)};
600691e669bSJoe Perches
601e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
602e29a70f1SJoe Perches	(?:(?:devm_)?
60358f02267SJoe Perches		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
604e29a70f1SJoe Perches		kstrdup(?:_const)? |
605e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
606461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
607e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
608e29a70f1SJoe Perches	dma_alloc_coherent
609e29a70f1SJoe Perches)};
610e29a70f1SJoe Perches
61120112475SJoe Perchesour $signature_tags = qr{(?xi:
61220112475SJoe Perches	Signed-off-by:|
613d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
61420112475SJoe Perches	Acked-by:|
61520112475SJoe Perches	Tested-by:|
61620112475SJoe Perches	Reviewed-by:|
61720112475SJoe Perches	Reported-by:|
6188543ae12SMugunthan V N	Suggested-by:|
61920112475SJoe Perches	To:|
62020112475SJoe Perches	Cc:
62120112475SJoe Perches)};
62220112475SJoe Perches
623adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
624adb2da82SJoe Perches	[=-]*> |
625adb2da82SJoe Perches	<[=-]* |
626adb2da82SJoe Perches	\[ |
627adb2da82SJoe Perches	\] |
628adb2da82SJoe Perches	start |
629adb2da82SJoe Perches	called |
630adb2da82SJoe Perches	entered |
631adb2da82SJoe Perches	entry |
632adb2da82SJoe Perches	enter |
633adb2da82SJoe Perches	in |
634adb2da82SJoe Perches	inside |
635adb2da82SJoe Perches	here |
636adb2da82SJoe Perches	begin |
637adb2da82SJoe Perches	exit |
638adb2da82SJoe Perches	end |
639adb2da82SJoe Perches	done |
640adb2da82SJoe Perches	leave |
641adb2da82SJoe Perches	completed |
642adb2da82SJoe Perches	out |
643adb2da82SJoe Perches	return |
644adb2da82SJoe Perches	[\.\!:\s]*
645adb2da82SJoe Perches)};
646adb2da82SJoe Perches
647831242abSAditya Srivastavasub edit_distance_min {
648831242abSAditya Srivastava	my (@arr) = @_;
649831242abSAditya Srivastava	my $len = scalar @arr;
650831242abSAditya Srivastava	if ((scalar @arr) < 1) {
651831242abSAditya Srivastava		# if underflow, return
652831242abSAditya Srivastava		return;
653831242abSAditya Srivastava	}
654831242abSAditya Srivastava	my $min = $arr[0];
655831242abSAditya Srivastava	for my $i (0 .. ($len-1)) {
656831242abSAditya Srivastava		if ($arr[$i] < $min) {
657831242abSAditya Srivastava			$min = $arr[$i];
658831242abSAditya Srivastava		}
659831242abSAditya Srivastava	}
660831242abSAditya Srivastava	return $min;
661831242abSAditya Srivastava}
662831242abSAditya Srivastava
663831242abSAditya Srivastavasub get_edit_distance {
664831242abSAditya Srivastava	my ($str1, $str2) = @_;
665831242abSAditya Srivastava	$str1 = lc($str1);
666831242abSAditya Srivastava	$str2 = lc($str2);
667831242abSAditya Srivastava	$str1 =~ s/-//g;
668831242abSAditya Srivastava	$str2 =~ s/-//g;
669831242abSAditya Srivastava	my $len1 = length($str1);
670831242abSAditya Srivastava	my $len2 = length($str2);
671831242abSAditya Srivastava	# two dimensional array storing minimum edit distance
672831242abSAditya Srivastava	my @distance;
673831242abSAditya Srivastava	for my $i (0 .. $len1) {
674831242abSAditya Srivastava		for my $j (0 .. $len2) {
675831242abSAditya Srivastava			if ($i == 0) {
676831242abSAditya Srivastava				$distance[$i][$j] = $j;
677831242abSAditya Srivastava			} elsif ($j == 0) {
678831242abSAditya Srivastava				$distance[$i][$j] = $i;
679831242abSAditya Srivastava			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
680831242abSAditya Srivastava				$distance[$i][$j] = $distance[$i - 1][$j - 1];
681831242abSAditya Srivastava			} else {
682831242abSAditya Srivastava				my $dist1 = $distance[$i][$j - 1]; #insert distance
683831242abSAditya Srivastava				my $dist2 = $distance[$i - 1][$j]; # remove
684831242abSAditya Srivastava				my $dist3 = $distance[$i - 1][$j - 1]; #replace
685831242abSAditya Srivastava				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
686831242abSAditya Srivastava			}
687831242abSAditya Srivastava		}
688831242abSAditya Srivastava	}
689831242abSAditya Srivastava	return $distance[$len1][$len2];
690831242abSAditya Srivastava}
691831242abSAditya Srivastava
692831242abSAditya Srivastavasub find_standard_signature {
693831242abSAditya Srivastava	my ($sign_off) = @_;
694831242abSAditya Srivastava	my @standard_signature_tags = (
695831242abSAditya Srivastava		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
696831242abSAditya Srivastava		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
697831242abSAditya Srivastava	);
698831242abSAditya Srivastava	foreach my $signature (@standard_signature_tags) {
699831242abSAditya Srivastava		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
700831242abSAditya Srivastava	}
701831242abSAditya Srivastava
702831242abSAditya Srivastava	return "";
703831242abSAditya Srivastava}
704831242abSAditya Srivastava
7051813087dSJoe Perchesour @typeListMisordered = (
7061813087dSJoe Perches	qr{char\s+(?:un)?signed},
7071813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
7081813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
7091813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
7101813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
7111813087dSJoe Perches	qr{short\s+(?:un)?signed},
7121813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
7131813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
7141813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
7151813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
7161813087dSJoe Perches	qr{int\s+(?:un)?signed},
7171813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
7181813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
7191813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
7201813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
7211813087dSJoe Perches	qr{long\s+(?:un)?signed},
7221813087dSJoe Perches);
7231813087dSJoe Perches
7248905a67cSAndy Whitcroftour @typeList = (
7258905a67cSAndy Whitcroft	qr{void},
7260c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
7270c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
7280c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
7290c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
7300c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
7310c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
7320c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
7330c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
7340c773d9dSJoe Perches	qr{(?:un)?signed},
7358905a67cSAndy Whitcroft	qr{float},
7368905a67cSAndy Whitcroft	qr{double},
7378905a67cSAndy Whitcroft	qr{bool},
7388905a67cSAndy Whitcroft	qr{struct\s+$Ident},
7398905a67cSAndy Whitcroft	qr{union\s+$Ident},
7408905a67cSAndy Whitcroft	qr{enum\s+$Ident},
7418905a67cSAndy Whitcroft	qr{${Ident}_t},
7428905a67cSAndy Whitcroft	qr{${Ident}_handler},
7438905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
7441813087dSJoe Perches	@typeListMisordered,
7458905a67cSAndy Whitcroft);
746938224b5SJoe Perches
747938224b5SJoe Perchesour $C90_int_types = qr{(?x:
748938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
749938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
750938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
751938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
752938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
753938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
754938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
755938224b5SJoe Perches
756938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
757938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
758938224b5SJoe Perches	long\s+(?:un)?signed|
759938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
760938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
761938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
762938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
763938224b5SJoe Perches
764938224b5SJoe Perches	int\s+(?:un)?signed|
765938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
766938224b5SJoe Perches)};
767938224b5SJoe Perches
768485ff23eSAlex Dowadour @typeListFile = ();
7698716de38SJoe Perchesour @typeListWithAttr = (
7708716de38SJoe Perches	@typeList,
7718716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
7728716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
7738716de38SJoe Perches);
7748716de38SJoe Perches
775c45dcabdSAndy Whitcroftour @modifierList = (
776c45dcabdSAndy Whitcroft	qr{fastcall},
777c45dcabdSAndy Whitcroft);
778485ff23eSAlex Dowadour @modifierListFile = ();
7798905a67cSAndy Whitcroft
7802435880fSJoe Perchesour @mode_permission_funcs = (
7812435880fSJoe Perches	["module_param", 3],
7822435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
7832435880fSJoe Perches	["module_param_array_named", 5],
7842435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
7852435880fSJoe Perches	["proc_create(?:_data|)", 2],
786459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
787459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
788459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
789459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
790459cf0aeSJoe Perches	["__ATTR", 2],
7912435880fSJoe Perches);
7922435880fSJoe Perches
7931a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
7941a3dcf2eSJoe Perches
795515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
796515a235eSJoe Perchesour $mode_perms_search = "";
797515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
798515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
799515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
800515a235eSJoe Perches}
80100180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
802515a235eSJoe Perches
8039189c7e7SJoe Perchesour %deprecated_apis = (
8049189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
8059189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
8069189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
8079189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
8089189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
8099189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
8109189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
8119189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
8129189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
8139189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
814defdaff1SIra Weiny	"kmap"					=> "kmap_local_page",
815defdaff1SIra Weiny	"kmap_atomic"				=> "kmap_local_page",
8169189c7e7SJoe Perches);
8179189c7e7SJoe Perches
8189189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
8199189c7e7SJoe Perchesour $deprecated_apis_search = "";
8209189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
8219189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
8229189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
8239189c7e7SJoe Perches}
8249189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
8259189c7e7SJoe Perches
826b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
827b392c64fSJoe Perches	S_IWUGO		|
828b392c64fSJoe Perches	S_IWOTH		|
829b392c64fSJoe Perches	S_IRWXUGO	|
830b392c64fSJoe Perches	S_IALLUGO	|
831b392c64fSJoe Perches	0[0-7][0-7][2367]
832b392c64fSJoe Perches}x;
833b392c64fSJoe Perches
834f90774e1SJoe Perchesour %mode_permission_string_types = (
835f90774e1SJoe Perches	"S_IRWXU" => 0700,
836f90774e1SJoe Perches	"S_IRUSR" => 0400,
837f90774e1SJoe Perches	"S_IWUSR" => 0200,
838f90774e1SJoe Perches	"S_IXUSR" => 0100,
839f90774e1SJoe Perches	"S_IRWXG" => 0070,
840f90774e1SJoe Perches	"S_IRGRP" => 0040,
841f90774e1SJoe Perches	"S_IWGRP" => 0020,
842f90774e1SJoe Perches	"S_IXGRP" => 0010,
843f90774e1SJoe Perches	"S_IRWXO" => 0007,
844f90774e1SJoe Perches	"S_IROTH" => 0004,
845f90774e1SJoe Perches	"S_IWOTH" => 0002,
846f90774e1SJoe Perches	"S_IXOTH" => 0001,
847f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
848f90774e1SJoe Perches	"S_IRUGO" => 0444,
849f90774e1SJoe Perches	"S_IWUGO" => 0222,
850f90774e1SJoe Perches	"S_IXUGO" => 0111,
851f90774e1SJoe Perches);
852f90774e1SJoe Perches
853f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
854f90774e1SJoe Perchesour $mode_perms_string_search = "";
855f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
856f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
857f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
858f90774e1SJoe Perches}
85900180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
86000180468SJoe Perchesour $multi_mode_perms_string_search = qr{
86100180468SJoe Perches	${single_mode_perms_string_search}
86200180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
86300180468SJoe Perches}x;
86400180468SJoe Perches
86500180468SJoe Perchessub perms_to_octal {
86600180468SJoe Perches	my ($string) = @_;
86700180468SJoe Perches
86800180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
86900180468SJoe Perches
87000180468SJoe Perches	my $val = "";
87100180468SJoe Perches	my $oval = "";
87200180468SJoe Perches	my $to = 0;
87300180468SJoe Perches	my $curpos = 0;
87400180468SJoe Perches	my $lastpos = 0;
87500180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
87600180468SJoe Perches		$curpos = pos($string);
87700180468SJoe Perches		my $match = $2;
87800180468SJoe Perches		my $omatch = $1;
87900180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
88000180468SJoe Perches		$lastpos = $curpos;
88100180468SJoe Perches		$to |= $mode_permission_string_types{$match};
88200180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
88300180468SJoe Perches		$val .= $match;
88400180468SJoe Perches		$oval .= $omatch;
88500180468SJoe Perches	}
88600180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
88700180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
88800180468SJoe Perches	return sprintf("%04o", $to);
88900180468SJoe Perches}
890f90774e1SJoe Perches
8917840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
8927840a94cSWolfram Sang	irq|
893cdcee686SSergey Ryazanov	memory|
894cdcee686SSergey Ryazanov	time|
895cdcee686SSergey Ryazanov	reboot
8967840a94cSWolfram Sang)};
8977840a94cSWolfram Sang# memory.h: ARM has a custom one
8987840a94cSWolfram Sang
89966b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
90066b47b4aSKees Cookmy $misspellings;
90166b47b4aSKees Cookmy %spelling_fix;
90236061e38SJoe Perches
90336061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
90466b47b4aSKees Cook	while (<$spelling>) {
90566b47b4aSKees Cook		my $line = $_;
90666b47b4aSKees Cook
90766b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
90866b47b4aSKees Cook		$line =~ s/^\s*//g;
90966b47b4aSKees Cook
91066b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
91166b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
91266b47b4aSKees Cook
91366b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
91466b47b4aSKees Cook
91566b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
91666b47b4aSKees Cook	}
91766b47b4aSKees Cook	close($spelling);
91836061e38SJoe Perches} else {
91936061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
92036061e38SJoe Perches}
92166b47b4aSKees Cook
922ebfd7d62SJoe Perchesif ($codespell) {
923ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
924ebfd7d62SJoe Perches		while (<$spelling>) {
925ebfd7d62SJoe Perches			my $line = $_;
926ebfd7d62SJoe Perches
927ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
928ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
929ebfd7d62SJoe Perches
930ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
931ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
932ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
933ebfd7d62SJoe Perches
934ebfd7d62SJoe Perches			$line =~ s/,.*$//;
935ebfd7d62SJoe Perches
936ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
937ebfd7d62SJoe Perches
938ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
939ebfd7d62SJoe Perches		}
940ebfd7d62SJoe Perches		close($spelling);
941ebfd7d62SJoe Perches	} else {
942ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
943ebfd7d62SJoe Perches	}
944ebfd7d62SJoe Perches}
945ebfd7d62SJoe Perches
946ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
947ebfd7d62SJoe Perches
94875ad8c57SJerome Forissiersub read_words {
94975ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
95075ad8c57SJerome Forissier
95175ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
95275ad8c57SJerome Forissier		while (<$words>) {
953bf1fa1daSJoe Perches			my $line = $_;
954bf1fa1daSJoe Perches
955bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
956bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
957bf1fa1daSJoe Perches
958bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
959bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
960bf1fa1daSJoe Perches			if ($line =~ /\s/) {
96175ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
962bf1fa1daSJoe Perches				next;
963bf1fa1daSJoe Perches			}
964bf1fa1daSJoe Perches
965ced69da1SQuentin Monnet			$$wordsRef .= '|' if (defined $$wordsRef);
96675ad8c57SJerome Forissier			$$wordsRef .= $line;
967bf1fa1daSJoe Perches		}
96875ad8c57SJerome Forissier		close($file);
96975ad8c57SJerome Forissier		return 1;
970bf1fa1daSJoe Perches	}
971bf1fa1daSJoe Perches
97275ad8c57SJerome Forissier	return 0;
97375ad8c57SJerome Forissier}
97475ad8c57SJerome Forissier
975ced69da1SQuentin Monnetmy $const_structs;
976ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) {
97775ad8c57SJerome Forissier	read_words(\$const_structs, $conststructsfile)
97875ad8c57SJerome Forissier	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
979ced69da1SQuentin Monnet}
98075ad8c57SJerome Forissier
981ced69da1SQuentin Monnetif (defined($typedefsfile)) {
982ced69da1SQuentin Monnet	my $typeOtherTypedefs;
98375ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
98475ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
985ced69da1SQuentin Monnet	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
98675ad8c57SJerome Forissier}
98775ad8c57SJerome Forissier
9888905a67cSAndy Whitcroftsub build_types {
989485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
990485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
9911813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
9928716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
993c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
994ab7e23f3SJoe Perches	$BasicType	= qr{
995ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
996ab7e23f3SJoe Perches				(?:${all}\b)
997ab7e23f3SJoe Perches		}x;
9988905a67cSAndy Whitcroft	$NonptrType	= qr{
999d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
1000cf655043SAndy Whitcroft			(?:
10016b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
10028ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
1003c45dcabdSAndy Whitcroft				(?:${all}\b)
1004cf655043SAndy Whitcroft			)
1005c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
10068905a67cSAndy Whitcroft		  }x;
10071813087dSJoe Perches	$NonptrTypeMisordered	= qr{
10081813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
10091813087dSJoe Perches			(?:
10101813087dSJoe Perches				(?:${Misordered}\b)
10111813087dSJoe Perches			)
10121813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
10131813087dSJoe Perches		  }x;
10148716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
10158716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
10168716de38SJoe Perches			(?:
10178716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
10188716de38SJoe Perches				(?:$typeTypedefs\b)|
10198716de38SJoe Perches				(?:${allWithAttr}\b)
10208716de38SJoe Perches			)
10218716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
10228716de38SJoe Perches		  }x;
10238905a67cSAndy Whitcroft	$Type	= qr{
1024c45dcabdSAndy Whitcroft			$NonptrType
10257b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
1026c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
10278905a67cSAndy Whitcroft		  }x;
10281813087dSJoe Perches	$TypeMisordered	= qr{
10291813087dSJoe Perches			$NonptrTypeMisordered
10307b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
10311813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
10321813087dSJoe Perches		  }x;
103391cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
10341813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
10358905a67cSAndy Whitcroft}
10368905a67cSAndy Whitcroftbuild_types();
10376c72ffaaSAndy Whitcroft
10387d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
1039d1fe9c09SJoe Perches
1040d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1041d1fe9c09SJoe Perches# requires at least perl version v5.10.0
1042d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
1043d1fe9c09SJoe Perches
1044d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
10452435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
1046c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
10477d2367afSJoe Perches
1048f8422308SJoe Perchesour $declaration_macros = qr{(?x:
10493e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
1050fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
1051dcea7964SJoe Perches	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(|
1052dcea7964SJoe Perches	(?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\(
1053f8422308SJoe Perches)};
1054f8422308SJoe Perches
10558d0325ccSAditya Srivastavaour %allow_repeated_words = (
10568d0325ccSAditya Srivastava	add => '',
10578d0325ccSAditya Srivastava	added => '',
10588d0325ccSAditya Srivastava	bad => '',
10598d0325ccSAditya Srivastava	be => '',
10608d0325ccSAditya Srivastava);
10618d0325ccSAditya Srivastava
10627d2367afSJoe Perchessub deparenthesize {
10637d2367afSJoe Perches	my ($string) = @_;
10647d2367afSJoe Perches	return "" if (!defined($string));
10655b9553abSJoe Perches
10665b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
10675b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
10685b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
10695b9553abSJoe Perches	}
10705b9553abSJoe Perches
10717d2367afSJoe Perches	$string =~ s@\s+@ @g;
10725b9553abSJoe Perches
10737d2367afSJoe Perches	return $string;
10747d2367afSJoe Perches}
10757d2367afSJoe Perches
10763445686aSJoe Perchessub seed_camelcase_file {
10773445686aSJoe Perches	my ($file) = @_;
10783445686aSJoe Perches
10793445686aSJoe Perches	return if (!(-f $file));
10803445686aSJoe Perches
10813445686aSJoe Perches	local $/;
10823445686aSJoe Perches
10833445686aSJoe Perches	open(my $include_file, '<', "$file")
10843445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
10853445686aSJoe Perches	my $text = <$include_file>;
10863445686aSJoe Perches	close($include_file);
10873445686aSJoe Perches
10883445686aSJoe Perches	my @lines = split('\n', $text);
10893445686aSJoe Perches
10903445686aSJoe Perches	foreach my $line (@lines) {
10913445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
10923445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
10933445686aSJoe Perches			$camelcase{$1} = 1;
109411ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
109511ea516aSJoe Perches			$camelcase{$1} = 1;
109611ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
10973445686aSJoe Perches			$camelcase{$1} = 1;
10983445686aSJoe Perches		}
10993445686aSJoe Perches	}
11003445686aSJoe Perches}
11013445686aSJoe Perches
1102cd28b119SJoe Perchesour %maintained_status = ();
1103cd28b119SJoe Perches
110485b0ee18SJoe Perchessub is_maintained_obsolete {
110585b0ee18SJoe Perches	my ($filename) = @_;
110685b0ee18SJoe Perches
1107f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
110885b0ee18SJoe Perches
1109cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
1110cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1111cd28b119SJoe Perches	}
111285b0ee18SJoe Perches
1113cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
111485b0ee18SJoe Perches}
111585b0ee18SJoe Perches
11163b6e8ac9SJoe Perchessub is_SPDX_License_valid {
11173b6e8ac9SJoe Perches	my ($license) = @_;
11183b6e8ac9SJoe Perches
1119f9363b31SGuenter Roeck	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
11203b6e8ac9SJoe Perches
112156294112SJoe Perches	my $root_path = abs_path($root);
1122f9363b31SGuenter Roeck	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
11233b6e8ac9SJoe Perches	return 0 if ($status ne "");
11243b6e8ac9SJoe Perches	return 1;
11253b6e8ac9SJoe Perches}
11263b6e8ac9SJoe Perches
11273445686aSJoe Perchesmy $camelcase_seeded = 0;
11283445686aSJoe Perchessub seed_camelcase_includes {
11293445686aSJoe Perches	return if ($camelcase_seeded);
11303445686aSJoe Perches
11313445686aSJoe Perches	my $files;
1132c707a81dSJoe Perches	my $camelcase_cache = "";
1133c707a81dSJoe Perches	my @include_files = ();
1134c707a81dSJoe Perches
1135c707a81dSJoe Perches	$camelcase_seeded = 1;
1136351b2a1fSJoe Perches
11370f7f635bSJoe Perches	if (-e "$gitroot") {
1138dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1139351b2a1fSJoe Perches		chomp $git_last_include_commit;
1140c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1141c707a81dSJoe Perches	} else {
1142c707a81dSJoe Perches		my $last_mod_date = 0;
1143c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
1144c707a81dSJoe Perches		@include_files = split('\n', $files);
1145c707a81dSJoe Perches		foreach my $file (@include_files) {
1146c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
1147c707a81dSJoe Perches						   localtime((stat $file)[9]));
1148c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
1149c707a81dSJoe Perches		}
1150c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1151c707a81dSJoe Perches	}
1152c707a81dSJoe Perches
1153c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1154c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
1155c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1156351b2a1fSJoe Perches		while (<$camelcase_file>) {
1157351b2a1fSJoe Perches			chomp;
1158351b2a1fSJoe Perches			$camelcase{$_} = 1;
1159351b2a1fSJoe Perches		}
1160351b2a1fSJoe Perches		close($camelcase_file);
1161351b2a1fSJoe Perches
1162351b2a1fSJoe Perches		return;
1163351b2a1fSJoe Perches	}
1164c707a81dSJoe Perches
11650f7f635bSJoe Perches	if (-e "$gitroot") {
1166dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
1167c707a81dSJoe Perches		@include_files = split('\n', $files);
11683445686aSJoe Perches	}
1169c707a81dSJoe Perches
11703445686aSJoe Perches	foreach my $file (@include_files) {
11713445686aSJoe Perches		seed_camelcase_file($file);
11723445686aSJoe Perches	}
1173351b2a1fSJoe Perches
1174c707a81dSJoe Perches	if ($camelcase_cache ne "") {
1175351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
1176c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
1177c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1178351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1179351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
1180351b2a1fSJoe Perches		}
1181351b2a1fSJoe Perches		close($camelcase_file);
1182351b2a1fSJoe Perches	}
11833445686aSJoe Perches}
11843445686aSJoe Perches
1185f5f61325SJoe Perchessub git_is_single_file {
1186f5f61325SJoe Perches	my ($filename) = @_;
1187f5f61325SJoe Perches
1188f5f61325SJoe Perches	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1189f5f61325SJoe Perches
1190f5f61325SJoe Perches	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1191f5f61325SJoe Perches	my $count = $output =~ tr/\n//;
1192f5f61325SJoe Perches	return $count eq 1 && $output =~ m{^${filename}$};
1193f5f61325SJoe Perches}
1194f5f61325SJoe Perches
1195d311cd44SJoe Perchessub git_commit_info {
1196d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
1197d311cd44SJoe Perches
11980f7f635bSJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1199d311cd44SJoe Perches
1200dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1201d311cd44SJoe Perches	$output =~ s/^\s*//gm;
1202d311cd44SJoe Perches	my @lines = split("\n", $output);
1203d311cd44SJoe Perches
12040d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
12050d7835fcSJoe Perches
12065a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1207d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
1208d311cd44SJoe Perches# all matching commit ids, but it's very slow...
1209d311cd44SJoe Perches#
1210d311cd44SJoe Perches#		echo "checking commits $1..."
1211d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
1212d311cd44SJoe Perches#		while read line ; do
1213d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
1214d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
1215d311cd44SJoe Perches#		done
12164ce9f970SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
12174ce9f970SJoe Perches		 $lines[0] =~ /^fatal: bad object $commit/) {
1218948b133aSHeinrich Schuchardt		$id = undef;
1219d311cd44SJoe Perches	} else {
1220d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1221d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1222d311cd44SJoe Perches	}
1223d311cd44SJoe Perches
1224d311cd44SJoe Perches	return ($id, $desc);
1225d311cd44SJoe Perches}
1226d311cd44SJoe Perches
12276c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
12280a920b5bSAndy Whitcroft
122900df344fSAndy Whitcroftmy @rawlines = ();
1230c2fdda0dSAndy Whitcroftmy @lines = ();
12313705ce5bSJoe Perchesmy @fixed = ();
1232d752fcc8SJoe Perchesmy @fixed_inserted = ();
1233d752fcc8SJoe Perchesmy @fixed_deleted = ();
1234194f66fcSJoe Perchesmy $fixlinenr = -1;
1235194f66fcSJoe Perches
12364a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
12374a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
12380f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
12394a593c34SDu, Changbin
12404a593c34SDu, Changbinif ($git) {
12414a593c34SDu, Changbin	my @commits = ();
12420dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
12434a593c34SDu, Changbin		my $git_range;
124428898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
124528898fd1SJoe Perches			$git_range = "-$2 $1";
12464a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
12474a593c34SDu, Changbin			$git_range = "$commit_expr";
12484a593c34SDu, Changbin		} else {
12490dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
12500dea9f1eSJoe Perches		}
1251dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
12520dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
125328898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
125428898fd1SJoe Perches			next if (!defined($1) || !defined($2));
12550dea9f1eSJoe Perches			my $sha1 = $1;
12560dea9f1eSJoe Perches			my $subject = $2;
12570dea9f1eSJoe Perches			unshift(@commits, $sha1);
12580dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
12594a593c34SDu, Changbin		}
12604a593c34SDu, Changbin	}
12614a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
12624a593c34SDu, Changbin	@ARGV = @commits;
12634a593c34SDu, Changbin}
12644a593c34SDu, Changbin
1265c2fdda0dSAndy Whitcroftmy $vname;
126698005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
12676c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
126821caa13cSAndy Whitcroft	my $FILE;
1269f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1270f5f61325SJoe Perches	my $oldfile = $file;
1271f5f61325SJoe Perches	$file = 1 if ($is_git_file);
12724a593c34SDu, Changbin	if ($git) {
12734a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
12744a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
12754a593c34SDu, Changbin	} elsif ($file) {
127621caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
12776c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
127821caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
127921caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
12806c72ffaaSAndy Whitcroft	} else {
128121caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
12826c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
12836c72ffaaSAndy Whitcroft	}
1284c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1285c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
12864a593c34SDu, Changbin	} elsif ($git) {
12870dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1288c2fdda0dSAndy Whitcroft	} else {
1289c2fdda0dSAndy Whitcroft		$vname = $filename;
1290c2fdda0dSAndy Whitcroft	}
129121caa13cSAndy Whitcroft	while (<$FILE>) {
12920a920b5bSAndy Whitcroft		chomp;
129300df344fSAndy Whitcroft		push(@rawlines, $_);
1294c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
12956c72ffaaSAndy Whitcroft	}
129621caa13cSAndy Whitcroft	close($FILE);
1297d8469f16SJoe Perches
1298d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1299d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1300d8469f16SJoe Perches		print "$vname\n";
1301d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1302d8469f16SJoe Perches	}
1303d8469f16SJoe Perches
1304c2fdda0dSAndy Whitcroft	if (!process($filename)) {
13050a920b5bSAndy Whitcroft		$exit = 1;
13060a920b5bSAndy Whitcroft	}
130700df344fSAndy Whitcroft	@rawlines = ();
130813214adfSAndy Whitcroft	@lines = ();
13093705ce5bSJoe Perches	@fixed = ();
1310d752fcc8SJoe Perches	@fixed_inserted = ();
1311d752fcc8SJoe Perches	@fixed_deleted = ();
1312194f66fcSJoe Perches	$fixlinenr = -1;
1313485ff23eSAlex Dowad	@modifierListFile = ();
1314485ff23eSAlex Dowad	@typeListFile = ();
1315485ff23eSAlex Dowad	build_types();
1316f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
13170a920b5bSAndy Whitcroft}
13180a920b5bSAndy Whitcroft
1319d8469f16SJoe Perchesif (!$quiet) {
13203c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
13213c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
13223c816e49SJoe Perches
13235b57980dSJoe Perches	if (!$perl_version_ok) {
1324d8469f16SJoe Perches		print << "EOM"
1325d8469f16SJoe Perches
1326d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
13275b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1328d8469f16SJoe PerchesEOM
1329d8469f16SJoe Perches	}
1330d8469f16SJoe Perches	if ($exit) {
1331d8469f16SJoe Perches		print << "EOM"
1332d8469f16SJoe Perches
1333d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1334d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1335d8469f16SJoe PerchesEOM
1336d8469f16SJoe Perches	}
1337d8469f16SJoe Perches}
1338d8469f16SJoe Perches
13390a920b5bSAndy Whitcroftexit($exit);
13400a920b5bSAndy Whitcroft
13410a920b5bSAndy Whitcroftsub top_of_kernel_tree {
13426c72ffaaSAndy Whitcroft	my ($root) = @_;
13436c72ffaaSAndy Whitcroft
13446c72ffaaSAndy Whitcroft	my @tree_check = (
13456c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
13466c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
13476c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
13486c72ffaaSAndy Whitcroft	);
13496c72ffaaSAndy Whitcroft
13506c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
13516c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
13520a920b5bSAndy Whitcroft			return 0;
13530a920b5bSAndy Whitcroft		}
13546c72ffaaSAndy Whitcroft	}
13556c72ffaaSAndy Whitcroft	return 1;
13566c72ffaaSAndy Whitcroft}
13570a920b5bSAndy Whitcroft
135820112475SJoe Perchessub parse_email {
135920112475SJoe Perches	my ($formatted_email) = @_;
136020112475SJoe Perches
136120112475SJoe Perches	my $name = "";
1362fccaebf0SDwaipayan Ray	my $quoted = "";
1363dfa05c28SJoe Perches	my $name_comment = "";
136420112475SJoe Perches	my $address = "";
136520112475SJoe Perches	my $comment = "";
136620112475SJoe Perches
136720112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
136820112475SJoe Perches		$name = $1;
136920112475SJoe Perches		$address = $2;
137020112475SJoe Perches		$comment = $3 if defined $3;
137120112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
137220112475SJoe Perches		$address = $1;
137320112475SJoe Perches		$comment = $2 if defined $2;
137420112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
137520112475SJoe Perches		$address = $1;
137620112475SJoe Perches		$comment = $2 if defined $2;
137785e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
137820112475SJoe Perches		$name = $formatted_email;
13793705ce5bSJoe Perches		$name = trim($name);
138020112475SJoe Perches		$name =~ s/^\"|\"$//g;
138120112475SJoe Perches		# If there's a name left after stripping spaces and
138220112475SJoe Perches		# leading quotes, and the address doesn't have both
138320112475SJoe Perches		# leading and trailing angle brackets, the address
138420112475SJoe Perches		# is invalid. ie:
138520112475SJoe Perches		#   "joe smith [email protected]" bad
138620112475SJoe Perches		#   "joe smith <[email protected]" bad
138720112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
138820112475SJoe Perches			$name = "";
138920112475SJoe Perches			$address = "";
139020112475SJoe Perches			$comment = "";
139120112475SJoe Perches		}
139220112475SJoe Perches	}
139320112475SJoe Perches
1394fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1395fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1396fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1397fccaebf0SDwaipayan Ray		$quoted = $1;
1398dfa05c28SJoe Perches	}
1399fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1400fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1401fccaebf0SDwaipayan Ray	}
1402fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1403fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1404fccaebf0SDwaipayan Ray
14053705ce5bSJoe Perches	$address = trim($address);
140620112475SJoe Perches	$address =~ s/^\<|\>$//g;
1407fccaebf0SDwaipayan Ray	$comment = trim($comment);
140820112475SJoe Perches
140920112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
141020112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
141120112475SJoe Perches		$name = "\"$name\"";
141220112475SJoe Perches	}
141320112475SJoe Perches
1414dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
141520112475SJoe Perches}
141620112475SJoe Perches
141720112475SJoe Perchessub format_email {
141848ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
141920112475SJoe Perches
142020112475SJoe Perches	my $formatted_email;
142120112475SJoe Perches
1422fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
14233705ce5bSJoe Perches	$address = trim($address);
1424fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
142520112475SJoe Perches
142620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
142720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
142820112475SJoe Perches		$name = "\"$name\"";
142920112475SJoe Perches	}
143020112475SJoe Perches
1431fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1432fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1433fccaebf0SDwaipayan Ray	$comment = trim($comment);
1434fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1435fccaebf0SDwaipayan Ray
143620112475SJoe Perches	if ("$name" eq "") {
143720112475SJoe Perches		$formatted_email = "$address";
143820112475SJoe Perches	} else {
143948ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
144020112475SJoe Perches	}
144148ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
144220112475SJoe Perches	return $formatted_email;
144320112475SJoe Perches}
144420112475SJoe Perches
1445dfa05c28SJoe Perchessub reformat_email {
1446dfa05c28SJoe Perches	my ($email) = @_;
1447dfa05c28SJoe Perches
1448dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
144948ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1450dfa05c28SJoe Perches}
1451dfa05c28SJoe Perches
1452dfa05c28SJoe Perchessub same_email_addresses {
1453fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1454dfa05c28SJoe Perches
1455dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1456dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1457dfa05c28SJoe Perches
145848ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
145948ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
146048ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
146148ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
146248ca2d8aSDwaipayan Ray}
1463dfa05c28SJoe Perches
1464d311cd44SJoe Perchessub which {
1465d311cd44SJoe Perches	my ($bin) = @_;
1466d311cd44SJoe Perches
1467d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1468d311cd44SJoe Perches		if (-e "$path/$bin") {
1469d311cd44SJoe Perches			return "$path/$bin";
1470d311cd44SJoe Perches		}
1471d311cd44SJoe Perches	}
1472d311cd44SJoe Perches
1473d311cd44SJoe Perches	return "";
1474d311cd44SJoe Perches}
1475d311cd44SJoe Perches
1476000d1cc1SJoe Perchessub which_conf {
1477000d1cc1SJoe Perches	my ($conf) = @_;
1478000d1cc1SJoe Perches
1479000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1480000d1cc1SJoe Perches		if (-e "$path/$conf") {
1481000d1cc1SJoe Perches			return "$path/$conf";
1482000d1cc1SJoe Perches		}
1483000d1cc1SJoe Perches	}
1484000d1cc1SJoe Perches
1485000d1cc1SJoe Perches	return "";
1486000d1cc1SJoe Perches}
1487000d1cc1SJoe Perches
14880a920b5bSAndy Whitcroftsub expand_tabs {
14890a920b5bSAndy Whitcroft	my ($str) = @_;
14900a920b5bSAndy Whitcroft
14910a920b5bSAndy Whitcroft	my $res = '';
14920a920b5bSAndy Whitcroft	my $n = 0;
14930a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
14940a920b5bSAndy Whitcroft		if ($c eq "\t") {
14950a920b5bSAndy Whitcroft			$res .= ' ';
14960a920b5bSAndy Whitcroft			$n++;
1497713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
14980a920b5bSAndy Whitcroft				$res .= ' ';
14990a920b5bSAndy Whitcroft			}
15000a920b5bSAndy Whitcroft			next;
15010a920b5bSAndy Whitcroft		}
15020a920b5bSAndy Whitcroft		$res .= $c;
15030a920b5bSAndy Whitcroft		$n++;
15040a920b5bSAndy Whitcroft	}
15050a920b5bSAndy Whitcroft
15060a920b5bSAndy Whitcroft	return $res;
15070a920b5bSAndy Whitcroft}
15086c72ffaaSAndy Whitcroftsub copy_spacing {
1509773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
15106c72ffaaSAndy Whitcroft	return $res;
15116c72ffaaSAndy Whitcroft}
15120a920b5bSAndy Whitcroft
15134a0df2efSAndy Whitcroftsub line_stats {
15144a0df2efSAndy Whitcroft	my ($line) = @_;
15154a0df2efSAndy Whitcroft
15164a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
15174a0df2efSAndy Whitcroft	$line =~ s/^.//;
15184a0df2efSAndy Whitcroft	$line = expand_tabs($line);
15194a0df2efSAndy Whitcroft
15204a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
15214a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
15224a0df2efSAndy Whitcroft
15234a0df2efSAndy Whitcroft	return (length($line), length($white));
15244a0df2efSAndy Whitcroft}
15254a0df2efSAndy Whitcroft
1526773647a0SAndy Whitcroftmy $sanitise_quote = '';
1527773647a0SAndy Whitcroft
1528773647a0SAndy Whitcroftsub sanitise_line_reset {
1529773647a0SAndy Whitcroft	my ($in_comment) = @_;
1530773647a0SAndy Whitcroft
1531773647a0SAndy Whitcroft	if ($in_comment) {
1532773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1533773647a0SAndy Whitcroft	} else {
1534773647a0SAndy Whitcroft		$sanitise_quote = '';
1535773647a0SAndy Whitcroft	}
1536773647a0SAndy Whitcroft}
153700df344fSAndy Whitcroftsub sanitise_line {
153800df344fSAndy Whitcroft	my ($line) = @_;
153900df344fSAndy Whitcroft
154000df344fSAndy Whitcroft	my $res = '';
154100df344fSAndy Whitcroft	my $l = '';
154200df344fSAndy Whitcroft
1543c2fdda0dSAndy Whitcroft	my $qlen = 0;
1544773647a0SAndy Whitcroft	my $off = 0;
1545773647a0SAndy Whitcroft	my $c;
154600df344fSAndy Whitcroft
1547773647a0SAndy Whitcroft	# Always copy over the diff marker.
1548773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1549773647a0SAndy Whitcroft
1550773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1551773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1552773647a0SAndy Whitcroft
15538d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1554773647a0SAndy Whitcroft		# and end, all to $;.
1555773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1556773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1557773647a0SAndy Whitcroft
1558773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1559773647a0SAndy Whitcroft			$off++;
156000df344fSAndy Whitcroft			next;
1561773647a0SAndy Whitcroft		}
156281bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1563773647a0SAndy Whitcroft			$sanitise_quote = '';
1564773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1565773647a0SAndy Whitcroft			$off++;
1566773647a0SAndy Whitcroft			next;
1567773647a0SAndy Whitcroft		}
1568113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1569113f04a8SDaniel Walker			$sanitise_quote = '//';
1570113f04a8SDaniel Walker
1571113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1572113f04a8SDaniel Walker			$off++;
1573113f04a8SDaniel Walker			next;
1574113f04a8SDaniel Walker		}
1575773647a0SAndy Whitcroft
1576773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1577773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1578773647a0SAndy Whitcroft		    $c eq "\\") {
1579773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1580773647a0SAndy Whitcroft			$off++;
1581773647a0SAndy Whitcroft			next;
1582773647a0SAndy Whitcroft		}
1583773647a0SAndy Whitcroft		# Regular quotes.
1584773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1585773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1586773647a0SAndy Whitcroft				$sanitise_quote = $c;
1587773647a0SAndy Whitcroft
1588773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1589773647a0SAndy Whitcroft				next;
1590773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1591773647a0SAndy Whitcroft				$sanitise_quote = '';
159200df344fSAndy Whitcroft			}
159300df344fSAndy Whitcroft		}
1594773647a0SAndy Whitcroft
1595fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1596773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1597773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1598113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1599113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1600773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1601773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
160200df344fSAndy Whitcroft		} else {
1603773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
160400df344fSAndy Whitcroft		}
1605c2fdda0dSAndy Whitcroft	}
1606c2fdda0dSAndy Whitcroft
1607113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1608113f04a8SDaniel Walker		$sanitise_quote = '';
1609113f04a8SDaniel Walker	}
1610113f04a8SDaniel Walker
1611c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1612c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1613c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1614c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1615c2fdda0dSAndy Whitcroft
1616c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1617c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1618c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1619c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1620c2fdda0dSAndy Whitcroft	}
1621c2fdda0dSAndy Whitcroft
1622dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1623dadf680dSJoe Perches		my $match = $1;
1624dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1625dadf680dSJoe Perches	}
1626dadf680dSJoe Perches
162700df344fSAndy Whitcroft	return $res;
162800df344fSAndy Whitcroft}
162900df344fSAndy Whitcroft
1630a6962d72SJoe Perchessub get_quoted_string {
1631a6962d72SJoe Perches	my ($line, $rawline) = @_;
1632a6962d72SJoe Perches
1633478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
163433acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1635a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1636a6962d72SJoe Perches}
1637a6962d72SJoe Perches
16388905a67cSAndy Whitcroftsub ctx_statement_block {
16398905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16408905a67cSAndy Whitcroft	my $line = $linenr - 1;
16418905a67cSAndy Whitcroft	my $blk = '';
16428905a67cSAndy Whitcroft	my $soff = $off;
16438905a67cSAndy Whitcroft	my $coff = $off - 1;
1644773647a0SAndy Whitcroft	my $coff_set = 0;
16458905a67cSAndy Whitcroft
164613214adfSAndy Whitcroft	my $loff = 0;
164713214adfSAndy Whitcroft
16488905a67cSAndy Whitcroft	my $type = '';
16498905a67cSAndy Whitcroft	my $level = 0;
1650a2750645SAndy Whitcroft	my @stack = ();
1651cf655043SAndy Whitcroft	my $p;
16528905a67cSAndy Whitcroft	my $c;
16538905a67cSAndy Whitcroft	my $len = 0;
165413214adfSAndy Whitcroft
165513214adfSAndy Whitcroft	my $remainder;
16568905a67cSAndy Whitcroft	while (1) {
1657a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1658a2750645SAndy Whitcroft
1659773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
16608905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
16618905a67cSAndy Whitcroft		# context.
16628905a67cSAndy Whitcroft		if ($off >= $len) {
16638905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1664dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1665c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
16668905a67cSAndy Whitcroft				$remain--;
166713214adfSAndy Whitcroft				$loff = $len;
1668c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
16698905a67cSAndy Whitcroft				$len = length($blk);
16708905a67cSAndy Whitcroft				$line++;
16718905a67cSAndy Whitcroft				last;
16728905a67cSAndy Whitcroft			}
16738905a67cSAndy Whitcroft			# Bail if there is no further context.
16748905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
167513214adfSAndy Whitcroft			if ($off >= $len) {
16768905a67cSAndy Whitcroft				last;
16778905a67cSAndy Whitcroft			}
1678f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1679f74bd194SAndy Whitcroft				$level++;
1680f74bd194SAndy Whitcroft				$type = '#';
1681f74bd194SAndy Whitcroft			}
16828905a67cSAndy Whitcroft		}
1683cf655043SAndy Whitcroft		$p = $c;
16848905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
168513214adfSAndy Whitcroft		$remainder = substr($blk, $off);
16868905a67cSAndy Whitcroft
1687773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
16884635f4fbSAndy Whitcroft
16894635f4fbSAndy Whitcroft		# Handle nested #if/#else.
16904635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
16914635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
16924635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
16934635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
16944635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
16954635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
16964635f4fbSAndy Whitcroft		}
16974635f4fbSAndy Whitcroft
16988905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
16998905a67cSAndy Whitcroft		# outermost level.
17008905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
17018905a67cSAndy Whitcroft			last;
17028905a67cSAndy Whitcroft		}
17038905a67cSAndy Whitcroft
170413214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1705773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1706773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1707773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1708773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1709773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1710773647a0SAndy Whitcroft			$coff_set = 1;
1711773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1712773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
171313214adfSAndy Whitcroft		}
171413214adfSAndy Whitcroft
17158905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
17168905a67cSAndy Whitcroft			$level++;
17178905a67cSAndy Whitcroft			$type = '(';
17188905a67cSAndy Whitcroft		}
17198905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
17208905a67cSAndy Whitcroft			$level--;
17218905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
17228905a67cSAndy Whitcroft
17238905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
17248905a67cSAndy Whitcroft				$coff = $off;
1725773647a0SAndy Whitcroft				$coff_set = 1;
1726773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
17278905a67cSAndy Whitcroft			}
17288905a67cSAndy Whitcroft		}
17298905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
17308905a67cSAndy Whitcroft			$level++;
17318905a67cSAndy Whitcroft			$type = '{';
17328905a67cSAndy Whitcroft		}
17338905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
17348905a67cSAndy Whitcroft			$level--;
17358905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
17368905a67cSAndy Whitcroft
17378905a67cSAndy Whitcroft			if ($level == 0) {
1738b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1739b998e001SPatrick Pannuto					$off++;
1740b998e001SPatrick Pannuto				}
17418905a67cSAndy Whitcroft				last;
17428905a67cSAndy Whitcroft			}
17438905a67cSAndy Whitcroft		}
1744f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1745f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1746f74bd194SAndy Whitcroft			$level--;
1747f74bd194SAndy Whitcroft			$type = '';
1748f74bd194SAndy Whitcroft			$off++;
1749f74bd194SAndy Whitcroft			last;
1750f74bd194SAndy Whitcroft		}
17518905a67cSAndy Whitcroft		$off++;
17528905a67cSAndy Whitcroft	}
1753a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
175413214adfSAndy Whitcroft	if ($off == $len) {
1755a3bb97a7SAndy Whitcroft		$loff = $len + 1;
175613214adfSAndy Whitcroft		$line++;
175713214adfSAndy Whitcroft		$remain--;
175813214adfSAndy Whitcroft	}
17598905a67cSAndy Whitcroft
17608905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
17618905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
17628905a67cSAndy Whitcroft
17638905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
17648905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
17658905a67cSAndy Whitcroft
1766773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
176713214adfSAndy Whitcroft
176813214adfSAndy Whitcroft	return ($statement, $condition,
176913214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
177013214adfSAndy Whitcroft}
177113214adfSAndy Whitcroft
1772cf655043SAndy Whitcroftsub statement_lines {
1773cf655043SAndy Whitcroft	my ($stmt) = @_;
1774cf655043SAndy Whitcroft
1775cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1776cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1777cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1778cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1779cf655043SAndy Whitcroft
1780cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1781cf655043SAndy Whitcroft
1782cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1783cf655043SAndy Whitcroft}
1784cf655043SAndy Whitcroft
1785cf655043SAndy Whitcroftsub statement_rawlines {
1786cf655043SAndy Whitcroft	my ($stmt) = @_;
1787cf655043SAndy Whitcroft
1788cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1789cf655043SAndy Whitcroft
1790cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1791cf655043SAndy Whitcroft}
1792cf655043SAndy Whitcroft
1793cf655043SAndy Whitcroftsub statement_block_size {
1794cf655043SAndy Whitcroft	my ($stmt) = @_;
1795cf655043SAndy Whitcroft
1796cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1797cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1798cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1799cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1800cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1801cf655043SAndy Whitcroft
1802cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1803cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1804cf655043SAndy Whitcroft
1805cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1806cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1807cf655043SAndy Whitcroft
1808cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1809cf655043SAndy Whitcroft		return $stmt_lines;
1810cf655043SAndy Whitcroft	} else {
1811cf655043SAndy Whitcroft		return $stmt_statements;
1812cf655043SAndy Whitcroft	}
1813cf655043SAndy Whitcroft}
1814cf655043SAndy Whitcroft
181513214adfSAndy Whitcroftsub ctx_statement_full {
181613214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
181713214adfSAndy Whitcroft	my ($statement, $condition, $level);
181813214adfSAndy Whitcroft
181913214adfSAndy Whitcroft	my (@chunks);
182013214adfSAndy Whitcroft
1821cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
182213214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
182313214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1824773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
182513214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1826cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1827cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1828cf655043SAndy Whitcroft	}
1829cf655043SAndy Whitcroft
1830cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1831cf655043SAndy Whitcroft	# could continue the statement.
1832cf655043SAndy Whitcroft	for (;;) {
183313214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
183413214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1835cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1836773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1837cf655043SAndy Whitcroft		#print "C: push\n";
1838cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
183913214adfSAndy Whitcroft	}
184013214adfSAndy Whitcroft
184113214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
18428905a67cSAndy Whitcroft}
18438905a67cSAndy Whitcroft
18444a0df2efSAndy Whitcroftsub ctx_block_get {
1845f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
18464a0df2efSAndy Whitcroft	my $line;
18474a0df2efSAndy Whitcroft	my $start = $linenr - 1;
18484a0df2efSAndy Whitcroft	my $blk = '';
18494a0df2efSAndy Whitcroft	my @o;
18504a0df2efSAndy Whitcroft	my @c;
18514a0df2efSAndy Whitcroft	my @res = ();
18524a0df2efSAndy Whitcroft
1853f0a594c1SAndy Whitcroft	my $level = 0;
18544635f4fbSAndy Whitcroft	my @stack = ($level);
185500df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
185600df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
185700df344fSAndy Whitcroft		$remain--;
185800df344fSAndy Whitcroft
185900df344fSAndy Whitcroft		$blk .= $rawlines[$line];
18604635f4fbSAndy Whitcroft
18614635f4fbSAndy Whitcroft		# Handle nested #if/#else.
186201464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
18634635f4fbSAndy Whitcroft			push(@stack, $level);
186401464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
18654635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
186601464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
18674635f4fbSAndy Whitcroft			$level = pop(@stack);
18684635f4fbSAndy Whitcroft		}
18694635f4fbSAndy Whitcroft
187001464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1871f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1872f0a594c1SAndy Whitcroft			if ($off > 0) {
1873f0a594c1SAndy Whitcroft				$off--;
1874f0a594c1SAndy Whitcroft				next;
1875f0a594c1SAndy Whitcroft			}
18764a0df2efSAndy Whitcroft
1877f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1878f0a594c1SAndy Whitcroft				$level--;
1879f0a594c1SAndy Whitcroft				last if ($level == 0);
1880f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1881f0a594c1SAndy Whitcroft				$level++;
1882f0a594c1SAndy Whitcroft			}
1883f0a594c1SAndy Whitcroft		}
18844a0df2efSAndy Whitcroft
1885f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
188600df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
18874a0df2efSAndy Whitcroft		}
18884a0df2efSAndy Whitcroft
1889f0a594c1SAndy Whitcroft		last if ($level == 0);
18904a0df2efSAndy Whitcroft	}
18914a0df2efSAndy Whitcroft
1892f0a594c1SAndy Whitcroft	return ($level, @res);
18934a0df2efSAndy Whitcroft}
18944a0df2efSAndy Whitcroftsub ctx_block_outer {
18954a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
18964a0df2efSAndy Whitcroft
1897f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1898f0a594c1SAndy Whitcroft	return @r;
18994a0df2efSAndy Whitcroft}
19004a0df2efSAndy Whitcroftsub ctx_block {
19014a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
19024a0df2efSAndy Whitcroft
1903f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1904f0a594c1SAndy Whitcroft	return @r;
1905653d4876SAndy Whitcroft}
1906653d4876SAndy Whitcroftsub ctx_statement {
1907f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1908f0a594c1SAndy Whitcroft
1909f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1910f0a594c1SAndy Whitcroft	return @r;
1911f0a594c1SAndy Whitcroft}
1912f0a594c1SAndy Whitcroftsub ctx_block_level {
1913653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1914653d4876SAndy Whitcroft
1915f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
19164a0df2efSAndy Whitcroft}
19179c0ca6f9SAndy Whitcroftsub ctx_statement_level {
19189c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
19199c0ca6f9SAndy Whitcroft
19209c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
19219c0ca6f9SAndy Whitcroft}
19224a0df2efSAndy Whitcroft
19234a0df2efSAndy Whitcroftsub ctx_locate_comment {
19244a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19254a0df2efSAndy Whitcroft
1926a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1927a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1928a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1929a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1930a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1931a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1932a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1933a55ee0ccSJoe Perches
19344a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1935a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
19364a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
19374a0df2efSAndy Whitcroft
19384a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
19394a0df2efSAndy Whitcroft	# comment.
19404a0df2efSAndy Whitcroft	my $in_comment = 0;
19414a0df2efSAndy Whitcroft	$current_comment = '';
19424a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
194300df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
194400df344fSAndy Whitcroft		#warn "           $line\n";
19454a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
19464a0df2efSAndy Whitcroft			$in_comment = 1;
19474a0df2efSAndy Whitcroft		}
19484a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
19494a0df2efSAndy Whitcroft			$in_comment = 1;
19504a0df2efSAndy Whitcroft		}
19514a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
19524a0df2efSAndy Whitcroft			$current_comment = '';
19534a0df2efSAndy Whitcroft		}
19544a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
19554a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
19564a0df2efSAndy Whitcroft			$in_comment = 0;
19574a0df2efSAndy Whitcroft		}
19584a0df2efSAndy Whitcroft	}
19594a0df2efSAndy Whitcroft
19604a0df2efSAndy Whitcroft	chomp($current_comment);
19614a0df2efSAndy Whitcroft	return($current_comment);
19624a0df2efSAndy Whitcroft}
19634a0df2efSAndy Whitcroftsub ctx_has_comment {
19644a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19654a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
19664a0df2efSAndy Whitcroft
196700df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
19684a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
19694a0df2efSAndy Whitcroft
19704a0df2efSAndy Whitcroft	return ($cmt ne '');
19714a0df2efSAndy Whitcroft}
19724a0df2efSAndy Whitcroft
19734d001e4dSAndy Whitcroftsub raw_line {
19744d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
19754d001e4dSAndy Whitcroft
19764d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
19774d001e4dSAndy Whitcroft	$cnt++;
19784d001e4dSAndy Whitcroft
19794d001e4dSAndy Whitcroft	my $line;
19804d001e4dSAndy Whitcroft	while ($cnt) {
19814d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
19824d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
19834d001e4dSAndy Whitcroft		$cnt--;
19844d001e4dSAndy Whitcroft	}
19854d001e4dSAndy Whitcroft
19864d001e4dSAndy Whitcroft	return $line;
19874d001e4dSAndy Whitcroft}
19884d001e4dSAndy Whitcroft
19892a9f9d85STobin C. Hardingsub get_stat_real {
19902a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
19912a9f9d85STobin C. Harding
19922a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
19932a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
19942a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
19952a9f9d85STobin C. Harding	}
19962a9f9d85STobin C. Harding
19972a9f9d85STobin C. Harding	return $stat_real;
19982a9f9d85STobin C. Harding}
19992a9f9d85STobin C. Harding
2000e3d95a2aSTobin C. Hardingsub get_stat_here {
2001e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
2002e3d95a2aSTobin C. Harding
2003e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
2004e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
2005e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
2006e3d95a2aSTobin C. Harding	}
2007e3d95a2aSTobin C. Harding
2008e3d95a2aSTobin C. Harding	return $herectx;
2009e3d95a2aSTobin C. Harding}
2010e3d95a2aSTobin C. Harding
20110a920b5bSAndy Whitcroftsub cat_vet {
20120a920b5bSAndy Whitcroft	my ($vet) = @_;
20139c0ca6f9SAndy Whitcroft	my ($res, $coded);
20140a920b5bSAndy Whitcroft
20159c0ca6f9SAndy Whitcroft	$res = '';
20166c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
20176c72ffaaSAndy Whitcroft		$res .= $1;
20186c72ffaaSAndy Whitcroft		if ($2 ne '') {
20199c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
20206c72ffaaSAndy Whitcroft			$res .= $coded;
20216c72ffaaSAndy Whitcroft		}
20229c0ca6f9SAndy Whitcroft	}
20239c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
20240a920b5bSAndy Whitcroft
20259c0ca6f9SAndy Whitcroft	return $res;
20260a920b5bSAndy Whitcroft}
20270a920b5bSAndy Whitcroft
2028c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
2029cf655043SAndy Whitcroftmy $av_pending;
2030c2fdda0dSAndy Whitcroftmy @av_paren_type;
20311f65f947SAndy Whitcroftmy $av_pend_colon;
2032c2fdda0dSAndy Whitcroft
2033c2fdda0dSAndy Whitcroftsub annotate_reset {
2034c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
2035cf655043SAndy Whitcroft	$av_pending = '_';
2036cf655043SAndy Whitcroft	@av_paren_type = ('E');
20371f65f947SAndy Whitcroft	$av_pend_colon = 'O';
2038c2fdda0dSAndy Whitcroft}
2039c2fdda0dSAndy Whitcroft
20406c72ffaaSAndy Whitcroftsub annotate_values {
20416c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
20426c72ffaaSAndy Whitcroft
20436c72ffaaSAndy Whitcroft	my $res;
20441f65f947SAndy Whitcroft	my $var = '_' x length($stream);
20456c72ffaaSAndy Whitcroft	my $cur = $stream;
20466c72ffaaSAndy Whitcroft
2047c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
20486c72ffaaSAndy Whitcroft
20496c72ffaaSAndy Whitcroft	while (length($cur)) {
2050773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
2051cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
2052171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
20536c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
2054c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
2055c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
2056cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
2057c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
20586c72ffaaSAndy Whitcroft			}
20596c72ffaaSAndy Whitcroft
2060c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
20619446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
20629446ef56SAndy Whitcroft			push(@av_paren_type, $type);
2063addcdceaSAndy Whitcroft			$type = 'c';
20649446ef56SAndy Whitcroft
2065e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2066c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
20676c72ffaaSAndy Whitcroft			$type = 'T';
20686c72ffaaSAndy Whitcroft
2069389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
2070389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
2071389a2fe5SAndy Whitcroft			$type = 'T';
2072389a2fe5SAndy Whitcroft
2073c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2074171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2075c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2076171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
2077171ae1a4SAndy Whitcroft			if ($2 ne '') {
2078cf655043SAndy Whitcroft				$av_pending = 'N';
2079171ae1a4SAndy Whitcroft			}
2080171ae1a4SAndy Whitcroft			$type = 'E';
2081171ae1a4SAndy Whitcroft
2082c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2083171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
2084171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
2085171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
20866c72ffaaSAndy Whitcroft
2087c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2088cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
2089c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2090cf655043SAndy Whitcroft
2091cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2092cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2093171ae1a4SAndy Whitcroft			$type = 'E';
2094cf655043SAndy Whitcroft
2095c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2096cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2097cf655043SAndy Whitcroft			$av_preprocessor = 1;
2098cf655043SAndy Whitcroft
2099cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2100cf655043SAndy Whitcroft
2101171ae1a4SAndy Whitcroft			$type = 'E';
2102cf655043SAndy Whitcroft
2103c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2104cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
2105cf655043SAndy Whitcroft
2106cf655043SAndy Whitcroft			$av_preprocessor = 1;
2107cf655043SAndy Whitcroft
2108cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
2109cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
2110cf655043SAndy Whitcroft			pop(@av_paren_type);
2111cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2112171ae1a4SAndy Whitcroft			$type = 'E';
21136c72ffaaSAndy Whitcroft
21146c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
2115c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
21166c72ffaaSAndy Whitcroft
2117171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2118171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2119171ae1a4SAndy Whitcroft			$av_pending = $type;
2120171ae1a4SAndy Whitcroft			$type = 'N';
2121171ae1a4SAndy Whitcroft
21226c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2123c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
21246c72ffaaSAndy Whitcroft			if (defined $2) {
2125cf655043SAndy Whitcroft				$av_pending = 'V';
21266c72ffaaSAndy Whitcroft			}
21276c72ffaaSAndy Whitcroft			$type = 'N';
21286c72ffaaSAndy Whitcroft
212914b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2130c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
213114b111c1SAndy Whitcroft			$av_pending = 'E';
21326c72ffaaSAndy Whitcroft			$type = 'N';
21336c72ffaaSAndy Whitcroft
21341f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
21351f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
21361f65f947SAndy Whitcroft			$av_pend_colon = 'C';
21371f65f947SAndy Whitcroft			$type = 'N';
21381f65f947SAndy Whitcroft
213914b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2140c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
21416c72ffaaSAndy Whitcroft			$type = 'N';
21426c72ffaaSAndy Whitcroft
21436c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2144c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2145cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2146cf655043SAndy Whitcroft			$av_pending = '_';
21476c72ffaaSAndy Whitcroft			$type = 'N';
21486c72ffaaSAndy Whitcroft
21496c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2150cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2151cf655043SAndy Whitcroft			if ($new_type ne '_') {
2152cf655043SAndy Whitcroft				$type = $new_type;
2153c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2154c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
21556c72ffaaSAndy Whitcroft			} else {
2156c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
21576c72ffaaSAndy Whitcroft			}
21586c72ffaaSAndy Whitcroft
2159c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2160c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2161c8cb2ca3SAndy Whitcroft			$type = 'V';
2162cf655043SAndy Whitcroft			$av_pending = 'V';
21636c72ffaaSAndy Whitcroft
21648e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
21658e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
21661f65f947SAndy Whitcroft				$av_pend_colon = 'B';
21678e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
21688e761b04SAndy Whitcroft				$av_pend_colon = 'L';
21691f65f947SAndy Whitcroft			}
21701f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
21711f65f947SAndy Whitcroft			$type = 'V';
21721f65f947SAndy Whitcroft
21736c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2174c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
21756c72ffaaSAndy Whitcroft			$type = 'V';
21766c72ffaaSAndy Whitcroft
21776c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2178c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
21796c72ffaaSAndy Whitcroft			$type = 'N';
21806c72ffaaSAndy Whitcroft
2181cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2182c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
218313214adfSAndy Whitcroft			$type = 'E';
21841f65f947SAndy Whitcroft			$av_pend_colon = 'O';
218513214adfSAndy Whitcroft
21868e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
21878e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
21888e761b04SAndy Whitcroft			$type = 'C';
21898e761b04SAndy Whitcroft
21901f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
21911f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
21921f65f947SAndy Whitcroft			$type = 'N';
21931f65f947SAndy Whitcroft
21941f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
21951f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
21961f65f947SAndy Whitcroft
21971f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
21981f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
21991f65f947SAndy Whitcroft				$type = 'E';
22001f65f947SAndy Whitcroft			} else {
22011f65f947SAndy Whitcroft				$type = 'N';
22021f65f947SAndy Whitcroft			}
22031f65f947SAndy Whitcroft			$av_pend_colon = 'O';
22041f65f947SAndy Whitcroft
22058e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
220613214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
22076c72ffaaSAndy Whitcroft			$type = 'N';
22086c72ffaaSAndy Whitcroft
22090d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
221074048ed8SAndy Whitcroft			my $variant;
221174048ed8SAndy Whitcroft
221274048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
221374048ed8SAndy Whitcroft			if ($type eq 'V') {
221474048ed8SAndy Whitcroft				$variant = 'B';
221574048ed8SAndy Whitcroft			} else {
221674048ed8SAndy Whitcroft				$variant = 'U';
221774048ed8SAndy Whitcroft			}
221874048ed8SAndy Whitcroft
221974048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
222074048ed8SAndy Whitcroft			$type = 'N';
222174048ed8SAndy Whitcroft
22226c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2223c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
22246c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
22256c72ffaaSAndy Whitcroft				$type = 'N';
22266c72ffaaSAndy Whitcroft			}
22276c72ffaaSAndy Whitcroft
22286c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2229c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
22306c72ffaaSAndy Whitcroft		}
22316c72ffaaSAndy Whitcroft		if (defined $1) {
22326c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
22336c72ffaaSAndy Whitcroft			$res .= $type x length($1);
22346c72ffaaSAndy Whitcroft		}
22356c72ffaaSAndy Whitcroft	}
22366c72ffaaSAndy Whitcroft
22371f65f947SAndy Whitcroft	return ($res, $var);
22386c72ffaaSAndy Whitcroft}
22396c72ffaaSAndy Whitcroft
22408905a67cSAndy Whitcroftsub possible {
224113214adfSAndy Whitcroft	my ($possible, $line) = @_;
22429a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
22430776e594SAndy Whitcroft		^(?:
22440776e594SAndy Whitcroft			$Modifier|
22450776e594SAndy Whitcroft			$Storage|
22460776e594SAndy Whitcroft			$Type|
22479a974fdbSAndy Whitcroft			DEFINE_\S+
22489a974fdbSAndy Whitcroft		)$|
22499a974fdbSAndy Whitcroft		^(?:
22500776e594SAndy Whitcroft			goto|
22510776e594SAndy Whitcroft			return|
22520776e594SAndy Whitcroft			case|
22530776e594SAndy Whitcroft			else|
22540776e594SAndy Whitcroft			asm|__asm__|
225589a88353SAndy Whitcroft			do|
225689a88353SAndy Whitcroft			\#|
225789a88353SAndy Whitcroft			\#\#|
22589a974fdbSAndy Whitcroft		)(?:\s|$)|
22590776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
22609a974fdbSAndy Whitcroft	    )}x;
22619a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
22629a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2263c45dcabdSAndy Whitcroft		# Check for modifiers.
2264c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2265c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2266c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2267c45dcabdSAndy Whitcroft
2268c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2269c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2270d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
22719a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2272d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2273485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2274d2506586SAndy Whitcroft				}
22759a974fdbSAndy Whitcroft			}
2276c45dcabdSAndy Whitcroft
2277c45dcabdSAndy Whitcroft		} else {
227813214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2279485ff23eSAlex Dowad			push(@typeListFile, $possible);
2280c45dcabdSAndy Whitcroft		}
22818905a67cSAndy Whitcroft		build_types();
22820776e594SAndy Whitcroft	} else {
22830776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
22848905a67cSAndy Whitcroft	}
22858905a67cSAndy Whitcroft}
22868905a67cSAndy Whitcroft
22876c72ffaaSAndy Whitcroftmy $prefix = '';
22886c72ffaaSAndy Whitcroft
2289000d1cc1SJoe Perchessub show_type {
2290cbec18afSJoe Perches	my ($type) = @_;
229191bfe484SJoe Perches
2292522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2293522b837cSAlexey Dobriyan
2294cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2295cbec18afSJoe Perches
2296cbec18afSJoe Perches	return !defined $ignore_type{$type};
2297000d1cc1SJoe Perches}
2298000d1cc1SJoe Perches
2299f0a594c1SAndy Whitcroftsub report {
2300cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2301cbec18afSJoe Perches
2302cbec18afSJoe Perches	if (!show_type($type) ||
2303cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2304773647a0SAndy Whitcroft		return 0;
2305773647a0SAndy Whitcroft	}
230657230297SJoe Perches	my $output = '';
2307737c0767SJohn Brooks	if ($color) {
230857230297SJoe Perches		if ($level eq 'ERROR') {
230957230297SJoe Perches			$output .= RED;
231057230297SJoe Perches		} elsif ($level eq 'WARNING') {
231157230297SJoe Perches			$output .= YELLOW;
2312000d1cc1SJoe Perches		} else {
231357230297SJoe Perches			$output .= GREEN;
2314000d1cc1SJoe Perches		}
231557230297SJoe Perches	}
231657230297SJoe Perches	$output .= $prefix . $level . ':';
231757230297SJoe Perches	if ($show_types) {
2318737c0767SJohn Brooks		$output .= BLUE if ($color);
231957230297SJoe Perches		$output .= "$type:";
232057230297SJoe Perches	}
2321737c0767SJohn Brooks	$output .= RESET if ($color);
232257230297SJoe Perches	$output .= ' ' . $msg . "\n";
232334d8815fSJoe Perches
232434d8815fSJoe Perches	if ($showfile) {
232534d8815fSJoe Perches		my @lines = split("\n", $output, -1);
232634d8815fSJoe Perches		splice(@lines, 1, 1);
232734d8815fSJoe Perches		$output = join("\n", @lines);
232834d8815fSJoe Perches	}
232952178ce0SDwaipayan Ray
233052178ce0SDwaipayan Ray	if ($terse) {
233152178ce0SDwaipayan Ray		$output = (split('\n', $output))[0] . "\n";
233252178ce0SDwaipayan Ray	}
233352178ce0SDwaipayan Ray
233452178ce0SDwaipayan Ray	if ($verbose && exists($verbose_messages{$type}) &&
233552178ce0SDwaipayan Ray	    !exists($verbose_emitted{$type})) {
233652178ce0SDwaipayan Ray		$output .= $verbose_messages{$type} . "\n\n";
233752178ce0SDwaipayan Ray		$verbose_emitted{$type} = 1;
233852178ce0SDwaipayan Ray	}
23398905a67cSAndy Whitcroft
234057230297SJoe Perches	push(our @report, $output);
2341773647a0SAndy Whitcroft
2342773647a0SAndy Whitcroft	return 1;
2343f0a594c1SAndy Whitcroft}
2344cbec18afSJoe Perches
2345f0a594c1SAndy Whitcroftsub report_dump {
234613214adfSAndy Whitcroft	our @report;
2347f0a594c1SAndy Whitcroft}
2348000d1cc1SJoe Perches
2349d752fcc8SJoe Perchessub fixup_current_range {
2350d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2351d752fcc8SJoe Perches
2352d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2353d752fcc8SJoe Perches		my $o = $1;
2354d752fcc8SJoe Perches		my $l = $2;
2355d752fcc8SJoe Perches		my $no = $o + $offset;
2356d752fcc8SJoe Perches		my $nl = $l + $length;
2357d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2358d752fcc8SJoe Perches	}
2359d752fcc8SJoe Perches}
2360d752fcc8SJoe Perches
2361d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2362d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2363d752fcc8SJoe Perches
2364d752fcc8SJoe Perches	my $range_last_linenr = 0;
2365d752fcc8SJoe Perches	my $delta_offset = 0;
2366d752fcc8SJoe Perches
2367d752fcc8SJoe Perches	my $old_linenr = 0;
2368d752fcc8SJoe Perches	my $new_linenr = 0;
2369d752fcc8SJoe Perches
2370d752fcc8SJoe Perches	my $next_insert = 0;
2371d752fcc8SJoe Perches	my $next_delete = 0;
2372d752fcc8SJoe Perches
2373d752fcc8SJoe Perches	my @lines = ();
2374d752fcc8SJoe Perches
2375d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2376d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2377d752fcc8SJoe Perches
2378d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2379d752fcc8SJoe Perches		my $save_line = 1;
2380d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2381323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2382d752fcc8SJoe Perches			$delta_offset = 0;
2383d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2384d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2385d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2386d752fcc8SJoe Perches		}
2387d752fcc8SJoe Perches
2388d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2389d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2390d752fcc8SJoe Perches			$save_line = 0;
2391d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2392d752fcc8SJoe Perches		}
2393d752fcc8SJoe Perches
2394d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2395d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2396d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2397d752fcc8SJoe Perches			$new_linenr++;
2398d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2399d752fcc8SJoe Perches		}
2400d752fcc8SJoe Perches
2401d752fcc8SJoe Perches		if ($save_line) {
2402d752fcc8SJoe Perches			push(@lines, $line);
2403d752fcc8SJoe Perches			$new_linenr++;
2404d752fcc8SJoe Perches		}
2405d752fcc8SJoe Perches
2406d752fcc8SJoe Perches		$old_linenr++;
2407d752fcc8SJoe Perches	}
2408d752fcc8SJoe Perches
2409d752fcc8SJoe Perches	return @lines;
2410d752fcc8SJoe Perches}
2411d752fcc8SJoe Perches
2412f2d7e4d4SJoe Perchessub fix_insert_line {
2413f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2414f2d7e4d4SJoe Perches
2415f2d7e4d4SJoe Perches	my $inserted = {
2416f2d7e4d4SJoe Perches		LINENR => $linenr,
2417f2d7e4d4SJoe Perches		LINE => $line,
2418f2d7e4d4SJoe Perches	};
2419f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2420f2d7e4d4SJoe Perches}
2421f2d7e4d4SJoe Perches
2422f2d7e4d4SJoe Perchessub fix_delete_line {
2423f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2424f2d7e4d4SJoe Perches
2425f2d7e4d4SJoe Perches	my $deleted = {
2426f2d7e4d4SJoe Perches		LINENR => $linenr,
2427f2d7e4d4SJoe Perches		LINE => $line,
2428f2d7e4d4SJoe Perches	};
2429f2d7e4d4SJoe Perches
2430f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2431f2d7e4d4SJoe Perches}
2432f2d7e4d4SJoe Perches
2433de7d4f0eSAndy Whitcroftsub ERROR {
2434cbec18afSJoe Perches	my ($type, $msg) = @_;
2435cbec18afSJoe Perches
2436cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2437de7d4f0eSAndy Whitcroft		our $clean = 0;
24386c72ffaaSAndy Whitcroft		our $cnt_error++;
24393705ce5bSJoe Perches		return 1;
2440de7d4f0eSAndy Whitcroft	}
24413705ce5bSJoe Perches	return 0;
2442773647a0SAndy Whitcroft}
2443de7d4f0eSAndy Whitcroftsub WARN {
2444cbec18afSJoe Perches	my ($type, $msg) = @_;
2445cbec18afSJoe Perches
2446cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2447de7d4f0eSAndy Whitcroft		our $clean = 0;
24486c72ffaaSAndy Whitcroft		our $cnt_warn++;
24493705ce5bSJoe Perches		return 1;
2450de7d4f0eSAndy Whitcroft	}
24513705ce5bSJoe Perches	return 0;
2452773647a0SAndy Whitcroft}
2453de7d4f0eSAndy Whitcroftsub CHK {
2454cbec18afSJoe Perches	my ($type, $msg) = @_;
2455cbec18afSJoe Perches
2456cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2457de7d4f0eSAndy Whitcroft		our $clean = 0;
24586c72ffaaSAndy Whitcroft		our $cnt_chk++;
24593705ce5bSJoe Perches		return 1;
24606c72ffaaSAndy Whitcroft	}
24613705ce5bSJoe Perches	return 0;
2462de7d4f0eSAndy Whitcroft}
2463de7d4f0eSAndy Whitcroft
24646ecd9674SAndy Whitcroftsub check_absolute_file {
24656ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
24666ecd9674SAndy Whitcroft	my $file = $absolute;
24676ecd9674SAndy Whitcroft
24686ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
24696ecd9674SAndy Whitcroft
24706ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
24716ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
24726ecd9674SAndy Whitcroft		if (-f "$root/$file") {
24736ecd9674SAndy Whitcroft			##print "file<$file>\n";
24746ecd9674SAndy Whitcroft			last;
24756ecd9674SAndy Whitcroft		}
24766ecd9674SAndy Whitcroft	}
24776ecd9674SAndy Whitcroft	if (! -f _)  {
24786ecd9674SAndy Whitcroft		return 0;
24796ecd9674SAndy Whitcroft	}
24806ecd9674SAndy Whitcroft
24816ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
24826ecd9674SAndy Whitcroft	my $prefix = $absolute;
24836ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
24846ecd9674SAndy Whitcroft
24856ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
24866ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2487000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2488000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
24896ecd9674SAndy Whitcroft	}
24906ecd9674SAndy Whitcroft}
24916ecd9674SAndy Whitcroft
24923705ce5bSJoe Perchessub trim {
24933705ce5bSJoe Perches	my ($string) = @_;
24943705ce5bSJoe Perches
2495b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2496b34c648bSJoe Perches
2497b34c648bSJoe Perches	return $string;
2498b34c648bSJoe Perches}
2499b34c648bSJoe Perches
2500b34c648bSJoe Perchessub ltrim {
2501b34c648bSJoe Perches	my ($string) = @_;
2502b34c648bSJoe Perches
2503b34c648bSJoe Perches	$string =~ s/^\s+//;
2504b34c648bSJoe Perches
2505b34c648bSJoe Perches	return $string;
2506b34c648bSJoe Perches}
2507b34c648bSJoe Perches
2508b34c648bSJoe Perchessub rtrim {
2509b34c648bSJoe Perches	my ($string) = @_;
2510b34c648bSJoe Perches
2511b34c648bSJoe Perches	$string =~ s/\s+$//;
25123705ce5bSJoe Perches
25133705ce5bSJoe Perches	return $string;
25143705ce5bSJoe Perches}
25153705ce5bSJoe Perches
251652ea8506SJoe Perchessub string_find_replace {
251752ea8506SJoe Perches	my ($string, $find, $replace) = @_;
251852ea8506SJoe Perches
251952ea8506SJoe Perches	$string =~ s/$find/$replace/g;
252052ea8506SJoe Perches
252152ea8506SJoe Perches	return $string;
252252ea8506SJoe Perches}
252352ea8506SJoe Perches
25243705ce5bSJoe Perchessub tabify {
25253705ce5bSJoe Perches	my ($leading) = @_;
25263705ce5bSJoe Perches
2527713a09deSAntonio Borneo	my $source_indent = $tabsize;
25283705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
25293705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
25303705ce5bSJoe Perches
25313705ce5bSJoe Perches	#convert leading spaces to tabs
25323705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
25333705ce5bSJoe Perches	#Remove spaces before a tab
25343705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
25353705ce5bSJoe Perches
25363705ce5bSJoe Perches	return "$leading";
25373705ce5bSJoe Perches}
25383705ce5bSJoe Perches
2539d1fe9c09SJoe Perchessub pos_last_openparen {
2540d1fe9c09SJoe Perches	my ($line) = @_;
2541d1fe9c09SJoe Perches
2542d1fe9c09SJoe Perches	my $pos = 0;
2543d1fe9c09SJoe Perches
2544d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2545d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2546d1fe9c09SJoe Perches
2547d1fe9c09SJoe Perches	my $last_openparen = 0;
2548d1fe9c09SJoe Perches
2549d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2550d1fe9c09SJoe Perches		return -1;
2551d1fe9c09SJoe Perches	}
2552d1fe9c09SJoe Perches
2553d1fe9c09SJoe Perches	my $len = length($line);
2554d1fe9c09SJoe Perches
2555d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2556d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2557d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2558d1fe9c09SJoe Perches			$pos += length($1) - 1;
2559d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2560d1fe9c09SJoe Perches			$last_openparen = $pos;
2561d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2562d1fe9c09SJoe Perches			last;
2563d1fe9c09SJoe Perches		}
2564d1fe9c09SJoe Perches	}
2565d1fe9c09SJoe Perches
256691cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2567d1fe9c09SJoe Perches}
2568d1fe9c09SJoe Perches
2569f36d3eb8SJoe Perchessub get_raw_comment {
2570f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2571f36d3eb8SJoe Perches	my $comment = '';
2572f36d3eb8SJoe Perches
2573f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2574f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2575f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2576f36d3eb8SJoe Perches		}
2577f36d3eb8SJoe Perches	}
2578f36d3eb8SJoe Perches
2579f36d3eb8SJoe Perches	return $comment;
2580f36d3eb8SJoe Perches}
2581f36d3eb8SJoe Perches
25825b8f82e1SSong Liusub exclude_global_initialisers {
25835b8f82e1SSong Liu	my ($realfile) = @_;
25845b8f82e1SSong Liu
25855b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
25865b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
25875b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
25885b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
25895b8f82e1SSong Liu}
25905b8f82e1SSong Liu
25910a920b5bSAndy Whitcroftsub process {
25920a920b5bSAndy Whitcroft	my $filename = shift;
25930a920b5bSAndy Whitcroft
25940a920b5bSAndy Whitcroft	my $linenr=0;
25950a920b5bSAndy Whitcroft	my $prevline="";
2596c2fdda0dSAndy Whitcroft	my $prevrawline="";
25970a920b5bSAndy Whitcroft	my $stashline="";
2598c2fdda0dSAndy Whitcroft	my $stashrawline="";
25990a920b5bSAndy Whitcroft
26004a0df2efSAndy Whitcroft	my $length;
26010a920b5bSAndy Whitcroft	my $indent;
26020a920b5bSAndy Whitcroft	my $previndent=0;
26030a920b5bSAndy Whitcroft	my $stashindent=0;
26040a920b5bSAndy Whitcroft
2605de7d4f0eSAndy Whitcroft	our $clean = 1;
26060a920b5bSAndy Whitcroft	my $signoff = 0;
2607cd261496SGeert Uytterhoeven	my $author = '';
2608cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
260948ca2d8aSDwaipayan Ray	my $author_sob = '';
26100a920b5bSAndy Whitcroft	my $is_patch = 0;
2611133712a2SRob Herring	my $is_binding_patch = -1;
261229ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
261315662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
261444d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2615ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2616490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2617bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
26182a076f40SJoe Perches	my $commit_log_long_line = 0;
2619e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
262013f1937eSJoe Perches	my $reported_maintainer_file = 0;
2621fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2622fa64205dSPasi Savanainen
26234ce9f970SJoe Perches	my $last_git_commit_id_linenr = -1;
26244ce9f970SJoe Perches
2625365dd4eaSJoe Perches	my $last_blank_line = 0;
26265e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2627365dd4eaSJoe Perches
262813214adfSAndy Whitcroft	our @report = ();
26296c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
26306c72ffaaSAndy Whitcroft	our $cnt_error = 0;
26316c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
26326c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
26336c72ffaaSAndy Whitcroft
26340a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
26350a920b5bSAndy Whitcroft	my $realfile = '';
26360a920b5bSAndy Whitcroft	my $realline = 0;
26370a920b5bSAndy Whitcroft	my $realcnt = 0;
26380a920b5bSAndy Whitcroft	my $here = '';
263977cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
26400a920b5bSAndy Whitcroft	my $in_comment = 0;
2641c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
26420a920b5bSAndy Whitcroft	my $first_line = 0;
26431e855726SWolfram Sang	my $p1_prefix = '';
26440a920b5bSAndy Whitcroft
264513214adfSAndy Whitcroft	my $prev_values = 'E';
264613214adfSAndy Whitcroft
264713214adfSAndy Whitcroft	# suppression flags
2648773647a0SAndy Whitcroft	my %suppress_ifbraces;
2649170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
26502b474a1aSAndy Whitcroft	my %suppress_export;
26513e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2652653d4876SAndy Whitcroft
26537e51f197SJoe Perches	my %signatures = ();
2654323c1260SJoe Perches
2655c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2656de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2657c2fdda0dSAndy Whitcroft	#
2658de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2659de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2660773647a0SAndy Whitcroft
2661d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2662d8b07710SJoe Perches
26639f3a8992SRob Herring	my $checklicenseline = 1;
26649f3a8992SRob Herring
2665773647a0SAndy Whitcroft	sanitise_line_reset();
2666c2fdda0dSAndy Whitcroft	my $line;
2667c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2668773647a0SAndy Whitcroft		$linenr++;
2669773647a0SAndy Whitcroft		$line = $rawline;
2670c2fdda0dSAndy Whitcroft
26713705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
26723705ce5bSJoe Perches
2673773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2674de7d4f0eSAndy Whitcroft			$setup_docs = 0;
26752581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2676de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2677de7d4f0eSAndy Whitcroft			}
2678773647a0SAndy Whitcroft			#next;
2679de7d4f0eSAndy Whitcroft		}
268074fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2681773647a0SAndy Whitcroft			$realline=$1-1;
2682773647a0SAndy Whitcroft			if (defined $2) {
2683773647a0SAndy Whitcroft				$realcnt=$3+1;
2684773647a0SAndy Whitcroft			} else {
2685773647a0SAndy Whitcroft				$realcnt=1+1;
2686773647a0SAndy Whitcroft			}
2687c45dcabdSAndy Whitcroft			$in_comment = 0;
2688773647a0SAndy Whitcroft
2689773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2690773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2691773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2692773647a0SAndy Whitcroft			# at context start.
2693773647a0SAndy Whitcroft			my $edge;
269401fa9147SAndy Whitcroft			my $cnt = $realcnt;
269501fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
269601fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
269701fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
269801fa9147SAndy Whitcroft				$cnt--;
269901fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2700721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2701fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2702fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2703fae17daeSAndy Whitcroft					($edge) = $1;
2704fae17daeSAndy Whitcroft					last;
2705fae17daeSAndy Whitcroft				}
2706773647a0SAndy Whitcroft			}
2707773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2708773647a0SAndy Whitcroft				$in_comment = 1;
2709773647a0SAndy Whitcroft			}
2710773647a0SAndy Whitcroft
2711773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2712773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2713773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2714773647a0SAndy Whitcroft			if (!defined $edge &&
271583242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2716773647a0SAndy Whitcroft			{
2717773647a0SAndy Whitcroft				$in_comment = 1;
2718773647a0SAndy Whitcroft			}
2719773647a0SAndy Whitcroft
2720773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2721773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2722773647a0SAndy Whitcroft
2723171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2724773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2725171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2726773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2727773647a0SAndy Whitcroft		}
2728773647a0SAndy Whitcroft		push(@lines, $line);
2729773647a0SAndy Whitcroft
2730773647a0SAndy Whitcroft		if ($realcnt > 1) {
2731773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2732773647a0SAndy Whitcroft		} else {
2733773647a0SAndy Whitcroft			$realcnt = 0;
2734773647a0SAndy Whitcroft		}
2735773647a0SAndy Whitcroft
2736773647a0SAndy Whitcroft		#print "==>$rawline\n";
2737773647a0SAndy Whitcroft		#print "-->$line\n";
2738de7d4f0eSAndy Whitcroft
2739de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2740de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2741de7d4f0eSAndy Whitcroft		}
2742de7d4f0eSAndy Whitcroft	}
2743de7d4f0eSAndy Whitcroft
27446c72ffaaSAndy Whitcroft	$prefix = '';
27456c72ffaaSAndy Whitcroft
2746773647a0SAndy Whitcroft	$realcnt = 0;
2747773647a0SAndy Whitcroft	$linenr = 0;
2748194f66fcSJoe Perches	$fixlinenr = -1;
27490a920b5bSAndy Whitcroft	foreach my $line (@lines) {
27500a920b5bSAndy Whitcroft		$linenr++;
2751194f66fcSJoe Perches		$fixlinenr++;
27521b5539b1SJoe Perches		my $sline = $line;	#copy of $line
27531b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
27540a920b5bSAndy Whitcroft
2755c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2756f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
27576c72ffaaSAndy Whitcroft
275812c253abSJoe Perches# check if it's a mode change, rename or start of a patch
275912c253abSJoe Perches		if (!$in_commit_log &&
276012c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
276112c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
276212c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
276312c253abSJoe Perches			$is_patch = 1;
276412c253abSJoe Perches		}
276512c253abSJoe Perches
27660a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2767e518e9a5SJoe Perches		if (!$in_commit_log &&
276874fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
276974fd4f34SJoe Perches			my $context = $4;
27700a920b5bSAndy Whitcroft			$is_patch = 1;
27714a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
27720a920b5bSAndy Whitcroft			$realline=$1-1;
27730a920b5bSAndy Whitcroft			if (defined $2) {
27740a920b5bSAndy Whitcroft				$realcnt=$3+1;
27750a920b5bSAndy Whitcroft			} else {
27760a920b5bSAndy Whitcroft				$realcnt=1+1;
27770a920b5bSAndy Whitcroft			}
2778c2fdda0dSAndy Whitcroft			annotate_reset();
277913214adfSAndy Whitcroft			$prev_values = 'E';
278013214adfSAndy Whitcroft
2781773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2782170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
27832b474a1aSAndy Whitcroft			%suppress_export = ();
27843e469cdcSAndy Whitcroft			$suppress_statement = 0;
278574fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
278674fd4f34SJoe Perches				$context_function = $1;
278774fd4f34SJoe Perches			} else {
278874fd4f34SJoe Perches				undef $context_function;
278974fd4f34SJoe Perches			}
27900a920b5bSAndy Whitcroft			next;
27910a920b5bSAndy Whitcroft
27924a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
27934a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
27944a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2795773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
27960a920b5bSAndy Whitcroft			$realline++;
2797d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
27980a920b5bSAndy Whitcroft
27994a0df2efSAndy Whitcroft			# Measure the line length and indent.
2800c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
28010a920b5bSAndy Whitcroft
28020a920b5bSAndy Whitcroft			# Track the previous line.
28030a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
28040a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2805c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2806c2fdda0dSAndy Whitcroft
2807773647a0SAndy Whitcroft			#warn "line<$line>\n";
28086c72ffaaSAndy Whitcroft
2809d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2810d8aaf121SAndy Whitcroft			$realcnt--;
28110a920b5bSAndy Whitcroft		}
28120a920b5bSAndy Whitcroft
2813cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2814cc77cdcaSAndy Whitcroft
28156c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
28166c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2817773647a0SAndy Whitcroft
28182ac73b4fSJoe Perches		my $found_file = 0;
2819773647a0SAndy Whitcroft		# extract the filename as it passes
28203bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
28213bf9a009SRabin Vincent			$realfile = $1;
28222b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2823270c49a0SJoe Perches			$in_commit_log = 0;
28242ac73b4fSJoe Perches			$found_file = 1;
28253bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2826773647a0SAndy Whitcroft			$realfile = $1;
28272b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2828270c49a0SJoe Perches			$in_commit_log = 0;
28291e855726SWolfram Sang
28301e855726SWolfram Sang			$p1_prefix = $1;
2831e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2832e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2833000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2834000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
28351e855726SWolfram Sang			}
2836773647a0SAndy Whitcroft
2837c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2838000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2839000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2840773647a0SAndy Whitcroft			}
28412ac73b4fSJoe Perches			$found_file = 1;
28422ac73b4fSJoe Perches		}
28432ac73b4fSJoe Perches
284434d8815fSJoe Perches#make up the handle for any error we report on this line
284534d8815fSJoe Perches		if ($showfile) {
284634d8815fSJoe Perches			$prefix = "$realfile:$realline: "
284734d8815fSJoe Perches		} elsif ($emacs) {
28487d3a9f67SJoe Perches			if ($file) {
28497d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
28507d3a9f67SJoe Perches			} else {
285134d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
285234d8815fSJoe Perches			}
28537d3a9f67SJoe Perches		}
285434d8815fSJoe Perches
28552ac73b4fSJoe Perches		if ($found_file) {
285685b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
285785b0ee18SJoe Perches				WARN("OBSOLETE",
285885b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
285985b0ee18SJoe Perches			}
28607bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
28612ac73b4fSJoe Perches				$check = 1;
28622ac73b4fSJoe Perches			} else {
28632ac73b4fSJoe Perches				$check = $check_orig;
28642ac73b4fSJoe Perches			}
28659f3a8992SRob Herring			$checklicenseline = 1;
2866133712a2SRob Herring
2867133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2868133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2869133712a2SRob Herring
2870133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2871133712a2SRob Herring
2872133712a2SRob Herring				if (($last_binding_patch != -1) &&
2873133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2874133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2875858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2876133712a2SRob Herring				}
2877133712a2SRob Herring			}
2878133712a2SRob Herring
2879773647a0SAndy Whitcroft			next;
2880773647a0SAndy Whitcroft		}
2881773647a0SAndy Whitcroft
2882389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
28830a920b5bSAndy Whitcroft
2884c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2885c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2886c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
28870a920b5bSAndy Whitcroft
28886c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
28896c72ffaaSAndy Whitcroft
2890490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2891490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2892490b292cSJoe Perches		if ($in_commit_log) {
2893490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2894490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2895490b292cSJoe Perches			}
2896490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2897490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2898490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2899490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2900490b292cSJoe Perches		}
2901490b292cSJoe Perches
2902e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2903e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
290413e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
290513e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2906e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2907e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2908e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2909e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2910e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2911e518e9a5SJoe Perches		}
2912e518e9a5SJoe Perches
29133bf9a009SRabin Vincent# Check for incorrect file permissions
29143bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
29153bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
291604db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
291704db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2918000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2919000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
29203bf9a009SRabin Vincent			}
29213bf9a009SRabin Vincent		}
29223bf9a009SRabin Vincent
2923cd261496SGeert Uytterhoeven# Check the patch for a From:
2924cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2925cd261496SGeert Uytterhoeven			$author = $1;
2926e7f929f3SDwaipayan Ray			my $curline = $linenr;
2927e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2928e7f929f3SDwaipayan Ray				$author .= $1;
2929e7f929f3SDwaipayan Ray			}
2930cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2931cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2932dfa05c28SJoe Perches			$author = reformat_email($author);
2933cd261496SGeert Uytterhoeven		}
2934cd261496SGeert Uytterhoeven
293520112475SJoe Perches# Check the patch for a signoff:
2936dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
29374a0df2efSAndy Whitcroft			$signoff++;
293815662b3eSJoe Perches			$in_commit_log = 0;
293948ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2940fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2941cd261496SGeert Uytterhoeven					$authorsignoff = 1;
294248ca2d8aSDwaipayan Ray				} else {
294348ca2d8aSDwaipayan Ray					my $ctx = $1;
294448ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
294548ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
294648ca2d8aSDwaipayan Ray
2947046fc741SMimi Zohar					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
294848ca2d8aSDwaipayan Ray						$author_sob = $ctx;
294948ca2d8aSDwaipayan Ray						$authorsignoff = 2;
2950046fc741SMimi Zohar					} elsif (lc $email_address eq lc $author_address) {
295148ca2d8aSDwaipayan Ray						$author_sob = $ctx;
295248ca2d8aSDwaipayan Ray						$authorsignoff = 3;
295348ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
295448ca2d8aSDwaipayan Ray						$author_sob = $ctx;
295548ca2d8aSDwaipayan Ray						$authorsignoff = 4;
295648ca2d8aSDwaipayan Ray
295748ca2d8aSDwaipayan Ray						my $address1 = $email_address;
295848ca2d8aSDwaipayan Ray						my $address2 = $author_address;
295948ca2d8aSDwaipayan Ray
296048ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
296148ca2d8aSDwaipayan Ray							$address1 = "$1$2";
296248ca2d8aSDwaipayan Ray						}
296348ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
296448ca2d8aSDwaipayan Ray							$address2 = "$1$2";
296548ca2d8aSDwaipayan Ray						}
296648ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
296748ca2d8aSDwaipayan Ray							$authorsignoff = 5;
296848ca2d8aSDwaipayan Ray						}
296948ca2d8aSDwaipayan Ray					}
2970cd261496SGeert Uytterhoeven				}
2971cd261496SGeert Uytterhoeven			}
29720a920b5bSAndy Whitcroft		}
297320112475SJoe Perches
297444d303ebSJoe Perches# Check for patch separator
297544d303ebSJoe Perches		if ($line =~ /^---$/) {
297644d303ebSJoe Perches			$has_patch_separator = 1;
297744d303ebSJoe Perches			$in_commit_log = 0;
297844d303ebSJoe Perches		}
297944d303ebSJoe Perches
2980e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2981e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2982e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2983e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2984e0d975b1SJoe Perches		}
2985e0d975b1SJoe Perches
298620112475SJoe Perches# Check signature styles
2987270c49a0SJoe Perches		if (!$in_header_lines &&
2988ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
298920112475SJoe Perches			my $space_before = $1;
299020112475SJoe Perches			my $sign_off = $2;
299120112475SJoe Perches			my $space_after = $3;
299220112475SJoe Perches			my $email = $4;
299320112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
299420112475SJoe Perches
2995ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2996831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
2997831242abSAditya Srivastava				if ($suggested_signature eq "") {
2998ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
2999ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
3000831242abSAditya Srivastava				} else {
3001831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
3002831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
3003831242abSAditya Srivastava					    $fix) {
3004831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
3005831242abSAditya Srivastava					}
3006831242abSAditya Srivastava				}
3007ce0338dfSJoe Perches			}
300820112475SJoe Perches			if (defined $space_before && $space_before ne "") {
30093705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30103705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
30113705ce5bSJoe Perches				    $fix) {
3012194f66fcSJoe Perches					$fixed[$fixlinenr] =
30133705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30143705ce5bSJoe Perches				}
301520112475SJoe Perches			}
301620112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
30173705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30183705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
30193705ce5bSJoe Perches				    $fix) {
3020194f66fcSJoe Perches					$fixed[$fixlinenr] =
30213705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30223705ce5bSJoe Perches				}
30233705ce5bSJoe Perches
302420112475SJoe Perches			}
302520112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
30263705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30273705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
30283705ce5bSJoe Perches				    $fix) {
3029194f66fcSJoe Perches					$fixed[$fixlinenr] =
30303705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30313705ce5bSJoe Perches				}
303220112475SJoe Perches			}
303320112475SJoe Perches
3034dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
303548ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
303620112475SJoe Perches			if ($suggested_email eq "") {
3037000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
3038000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
303920112475SJoe Perches			} else {
304020112475SJoe Perches				my $dequoted = $suggested_email;
304120112475SJoe Perches				$dequoted =~ s/^"//;
304220112475SJoe Perches				$dequoted =~ s/" </ </;
304320112475SJoe Perches				# Don't force email to have quotes
304420112475SJoe Perches				# Allow just an angle bracketed address
3045fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
3046fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3047fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3048fccaebf0SDwaipayan Ray					    $fix) {
3049fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3050fccaebf0SDwaipayan Ray					}
3051fccaebf0SDwaipayan Ray				}
3052fccaebf0SDwaipayan Ray
3053fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
3054fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
3055fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
3056fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
3057fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3058fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3059fccaebf0SDwaipayan Ray					    $fix) {
3060fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3061fccaebf0SDwaipayan Ray					}
3062fccaebf0SDwaipayan Ray				}
3063fccaebf0SDwaipayan Ray
3064fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
3065fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3066fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
3067000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
3068fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
3069fccaebf0SDwaipayan Ray				}
3070fccaebf0SDwaipayan Ray
3071fccaebf0SDwaipayan Ray
3072fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
3073e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
3074fccaebf0SDwaipayan Ray				# begin with a #
3075fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3076fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
3077fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
3078fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
3079fccaebf0SDwaipayan Ray						my $new_comment = $comment;
3080fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3081fccaebf0SDwaipayan Ray
3082fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
3083fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
3084fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
3085fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
3086fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
3087fccaebf0SDwaipayan Ray
3088fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3089fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
3090fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
3091fccaebf0SDwaipayan Ray
3092fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3093fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3094fccaebf0SDwaipayan Ray						    $fix) {
3095fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3096fccaebf0SDwaipayan Ray						}
3097fccaebf0SDwaipayan Ray					}
3098fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3099fccaebf0SDwaipayan Ray					my $new_comment = $comment;
3100fccaebf0SDwaipayan Ray
3101fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
3102fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
3103fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
3104fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3105fccaebf0SDwaipayan Ray
3106fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
3107fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3108fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
3109fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3110fccaebf0SDwaipayan Ray
3111fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3112fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3113fccaebf0SDwaipayan Ray					    $fix) {
3114fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3115fccaebf0SDwaipayan Ray					}
311620112475SJoe Perches				}
31170a920b5bSAndy Whitcroft			}
31187e51f197SJoe Perches
31197e51f197SJoe Perches# Check for duplicate signatures
31207e51f197SJoe Perches			my $sig_nospace = $line;
31217e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
31227e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
31237e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
31247e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
31257e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
31267e51f197SJoe Perches			} else {
31277e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
31287e51f197SJoe Perches			}
31296c5d24eeSSean Christopherson
31306c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
31316c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
31326c5d24eeSSean Christopherson				if ($email eq $author) {
31336c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31346c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
31356c5d24eeSSean Christopherson				}
31366c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
31376c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31386c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
31396c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
31406c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31416c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31426c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
31436c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31446c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
31456c5d24eeSSean Christopherson				}
31466c5d24eeSSean Christopherson			}
31470a920b5bSAndy Whitcroft		}
31480a920b5bSAndy Whitcroft
3149*bd17e036SNiklas Söderlund# Check Fixes: styles is correct
3150*bd17e036SNiklas Söderlund		if (!$in_header_lines &&
3151*bd17e036SNiklas Söderlund		    $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
3152*bd17e036SNiklas Söderlund			my $orig_commit = "";
3153*bd17e036SNiklas Söderlund			my $id = "0123456789ab";
3154*bd17e036SNiklas Söderlund			my $title = "commit title";
3155*bd17e036SNiklas Söderlund			my $tag_case = 1;
3156*bd17e036SNiklas Söderlund			my $tag_space = 1;
3157*bd17e036SNiklas Söderlund			my $id_length = 1;
3158*bd17e036SNiklas Söderlund			my $id_case = 1;
3159*bd17e036SNiklas Söderlund			my $title_has_quotes = 0;
3160*bd17e036SNiklas Söderlund
3161*bd17e036SNiklas Söderlund			if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) {
3162*bd17e036SNiklas Söderlund				my $tag = $1;
3163*bd17e036SNiklas Söderlund				$orig_commit = $2;
3164*bd17e036SNiklas Söderlund				$title = $3;
3165*bd17e036SNiklas Söderlund
3166*bd17e036SNiklas Söderlund				$tag_case = 0 if $tag eq "Fixes:";
3167*bd17e036SNiklas Söderlund				$tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i);
3168*bd17e036SNiklas Söderlund
3169*bd17e036SNiklas Söderlund				$id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i);
3170*bd17e036SNiklas Söderlund				$id_case = 0 if ($orig_commit !~ /[A-F]/);
3171*bd17e036SNiklas Söderlund
3172*bd17e036SNiklas Söderlund				# Always strip leading/trailing parens then double quotes if existing
3173*bd17e036SNiklas Söderlund				$title = substr($title, 1, -1);
3174*bd17e036SNiklas Söderlund				if ($title =~ /^".*"$/) {
3175*bd17e036SNiklas Söderlund					$title = substr($title, 1, -1);
3176*bd17e036SNiklas Söderlund					$title_has_quotes = 1;
3177*bd17e036SNiklas Söderlund				}
3178*bd17e036SNiklas Söderlund			}
3179*bd17e036SNiklas Söderlund
3180*bd17e036SNiklas Söderlund			my ($cid, $ctitle) = git_commit_info($orig_commit, $id,
3181*bd17e036SNiklas Söderlund							     $title);
3182*bd17e036SNiklas Söderlund
3183*bd17e036SNiklas Söderlund			if ($ctitle ne $title || $tag_case || $tag_space ||
3184*bd17e036SNiklas Söderlund			    $id_length || $id_case || !$title_has_quotes) {
3185*bd17e036SNiklas Söderlund				if (WARN("BAD_FIXES_TAG",
3186*bd17e036SNiklas Söderlund				     "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) &&
3187*bd17e036SNiklas Söderlund				    $fix) {
3188*bd17e036SNiklas Söderlund					$fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")";
3189*bd17e036SNiklas Söderlund				}
3190*bd17e036SNiklas Söderlund			}
3191*bd17e036SNiklas Söderlund		}
3192*bd17e036SNiklas Söderlund
3193a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3194a2fe16b9SJoe Perches		if ($in_header_lines &&
3195a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3196a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3197a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3198a2fe16b9SJoe Perches		}
3199a2fe16b9SJoe Perches
320044d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
320144d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
32027580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
32037580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
32047580c5b9SAditya Srivastava			    $fix) {
32057580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
32067580c5b9SAditya Srivastava			}
32077ebd05efSChristopher Covington		}
32087ebd05efSChristopher Covington
3209369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3210369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3211369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3212369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3213369c8dd3SJoe Perches					# timestamp
3214634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3215634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3216634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3217634cffccSJoe Perches					# stack dump address styles
3218369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3219369c8dd3SJoe Perches		}
3220369c8dd3SJoe Perches
32212a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
32222a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3223bf4daf12SJoe Perches		    length($line) > 75 &&
3224bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3225bf4daf12SJoe Perches					# file delta changes
322636f8b348SJerome Forissier		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
3227bf4daf12SJoe Perches					# filename then :
322827b379afSAditya Srivastava		      $line =~ /^\s*(?:Fixes:|Link:|$signature_tags)/i ||
322927b379afSAditya Srivastava					# A Fixes: or Link: line or signature tag line
3230bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
32312a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
32322a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
32332a076f40SJoe Perches			$commit_log_long_line = 1;
32342a076f40SJoe Perches		}
32352a076f40SJoe Perches
3236bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3237bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3238bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3239bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3240bf4daf12SJoe Perches		}
3241bf4daf12SJoe Perches
3242084a617aSDwaipayan Ray# Check for lines starting with a #
3243084a617aSDwaipayan Ray		if ($in_commit_log && $line =~ /^#/) {
3244084a617aSDwaipayan Ray			if (WARN("COMMIT_COMMENT_SYMBOL",
3245084a617aSDwaipayan Ray				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
3246084a617aSDwaipayan Ray			    $fix) {
3247084a617aSDwaipayan Ray				$fixed[$fixlinenr] =~ s/^/ /;
3248084a617aSDwaipayan Ray			}
3249084a617aSDwaipayan Ray		}
3250084a617aSDwaipayan Ray
32510d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
32524ce9f970SJoe Perches# A correctly formed commit description is:
32534ce9f970SJoe Perches#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
32544ce9f970SJoe Perches# with the commit subject '("' prefix and '")' suffix
32554ce9f970SJoe Perches# This is a fairly compilicated block as it tests for what appears to be
32564ce9f970SJoe Perches# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
32574ce9f970SJoe Perches# possible SHA-1 matches.
32584ce9f970SJoe Perches# A commit match can span multiple lines so this block attempts to find a
32594ce9f970SJoe Perches# complete typical commit on a maximum of 3 lines
32604ce9f970SJoe Perches		if ($perl_version_ok &&
32614ce9f970SJoe Perches		    $in_commit_log && !$commit_log_possible_stack_dump &&
3262a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
3263e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
32644ce9f970SJoe Perches		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
32654ce9f970SJoe Perches		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
3266aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
3267369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
3268bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
3269fe043ea1SJoe Perches			my $init_char = "c";
3270fe043ea1SJoe Perches			my $orig_commit = "";
32710d7835fcSJoe Perches			my $short = 1;
32720d7835fcSJoe Perches			my $long = 0;
32730d7835fcSJoe Perches			my $case = 1;
32740d7835fcSJoe Perches			my $space = 1;
32750d7835fcSJoe Perches			my $id = '0123456789ab';
32760d7835fcSJoe Perches			my $orig_desc = "commit description";
32770d7835fcSJoe Perches			my $description = "";
32784ce9f970SJoe Perches			my $herectx = $herecurr;
32794ce9f970SJoe Perches			my $has_parens = 0;
32804ce9f970SJoe Perches			my $has_quotes = 0;
32810d7835fcSJoe Perches
32824ce9f970SJoe Perches			my $input = $line;
32834ce9f970SJoe Perches			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
32844ce9f970SJoe Perches				for (my $n = 0; $n < 2; $n++) {
32854ce9f970SJoe Perches					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
32864ce9f970SJoe Perches						$orig_desc = $1;
32874ce9f970SJoe Perches						$has_parens = 1;
32884ce9f970SJoe Perches						# Always strip leading/trailing parens then double quotes if existing
32894ce9f970SJoe Perches						$orig_desc = substr($orig_desc, 1, -1);
32904ce9f970SJoe Perches						if ($orig_desc =~ /^".*"$/) {
32914ce9f970SJoe Perches							$orig_desc = substr($orig_desc, 1, -1);
32924ce9f970SJoe Perches							$has_quotes = 1;
32934ce9f970SJoe Perches						}
32944ce9f970SJoe Perches						last;
32954ce9f970SJoe Perches					}
32964ce9f970SJoe Perches					last if ($#lines < $linenr + $n);
32974ce9f970SJoe Perches					$input .= " " . trim($rawlines[$linenr + $n]);
32984ce9f970SJoe Perches					$herectx .= "$rawlines[$linenr + $n]\n";
32994ce9f970SJoe Perches				}
33004ce9f970SJoe Perches				$herectx = $herecurr if (!$has_parens);
3301fe043ea1SJoe Perches			}
3302fe043ea1SJoe Perches
33034ce9f970SJoe Perches			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
33044ce9f970SJoe Perches				$init_char = $1;
33054ce9f970SJoe Perches				$orig_commit = lc($2);
33064ce9f970SJoe Perches				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
33074ce9f970SJoe Perches				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
33084ce9f970SJoe Perches				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
33094ce9f970SJoe Perches				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
33104ce9f970SJoe Perches			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
33114ce9f970SJoe Perches				$orig_commit = lc($1);
33120d7835fcSJoe Perches			}
33130d7835fcSJoe Perches
33140d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
33150d7835fcSJoe Perches							      $id, $orig_desc);
33160d7835fcSJoe Perches
3317948b133aSHeinrich Schuchardt			if (defined($id) &&
33184ce9f970SJoe Perches			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
33194ce9f970SJoe Perches			    $last_git_commit_id_linenr != $linenr - 1) {
3320d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
33214ce9f970SJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
33220d7835fcSJoe Perches			}
33234ce9f970SJoe Perches			#don't report the next line if this line ends in commit and the sha1 hash is the next line
33244ce9f970SJoe Perches			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
3325d311cd44SJoe Perches		}
3326d311cd44SJoe Perches
332713f1937eSJoe Perches# Check for added, moved or deleted files
332813f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
332913f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
333013f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
333113f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
333213f1937eSJoe Perches		      (defined($1) || defined($2))))) {
3333a82603a8SAndrew Jeffery			$is_patch = 1;
333413f1937eSJoe Perches			$reported_maintainer_file = 1;
333513f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
333613f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
333713f1937eSJoe Perches		}
333813f1937eSJoe Perches
3339e400edb1SRob Herring# Check for adding new DT bindings not in schema format
3340e400edb1SRob Herring		if (!$in_commit_log &&
3341e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3342e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3343e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
334456ddc4cdSMauro Carvalho Chehab			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3345e400edb1SRob Herring		}
3346e400edb1SRob Herring
334700df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
33488905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3349000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
3350000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
33516c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
3352de7d4f0eSAndy Whitcroft		}
3353de7d4f0eSAndy Whitcroft
3354de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
3355de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
3356171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
3357171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3358171ae1a4SAndy Whitcroft
3359171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
3360171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
3361171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
3362171ae1a4SAndy Whitcroft
336334d99219SJoe Perches			CHK("INVALID_UTF8",
3364000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
336500df344fSAndy Whitcroft		}
33660a920b5bSAndy Whitcroft
336715662b3eSJoe Perches# Check if it's the start of a commit log
336815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
336915662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
3370eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
3371eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
337215662b3eSJoe Perches			$in_header_lines = 0;
337315662b3eSJoe Perches			$in_commit_log = 1;
3374ed43c4e5SAllen Hubbe			$has_commit_log = 1;
337515662b3eSJoe Perches		}
337615662b3eSJoe Perches
3377fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
3378fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
3379fa64205dSPasi Savanainen		if ($in_header_lines &&
3380fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3381fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
3382fa64205dSPasi Savanainen			$non_utf8_charset = 1;
3383fa64205dSPasi Savanainen		}
3384fa64205dSPasi Savanainen
3385fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
338615662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3387fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
338815662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
338915662b3eSJoe Perches		}
339015662b3eSJoe Perches
3391d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3392d6430f71SJoe Perches		if ($tree && $in_commit_log) {
3393d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
3394d6430f71SJoe Perches				my $file = $1;
3395d6430f71SJoe Perches
3396d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
3397d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
3398d6430f71SJoe Perches					#
3399d6430f71SJoe Perches				} else {
3400d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
3401d6430f71SJoe Perches				}
3402d6430f71SJoe Perches			}
3403d6430f71SJoe Perches		}
3404d6430f71SJoe Perches
340566b47b4aSKees Cook# Check for various typo / spelling mistakes
340666d7a382SJoe Perches		if (defined($misspellings) &&
340766d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
34087da07c31SDwaipayan Ray			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
340966b47b4aSKees Cook				my $typo = $1;
34107da07c31SDwaipayan Ray				my $blank = copy_spacing($rawline);
34117da07c31SDwaipayan Ray				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
34127da07c31SDwaipayan Ray				my $hereptr = "$hereline$ptr\n";
341366b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
341466b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
341566b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
34160675a8fbSJean Delvare				my $msg_level = \&WARN;
34170675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
34180675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
34197da07c31SDwaipayan Ray						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
342066b47b4aSKees Cook				    $fix) {
342166b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
342266b47b4aSKees Cook				}
342366b47b4aSKees Cook			}
342466b47b4aSKees Cook		}
342566b47b4aSKees Cook
3426a8dd86bfSMatteo Croce# check for invalid commit id
3427a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
3428a8dd86bfSMatteo Croce			my $id;
3429a8dd86bfSMatteo Croce			my $description;
3430a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
3431a8dd86bfSMatteo Croce			if (!defined($id)) {
3432a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
3433a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
3434a8dd86bfSMatteo Croce			}
3435a8dd86bfSMatteo Croce		}
3436a8dd86bfSMatteo Croce
3437310cd06bSJoe Perches# check for repeated words separated by a single space
34388d0325ccSAditya Srivastava# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
34398d0325ccSAditya Srivastava		if (($rawline =~ /^\+/ || $in_commit_log) &&
34408d0325ccSAditya Srivastava		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
34411db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3442310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3443310cd06bSJoe Perches
3444310cd06bSJoe Perches				my $first = $1;
3445310cd06bSJoe Perches				my $second = $2;
34461db81a68SDwaipayan Ray				my $start_pos = $-[1];
34471db81a68SDwaipayan Ray				my $end_pos = $+[2];
3448310cd06bSJoe Perches				if ($first =~ /(?:struct|union|enum)/) {
3449310cd06bSJoe Perches					pos($rawline) += length($first) + length($second) + 1;
3450310cd06bSJoe Perches					next;
3451310cd06bSJoe Perches				}
3452310cd06bSJoe Perches
34531db81a68SDwaipayan Ray				next if (lc($first) ne lc($second));
3454310cd06bSJoe Perches				next if ($first eq 'long');
3455310cd06bSJoe Perches
34561db81a68SDwaipayan Ray				# check for character before and after the word matches
34571db81a68SDwaipayan Ray				my $start_char = '';
34581db81a68SDwaipayan Ray				my $end_char = '';
34591db81a68SDwaipayan Ray				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
34601db81a68SDwaipayan Ray				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
34611db81a68SDwaipayan Ray
34621db81a68SDwaipayan Ray				next if ($start_char =~ /^\S$/);
34631db81a68SDwaipayan Ray				next if (index(" \t.,;?!", $end_char) == -1);
34641db81a68SDwaipayan Ray
34658d0325ccSAditya Srivastava				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
34668d0325ccSAditya Srivastava				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
34678d0325ccSAditya Srivastava					next if (!exists($allow_repeated_words{lc($first)}));
34688d0325ccSAditya Srivastava				}
34698d0325ccSAditya Srivastava
3470310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3471310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3472310cd06bSJoe Perches				    $fix) {
3473310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3474310cd06bSJoe Perches				}
3475310cd06bSJoe Perches			}
3476310cd06bSJoe Perches
3477310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3478310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
3479310cd06bSJoe Perches			    $prevrawline =~ /($word_pattern)\s*$/) {
3480310cd06bSJoe Perches				my $last_word = $1;
3481310cd06bSJoe Perches				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
3482310cd06bSJoe Perches					if (WARN("REPEATED_WORD",
3483310cd06bSJoe Perches						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3484310cd06bSJoe Perches					    $fix) {
3485310cd06bSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3486310cd06bSJoe Perches					}
3487310cd06bSJoe Perches				}
3488310cd06bSJoe Perches			}
3489310cd06bSJoe Perches		}
3490310cd06bSJoe Perches
349130670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
349230670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
349300df344fSAndy Whitcroft
34940a920b5bSAndy Whitcroft#trailing whitespace
34959c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
3496c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3497d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3498d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
3499d5e616fcSJoe Perches			    $fix) {
3500194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
3501d5e616fcSJoe Perches			}
3502c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
3503c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35043705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
35053705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
35063705ce5bSJoe Perches			    $fix) {
3507194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
35083705ce5bSJoe Perches			}
35093705ce5bSJoe Perches
3510d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
35110a920b5bSAndy Whitcroft		}
35125368df20SAndy Whitcroft
35134783f894SJosh Triplett# Check for FSF mailing addresses.
3514109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
35151bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
35163e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
35173e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
35184783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35190675a8fbSJean Delvare			my $msg_level = \&ERROR;
35200675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
35210675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
35224783f894SJosh 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)
35234783f894SJosh Triplett		}
35244783f894SJosh Triplett
35253354957aSAndi Kleen# check for Kconfig help text having a real description
35269fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
35279fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
35283354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3529678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3530678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3531678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3532678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
3533b8709bceSJoe Perches			my $ln = $linenr;
3534b8709bceSJoe Perches			my $needs_help = 0;
3535b8709bceSJoe Perches			my $has_help = 0;
3536b8709bceSJoe Perches			my $help_length = 0;
3537b8709bceSJoe Perches			while (defined $lines[$ln]) {
3538b8709bceSJoe Perches				my $f = $lines[$ln++];
35399fe287d7SAndy Whitcroft
35409fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
3541b8709bceSJoe Perches				last if ($f !~ /^[\+ ]/);	# !patch context
3542a1385803SAndy Whitcroft
3543b8709bceSJoe Perches				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3544b8709bceSJoe Perches					$needs_help = 1;
3545b8709bceSJoe Perches					next;
3546b8709bceSJoe Perches				}
3547b8709bceSJoe Perches				if ($f =~ /^\+\s*help\s*$/) {
3548b8709bceSJoe Perches					$has_help = 1;
3549b8709bceSJoe Perches					next;
3550a1385803SAndy Whitcroft				}
3551a1385803SAndy Whitcroft
3552b8709bceSJoe Perches				$f =~ s/^.//;	# strip patch context [+ ]
3553b8709bceSJoe Perches				$f =~ s/#.*//;	# strip # directives
3554b8709bceSJoe Perches				$f =~ s/^\s+//;	# strip leading blanks
3555b8709bceSJoe Perches				next if ($f =~ /^$/);	# skip blank lines
3556678ae162SUlf Magnusson
3557b8709bceSJoe Perches				# At the end of this Kconfig block:
3558678ae162SUlf Magnusson				# This only checks context lines in the patch
3559678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3560678ae162SUlf Magnusson				# positives, even though some of these are
3561678ae162SUlf Magnusson				# common words in help texts
3562b8709bceSJoe Perches				if ($f =~ /^(?:config|menuconfig|choice|endchoice|
3563678ae162SUlf Magnusson					       if|endif|menu|endmenu|source)\b/x) {
35649fe287d7SAndy Whitcroft					last;
35659fe287d7SAndy Whitcroft				}
3566b8709bceSJoe Perches				$help_length++ if ($has_help);
35673354957aSAndi Kleen			}
3568b8709bceSJoe Perches			if ($needs_help &&
3569b8709bceSJoe Perches			    $help_length < $min_conf_desc_length) {
3570b8709bceSJoe Perches				my $stat_real = get_stat_real($linenr, $ln - 1);
3571000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
3572b8709bceSJoe Perches				     "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n");
357356193274SVadim Bendebury			}
35743354957aSAndi Kleen		}
35753354957aSAndi Kleen
35767ccf41a8SJoe Perches# check MAINTAINERS entries
35777ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
35787ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
35797ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3580628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3581628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3582628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3583628f91a2SJoe Perches				    $fix) {
3584628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3585628f91a2SJoe Perches				}
3586628f91a2SJoe Perches			}
35877ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
35887ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
35897ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
35907ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
35917ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
35927ccf41a8SJoe Perches				my $cur = $1;
35937ccf41a8SJoe Perches				my $curval = $2;
35947ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
35957ccf41a8SJoe Perches				my $prev = $1;
35967ccf41a8SJoe Perches				my $prevval = $2;
35977ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
35987ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
35997ccf41a8SJoe Perches				if ($curindex < 0) {
36007ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
36017ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
36027ccf41a8SJoe Perches				} else {
36037ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
36047ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
36057ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
36067ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
36077ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
36087ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
36097ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
36107ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
36117ccf41a8SJoe Perches					}
36127ccf41a8SJoe Perches				}
36137ccf41a8SJoe Perches			}
36147ccf41a8SJoe Perches		}
3615628f91a2SJoe Perches
3616c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3617c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3618c68e5878SArnaud Lacombe			my $flag = $1;
3619c68e5878SArnaud Lacombe			my $replacement = {
3620c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3621c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3622c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3623c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3624c68e5878SArnaud Lacombe			};
3625c68e5878SArnaud Lacombe
3626c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3627c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3628c68e5878SArnaud Lacombe		}
3629c68e5878SArnaud Lacombe
3630bff5da43SRob Herring# check for DT compatible documentation
36317dd05b38SFlorian Vaussard		if (defined $root &&
36327dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
36337dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
36347dd05b38SFlorian Vaussard
3635bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3636bff5da43SRob Herring
3637cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3638852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3639cc93319bSFlorian Vaussard
3640bff5da43SRob Herring			foreach my $compat (@compats) {
3641bff5da43SRob Herring				my $compat2 = $compat;
3642185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3643185d566bSRob Herring				my $compat3 = $compat;
3644185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3645185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3646bff5da43SRob Herring				if ( $? >> 8 ) {
3647bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3648bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3649bff5da43SRob Herring				}
3650bff5da43SRob Herring
36514fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
36524fbf32a6SFlorian Vaussard				my $vendor = $1;
3653852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3654bff5da43SRob Herring				if ( $? >> 8 ) {
3655bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3656cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3657bff5da43SRob Herring				}
3658bff5da43SRob Herring			}
3659bff5da43SRob Herring		}
3660bff5da43SRob Herring
36619f3a8992SRob Herring# check for using SPDX license tag at beginning of files
36629f3a8992SRob Herring		if ($realline == $checklicenseline) {
36639f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
36649f3a8992SRob Herring				$checklicenseline = 2;
36659f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
36669f3a8992SRob Herring				my $comment = "";
36679f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
36689f3a8992SRob Herring					$comment = '/*';
36699f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
36709f3a8992SRob Herring					$comment = '//';
3671c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
36729f3a8992SRob Herring					$comment = '#';
36739f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
36749f3a8992SRob Herring					$comment = '..';
36759f3a8992SRob Herring				}
36769f3a8992SRob Herring
3677fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3678fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3679fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3680ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3681fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3682fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3683fdf13693SJoe Perches				}
3684fdf13693SJoe Perches
36859f3a8992SRob Herring				if ($comment !~ /^$/ &&
3686ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
36879f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
36889f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
36893b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
36903b6e8ac9SJoe Perches					my $spdx_license = $1;
36913b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
36923b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
36933b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
36943b6e8ac9SJoe Perches					}
369550c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
369650c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
369750c92900SLubomir Rintel						my $msg_level = \&WARN;
369850c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
369950c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
370050c92900SLubomir Rintel
370150c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
370250c92900SLubomir Rintel						    $fix) {
370350c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
370450c92900SLubomir Rintel						}
370550c92900SLubomir Rintel					}
37069f3a8992SRob Herring				}
37079f3a8992SRob Herring			}
37089f3a8992SRob Herring		}
37099f3a8992SRob Herring
3710a0154cdbSJoe Perches# check for embedded filenames
3711a0154cdbSJoe Perches		if ($rawline =~ /^\+.*\Q$realfile\E/) {
3712a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3713a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3714a0154cdbSJoe Perches		}
3715a0154cdbSJoe Perches
37165368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3717d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
37185368df20SAndy Whitcroft
3719a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3720a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3721a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3722a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3723a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3724a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3725a8da38a9SJoe Perches		}
3726a8da38a9SJoe Perches
372747e0c88bSJoe Perches# line length limit (with some exclusions)
372847e0c88bSJoe Perches#
372947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
373047e0c88bSJoe Perches#	logging functions like pr_info that end in a string
373147e0c88bSJoe Perches#	lines with a single string
373247e0c88bSJoe Perches#	#defines that are a single string
37332e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
373447e0c88bSJoe Perches#
373547e0c88bSJoe Perches# There are 3 different line length message types:
3736ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
373747e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
373847e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
373947e0c88bSJoe Perches#
374047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
374147e0c88bSJoe Perches#
374247e0c88bSJoe Perches
3743b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
374447e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
374547e0c88bSJoe Perches
374647e0c88bSJoe Perches			# Check the allowed long line types first
374747e0c88bSJoe Perches
374847e0c88bSJoe Perches			# logging functions that end in a string that starts
374947e0c88bSJoe Perches			# before $max_line_length
375047e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
375147e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
375247e0c88bSJoe Perches				$msg_type = "";
375347e0c88bSJoe Perches
375447e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
375547e0c88bSJoe Perches			# #defines with only strings
375647e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
375747e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
375847e0c88bSJoe Perches				$msg_type = "";
375947e0c88bSJoe Perches
3760cc147506SJoe Perches			# More special cases
3761cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3762cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3763d560a5f8SJoe Perches				$msg_type = "";
3764d560a5f8SJoe Perches
37652e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
37662e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
37672e4bbbc5SAndreas Brauchli				$msg_type = "";
37682e4bbbc5SAndreas Brauchli
376947e0c88bSJoe Perches			# Otherwise set the alternate message types
377047e0c88bSJoe Perches
377147e0c88bSJoe Perches			# a comment starts before $max_line_length
377247e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
377347e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
377447e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
377547e0c88bSJoe Perches
377647e0c88bSJoe Perches			# a quoted string starts before $max_line_length
377747e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
377847e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
377947e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
378047e0c88bSJoe Perches			}
378147e0c88bSJoe Perches
378247e0c88bSJoe Perches			if ($msg_type ne "" &&
378347e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3784bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3785bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3786bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3787bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
37880a920b5bSAndy Whitcroft			}
378947e0c88bSJoe Perches		}
37900a920b5bSAndy Whitcroft
37918905a67cSAndy Whitcroft# check for adding lines without a newline.
37928905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
379347ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
379447ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
379547ca69b8STom Rix			    $fix) {
379647ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
379747ca69b8STom Rix			}
37988905a67cSAndy Whitcroft		}
37998905a67cSAndy Whitcroft
3800de93245cSAditya Srivastava# check for .L prefix local symbols in .S files
3801de93245cSAditya Srivastava		if ($realfile =~ /\.S$/ &&
3802de93245cSAditya Srivastava		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3803de93245cSAditya Srivastava			WARN("AVOID_L_PREFIX",
3804de93245cSAditya 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);
3805de93245cSAditya Srivastava		}
3806de93245cSAditya Srivastava
3807b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3808de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
38090a920b5bSAndy Whitcroft
38100a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3811713a09deSAntonio Borneo# more than $tabsize must use tabs.
3812c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3813c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3814c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3815d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
38163705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
38173705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
38183705ce5bSJoe Perches			    $fix) {
3819194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
38203705ce5bSJoe Perches			}
38210a920b5bSAndy Whitcroft		}
38220a920b5bSAndy Whitcroft
382308e44365SAlberto Panizzo# check for space before tabs.
382408e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
382508e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
38263705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
38273705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
38283705ce5bSJoe Perches			    $fix) {
3829194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3830713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3831194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3832c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
38333705ce5bSJoe Perches			}
383408e44365SAlberto Panizzo		}
383508e44365SAlberto Panizzo
38366a487211SJoe Perches# check for assignments on the start of a line
38376a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3838da7355abSAditya Srivastava			my $operator = $1;
3839da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3840da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3841da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3842da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3843da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3844da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3845da7355abSAditya Srivastava			}
38466a487211SJoe Perches		}
38476a487211SJoe Perches
3848d1fe9c09SJoe Perches# check for && or || at the start of a line
3849d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
38508e08f076SAditya Srivastava			my $operator = $1;
38518e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
38528e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
38538e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
38548e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
38558e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
38568e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
38578e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
38588e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
38598e08f076SAditya Srivastava			}
3860d1fe9c09SJoe Perches		}
3861d1fe9c09SJoe Perches
3862a91e8994SJoe Perches# check indentation starts on a tab stop
38635b57980dSJoe Perches		if ($perl_version_ok &&
3864bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3865a91e8994SJoe Perches			my $indent = length($1);
3866713a09deSAntonio Borneo			if ($indent % $tabsize) {
3867a91e8994SJoe Perches				if (WARN("TABSTOP",
3868a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3869a91e8994SJoe Perches				    $fix) {
3870713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3871a91e8994SJoe Perches				}
3872a91e8994SJoe Perches			}
3873a91e8994SJoe Perches		}
3874a91e8994SJoe Perches
3875d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
38765b57980dSJoe Perches		if ($perl_version_ok &&
3877fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3878d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3879d1fe9c09SJoe Perches			my $oldindent = $1;
3880d1fe9c09SJoe Perches			my $rest = $2;
3881d1fe9c09SJoe Perches
3882d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3883d1fe9c09SJoe Perches			if ($pos >= 0) {
3884b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3885b34a26f3SJoe Perches				my $newindent = $2;
3886d1fe9c09SJoe Perches
3887d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3888713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3889713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3890d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3891d1fe9c09SJoe Perches
3892d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3893d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
38943705ce5bSJoe Perches
38953705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
38963705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
38973705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3898194f66fcSJoe Perches						$fixed[$fixlinenr] =~
38993705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
39003705ce5bSJoe Perches					}
3901d1fe9c09SJoe Perches				}
3902d1fe9c09SJoe Perches			}
3903d1fe9c09SJoe Perches		}
3904d1fe9c09SJoe Perches
39056ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
39066ab3a970SJoe Perches# avoid checking a few false positives:
39076ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
39086ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
39096ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
39106ab3a970SJoe Perches#   multiline macros that define functions
39116ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
39126ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
39136ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
39143705ce5bSJoe Perches			if (CHK("SPACING",
3915f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
39163705ce5bSJoe Perches			    $fix) {
3917194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3918f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
39193705ce5bSJoe Perches			}
3920aad4f614SJoe Perches		}
3921aad4f614SJoe Perches
392286406b1cSJoe Perches# Block comment styles
392386406b1cSJoe Perches# Networking with an initial /*
392405880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3925fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
392685ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
3927c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
392805880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
392905880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
393005880600SJoe Perches		}
393105880600SJoe Perches
393286406b1cSJoe Perches# Block comments use * on subsequent lines
393386406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
393486406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3935a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
393661135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3937a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
393886406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
393986406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3940a605e32eSJoe Perches		}
3941a605e32eSJoe Perches
394286406b1cSJoe Perches# Block comments use */ on trailing lines
394386406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3944c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3945c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3946c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
394786406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
394886406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
394905880600SJoe Perches		}
395005880600SJoe Perches
395108eb9b80SJoe Perches# Block comment * alignment
395208eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3953af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3954af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3955af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
395608eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3957af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3958af207524SJoe Perches			my $oldindent;
395908eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3960af207524SJoe Perches			if (defined($1)) {
3961af207524SJoe Perches				$oldindent = expand_tabs($1);
3962af207524SJoe Perches			} else {
3963af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3964af207524SJoe Perches				$oldindent = expand_tabs($1);
3965af207524SJoe Perches			}
396608eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
396708eb9b80SJoe Perches			my $newindent = $1;
396808eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3969af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
397008eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
397108eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
397208eb9b80SJoe Perches			}
397308eb9b80SJoe Perches		}
397408eb9b80SJoe Perches
39757f619191SJoe Perches# check for missing blank lines after struct/union declarations
39767f619191SJoe Perches# with exceptions for various attributes and macros
39777f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
39787f619191SJoe Perches		    $line =~ /^\+/ &&
39797f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
398005dc40e6SJoe Perches		      $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ ||
39817f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
39827f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
39837f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
39847f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
39857f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
39860bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
39877f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3988d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3989d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3990d752fcc8SJoe Perches			    $fix) {
3991f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3992d752fcc8SJoe Perches			}
39937f619191SJoe Perches		}
39947f619191SJoe Perches
3995365dd4eaSJoe Perches# check for multiple consecutive blank lines
3996365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3997365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3998365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3999d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
4000d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
4001d752fcc8SJoe Perches			    $fix) {
4002f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4003d752fcc8SJoe Perches			}
4004d752fcc8SJoe Perches
4005365dd4eaSJoe Perches			$last_blank_line = $linenr;
4006365dd4eaSJoe Perches		}
4007365dd4eaSJoe Perches
40083b617e3bSJoe Perches# check for missing blank lines after declarations
4009b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
4010b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
4011b5e8736aSJoe Perches			# use temporaries
4012b5e8736aSJoe Perches			my $sl = $sline;
4013b5e8736aSJoe Perches			my $pl = $prevline;
4014b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
4015b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4016b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4017b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
40185a4e1fd3SJoe Perches			# function pointer declarations
4019b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
40203f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
4021b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
40223f7bac03SJoe Perches			# known declaration macros
4023b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
40243f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
4025b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
40263f7bac03SJoe Perches			# other possible extensions of declaration lines
4027b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
40283f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
4029b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
40303f7bac03SJoe Perches			# looks like a declaration
4031b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
40325a4e1fd3SJoe Perches			# function pointer declarations
4033b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
40343f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
4035b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
40363f7bac03SJoe Perches			# known declaration macros
4037b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
40383f7bac03SJoe Perches			# start of struct or union or enum
4039b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
40403f7bac03SJoe Perches			# start or end of block or continuation of declaration
4041b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
40423f7bac03SJoe Perches			# bitfield continuation
4043b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
40443f7bac03SJoe Perches			# other possible extensions of declaration lines
4045b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
4046d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
4047d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
4048d752fcc8SJoe Perches				    $fix) {
4049f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
4050d752fcc8SJoe Perches				}
40513b617e3bSJoe Perches			}
4052b5e8736aSJoe Perches		}
40533b617e3bSJoe Perches
40545f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
40556b4c5bebSAndy Whitcroft# Exceptions:
40566b4c5bebSAndy Whitcroft#  1) within comments
40576b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
40586b4c5bebSAndy Whitcroft#  3) hanging labels
40593705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
40605f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
40613705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
40623705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
40633705ce5bSJoe Perches			    $fix) {
4064194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
40653705ce5bSJoe Perches			}
40665f7ddae6SRaffaele Recalcati		}
40675f7ddae6SRaffaele Recalcati
4068b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
4069b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
4070b9ea10d6SAndy Whitcroft
40715751a24eSJoe Perches# check for unusual line ending [ or (
40725751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
40735751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
40745751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
40755751a24eSJoe Perches		}
40765751a24eSJoe Perches
40774dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
40784dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
40794dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
40804dbed76fSJoe Perches			$context_function = $1;
40814dbed76fSJoe Perches		}
40824dbed76fSJoe Perches
40834dbed76fSJoe Perches# check if this appears to be the end of function declaration
40844dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
40854dbed76fSJoe Perches			undef $context_function;
40864dbed76fSJoe Perches		}
40874dbed76fSJoe Perches
4088032a4c0fSJoe Perches# check indentation of any line with a bare else
4089840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
4090032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
4091032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
4092032a4c0fSJoe Perches			my $tabs = length($1) + 1;
4093840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
4094840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
4095840080a0SJoe Perches			     defined $lines[$linenr] &&
4096840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
4097032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
4098032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
4099032a4c0fSJoe Perches			}
4100032a4c0fSJoe Perches		}
4101032a4c0fSJoe Perches
4102c00df19aSJoe Perches# check indentation of a line with a break;
4103dc58bc55SJoe Perches# if the previous line is a goto, return or break
4104dc58bc55SJoe Perches# and is indented the same # of tabs
4105c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4106c00df19aSJoe Perches			my $tabs = $1;
4107dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4108dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
4109dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
4110dc58bc55SJoe Perches				    $fix) {
4111dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
4112dc58bc55SJoe Perches				}
4113c00df19aSJoe Perches			}
4114c00df19aSJoe Perches		}
4115c00df19aSJoe Perches
4116c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
4117cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4118000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
4119000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4120c2fdda0dSAndy Whitcroft		}
412122f2a2efSAndy Whitcroft
412256e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
412356e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
412456e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
412556e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
412656e77d70SJoe Perches		}
412756e77d70SJoe Perches
41289c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
41292b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
41302b474a1aSAndy Whitcroft		    $realline_next);
41313e469cdcSAndy Whitcroft#print "LINE<$line>\n";
4132ca819864SJoe Perches		if ($linenr > $suppress_statement &&
41331b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
4134170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4135f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4136171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
4137171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
4138171ae1a4SAndy Whitcroft
41393e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
41403e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
41413e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
41423e469cdcSAndy Whitcroft			# until we hit end of it.
41433e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
41443e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
41453e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
41463e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
41473e469cdcSAndy Whitcroft			}
4148f74bd194SAndy Whitcroft
41492b474a1aSAndy Whitcroft			# Find the real next line.
41502b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
41512b474a1aSAndy Whitcroft			if (defined $realline_next &&
41522b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
41532b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
41542b474a1aSAndy Whitcroft				$realline_next++;
41552b474a1aSAndy Whitcroft			}
41562b474a1aSAndy Whitcroft
4157171ae1a4SAndy Whitcroft			my $s = $stat;
4158171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
4159cf655043SAndy Whitcroft
4160c2fdda0dSAndy Whitcroft			# Ignore goto labels.
4161171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
4162c2fdda0dSAndy Whitcroft
4163c2fdda0dSAndy Whitcroft			# Ignore functions being called
4164171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
4165c2fdda0dSAndy Whitcroft
4166463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
4167463f2864SAndy Whitcroft
4168c45dcabdSAndy Whitcroft			# declarations always start with types
4169d2506586SAndy 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) {
4170c45dcabdSAndy Whitcroft				my $type = $1;
4171c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
4172c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
4173c45dcabdSAndy Whitcroft
41746c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
4175a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4176c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
4177c2fdda0dSAndy Whitcroft			}
41788905a67cSAndy Whitcroft
41796c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
418065863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4181c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
41829c0ca6f9SAndy Whitcroft			}
41838905a67cSAndy Whitcroft
41848905a67cSAndy Whitcroft			# Check for any sort of function declaration.
41858905a67cSAndy Whitcroft			# int foo(something bar, other baz);
41868905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
4187171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
41888905a67cSAndy Whitcroft				my ($name_len) = length($1);
41898905a67cSAndy Whitcroft
4190cf655043SAndy Whitcroft				my $ctx = $s;
4191773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
41928905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
4193cf655043SAndy Whitcroft
41948905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4195c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
41968905a67cSAndy Whitcroft
4197c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
41988905a67cSAndy Whitcroft					}
41998905a67cSAndy Whitcroft				}
42008905a67cSAndy Whitcroft			}
42018905a67cSAndy Whitcroft
42029c0ca6f9SAndy Whitcroft		}
42039c0ca6f9SAndy Whitcroft
420400df344fSAndy Whitcroft#
420500df344fSAndy Whitcroft# Checks which may be anchored in the context.
420600df344fSAndy Whitcroft#
420700df344fSAndy Whitcroft
420800df344fSAndy Whitcroft# Check for switch () and associated case and default
420900df344fSAndy Whitcroft# statements should be at the same indent.
421000df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
421100df344fSAndy Whitcroft			my $err = '';
421200df344fSAndy Whitcroft			my $sep = '';
421300df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
421400df344fSAndy Whitcroft			shift(@ctx);
421500df344fSAndy Whitcroft			for my $ctx (@ctx) {
421600df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
421700df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
421800df344fSAndy Whitcroft							$indent != $cindent) {
421900df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
422000df344fSAndy Whitcroft					$sep = '';
422100df344fSAndy Whitcroft				} else {
422200df344fSAndy Whitcroft					$sep = "[...]\n";
422300df344fSAndy Whitcroft				}
422400df344fSAndy Whitcroft			}
422500df344fSAndy Whitcroft			if ($err ne '') {
4226000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4227000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4228de7d4f0eSAndy Whitcroft			}
4229de7d4f0eSAndy Whitcroft		}
4230de7d4f0eSAndy Whitcroft
4231de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4232de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
42330fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4234773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4235773647a0SAndy Whitcroft
42369c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
42378eef05ddSJoe Perches
42388eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
42398eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
42408eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
42418eef05ddSJoe Perches			}
42428eef05ddSJoe Perches
4243de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4244de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4245de7d4f0eSAndy Whitcroft
4246548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4247548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4248de7d4f0eSAndy Whitcroft
4249548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4250548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4251548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4252548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4253548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4254773647a0SAndy Whitcroft				$ctx_ln++;
4255773647a0SAndy Whitcroft			}
4256548596d5SAndy Whitcroft
425753210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
425853210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4259773647a0SAndy Whitcroft
4260773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4261000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4262000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
426301464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
426400df344fSAndy Whitcroft			}
4265773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4266773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4267773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4268773647a0SAndy Whitcroft			{
42699c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
42709c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4271000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4272000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
427301464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
42749c0ca6f9SAndy Whitcroft				}
42759c0ca6f9SAndy Whitcroft			}
427600df344fSAndy Whitcroft		}
427700df344fSAndy Whitcroft
42784d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4279f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
42803e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
42813e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
42823e469cdcSAndy Whitcroft					if (!defined $stat);
42834d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
42844d001e4dSAndy Whitcroft
42854d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
42864d001e4dSAndy Whitcroft
42879f5af480SJoe Perches			# remove inline comments
42889f5af480SJoe Perches			$s =~ s/$;/ /g;
42899f5af480SJoe Perches			$c =~ s/$;/ /g;
42904d001e4dSAndy Whitcroft
42914d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
42926f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
42936f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
42944d001e4dSAndy Whitcroft
42959f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
42969f5af480SJoe Perches			# none on the first line, and are going to readd them
42979f5af480SJoe Perches			# where necessary.
42989f5af480SJoe Perches			$s =~ s/\n./\n/gs;
42999f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
43009f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
43019f5af480SJoe Perches			}
43029f5af480SJoe Perches
43034d001e4dSAndy Whitcroft			# We want to check the first line inside the block
43044d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
43054d001e4dSAndy Whitcroft			#  1) any blank line termination
43064d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
43074d001e4dSAndy Whitcroft			#  3) any do (...) {
43084d001e4dSAndy Whitcroft			my $continuation = 0;
43094d001e4dSAndy Whitcroft			my $check = 0;
43104d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
43114d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
43124d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
43134d001e4dSAndy Whitcroft				$continuation = 1;
43144d001e4dSAndy Whitcroft			}
43159bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
43164d001e4dSAndy Whitcroft				$check = 1;
43174d001e4dSAndy Whitcroft				$cond_lines++;
43184d001e4dSAndy Whitcroft			}
43194d001e4dSAndy Whitcroft
43204d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
43214d001e4dSAndy Whitcroft			# preprocessor statement.
43224d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
43234d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
43244d001e4dSAndy Whitcroft				$check = 0;
43254d001e4dSAndy Whitcroft			}
43264d001e4dSAndy Whitcroft
43279bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4328740504c6SAndy Whitcroft			$continuation = 0;
43299bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
43309bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
43314d001e4dSAndy Whitcroft
4332f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4333f16fa28fSAndy Whitcroft				# is not linear.
4334f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4335f16fa28fSAndy Whitcroft					$check = 0;
4336f16fa28fSAndy Whitcroft				}
4337f16fa28fSAndy Whitcroft
43389bd49efeSAndy Whitcroft				# Ignore:
43399bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
43409bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
43419bd49efeSAndy Whitcroft				#  3) labels.
4342740504c6SAndy Whitcroft				if ($continuation ||
4343740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
43449bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
43459bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4346740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
434730dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
43489bd49efeSAndy Whitcroft						$cond_lines++;
43499bd49efeSAndy Whitcroft					}
43504d001e4dSAndy Whitcroft				}
435130dad6ebSAndy Whitcroft			}
43524d001e4dSAndy Whitcroft
43534d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
43544d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
43554d001e4dSAndy Whitcroft
43564d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
43574d001e4dSAndy Whitcroft			# this is not this patch's fault.
43584d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
43594d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
43604d001e4dSAndy Whitcroft				$check = 0;
43614d001e4dSAndy Whitcroft			}
43624d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
43634d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
43644d001e4dSAndy Whitcroft			}
43654d001e4dSAndy Whitcroft
43669bd49efeSAndy 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";
43674d001e4dSAndy Whitcroft
43689f5af480SJoe Perches			if ($check && $s ne '' &&
4369713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
43709f5af480SJoe Perches			     ($sindent < $indent) ||
4371f6950a73SJoe Perches			     ($sindent == $indent &&
4372f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4373713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4374000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4375000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
43764d001e4dSAndy Whitcroft			}
43774d001e4dSAndy Whitcroft		}
43784d001e4dSAndy Whitcroft
43796c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
43806c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
43811f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
43821f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
43836c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4384c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4385c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4386cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4387cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
43881f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4389c2fdda0dSAndy Whitcroft		}
43906c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
43916c72ffaaSAndy Whitcroft
439200df344fSAndy Whitcroft#ignore lines not being added
43933705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
439400df344fSAndy Whitcroft
439599ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
439699ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
439799ca38c2SJoe Perches#	struct foo bar = *(&(bar));
439899ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
439999ca38c2SJoe Perches			my $var = $1;
440099ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
440199ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
440299ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
440399ca38c2SJoe Perches			}
440499ca38c2SJoe Perches		}
440599ca38c2SJoe Perches
440611ca40a0SJoe Perches# check for dereferences that span multiple lines
440711ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
440811ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
440911ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
441011ca40a0SJoe Perches			my $ref = $1;
441111ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
441211ca40a0SJoe Perches			$ref .= $1;
441311ca40a0SJoe Perches			$ref =~ s/\s//g;
441411ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
441511ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
441611ca40a0SJoe Perches		}
441711ca40a0SJoe Perches
4418a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4419c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4420a1ce18e4SJoe Perches			my $type = $1;
4421a1ce18e4SJoe Perches			my $var = $2;
4422207a8e84SJoe Perches			$var = "" if (!defined $var);
4423207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4424a1ce18e4SJoe Perches				my $sign = $1;
4425a1ce18e4SJoe Perches				my $pointer = $2;
4426a1ce18e4SJoe Perches
4427a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4428a1ce18e4SJoe Perches
4429a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4430a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4431a1ce18e4SJoe Perches				    $fix) {
4432a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4433207a8e84SJoe Perches					my $comp_pointer = $pointer;
4434207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4435207a8e84SJoe Perches					$decl .= $comp_pointer;
4436207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4437207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4438a1ce18e4SJoe Perches				}
4439a1ce18e4SJoe Perches			}
4440a1ce18e4SJoe Perches		}
4441a1ce18e4SJoe Perches
4442653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
44437429c690SAndy Whitcroft		if ($dbg_type) {
44447429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4445000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4446000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
44477429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4448000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4449000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
44507429c690SAndy Whitcroft			}
4451653d4876SAndy Whitcroft			next;
4452653d4876SAndy Whitcroft		}
4453a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4454a1ef277eSAndy Whitcroft		if ($dbg_attr) {
44559360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4456000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4457000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
44589360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4459000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4460000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4461a1ef277eSAndy Whitcroft			}
4462a1ef277eSAndy Whitcroft			next;
4463a1ef277eSAndy Whitcroft		}
4464653d4876SAndy Whitcroft
4465f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
446699423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
446799423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4468d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4469d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4470f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4471f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4472f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4473d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4474d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4475f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4476d752fcc8SJoe Perches				$fixedline = $line;
44778d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4478f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4479d752fcc8SJoe Perches			}
4480f0a594c1SAndy Whitcroft		}
4481f0a594c1SAndy Whitcroft
448200df344fSAndy Whitcroft#
448300df344fSAndy Whitcroft# Checks which are anchored on the added line.
448400df344fSAndy Whitcroft#
448500df344fSAndy Whitcroft
4486653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4487c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4488653d4876SAndy Whitcroft			my $path = $1;
4489653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4490000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4491495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4492495e9d84SJoe Perches			}
4493495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4494495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4495495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4496653d4876SAndy Whitcroft			}
4497653d4876SAndy Whitcroft		}
4498653d4876SAndy Whitcroft
449900df344fSAndy Whitcroft# no C99 // comments
450000df344fSAndy Whitcroft		if ($line =~ m{//}) {
45013705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
45023705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
45033705ce5bSJoe Perches			    $fix) {
4504194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
45053705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
45063705ce5bSJoe Perches					my $comment = trim($1);
4507194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
45083705ce5bSJoe Perches				}
45093705ce5bSJoe Perches			}
451000df344fSAndy Whitcroft		}
451100df344fSAndy Whitcroft		# Remove C99 comments.
45120a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
45136c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
45140a920b5bSAndy Whitcroft
45152b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
45162b474a1aSAndy Whitcroft# the whole statement.
45172b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
45182b474a1aSAndy Whitcroft		if (defined $realline_next &&
45192b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
45202b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
452136794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
45223cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
45233cbf62dfSAndy Whitcroft			# a prefix:
45243cbf62dfSAndy Whitcroft			#   XXX(foo);
45253cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4526653d4876SAndy Whitcroft			my $name = $1;
452770a11659SJoe Perches			$name =~ s/^\s*($Ident).*/$1/;
452887a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
45293cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
45303cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
45313cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
45323cbf62dfSAndy Whitcroft
45333cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
45342b474a1aSAndy Whitcroft				\n.}\s*$|
453548012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
453648012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
453748012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
45382b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
45392b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
454048012058SAndy Whitcroft			    )/x) {
45412b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
45422b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
45432b474a1aSAndy Whitcroft			} else {
45442b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
45450a920b5bSAndy Whitcroft			}
45460a920b5bSAndy Whitcroft		}
45472b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
45482b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
454936794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
45502b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
45512b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
45522b474a1aSAndy Whitcroft		}
45532b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
45542b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4555000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4556000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
45572b474a1aSAndy Whitcroft		}
45580a920b5bSAndy Whitcroft
45595150bda4SJoe Eloff# check for global initialisers.
45605b8f82e1SSong Liu		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
45615b8f82e1SSong Liu		    !exclude_global_initialisers($realfile)) {
4562d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
45636d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4564d5e616fcSJoe Perches			    $fix) {
45656d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4566d5e616fcSJoe Perches			}
4567f0a594c1SAndy Whitcroft		}
45680a920b5bSAndy Whitcroft# check for static initialisers.
45696d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4570d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
45716d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4572d5e616fcSJoe Perches				      $herecurr) &&
4573d5e616fcSJoe Perches			    $fix) {
45746d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4575d5e616fcSJoe Perches			}
45760a920b5bSAndy Whitcroft		}
45770a920b5bSAndy Whitcroft
45781813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
45791813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
45801813087dSJoe Perches			my $tmp = trim($1);
45811813087dSJoe Perches			WARN("MISORDERED_TYPE",
45821813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
45831813087dSJoe Perches		}
45841813087dSJoe Perches
4585809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4586809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4587809e082eSJoe Perches			my $type = trim($1);
4588809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4589809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4590809e082eSJoe Perches			my $new_type = $type;
4591809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4592809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4593809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4594809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4595809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4596809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4597809e082eSJoe Perches			$new_type = trim($new_type);
4598809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4599809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4600809e082eSJoe Perches			    $fix) {
4601809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4602809e082eSJoe Perches			}
4603809e082eSJoe Perches		}
4604809e082eSJoe Perches
4605cb710ecaSJoe Perches# check for static const char * arrays.
4606cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4607000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4608000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4609cb710ecaSJoe Perches				$herecurr);
4610cb710ecaSJoe Perches		}
4611cb710ecaSJoe Perches
461277b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
461377b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
461477b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
461577b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
461677b8c0a8SJoe Perches			    $fix) {
461777b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
461877b8c0a8SJoe Perches			}
461977b8c0a8SJoe Perches		}
462077b8c0a8SJoe Perches
4621cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4622cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4623000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4624000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4625cb710ecaSJoe Perches				$herecurr);
4626cb710ecaSJoe Perches		}
4627cb710ecaSJoe Perches
4628ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4629ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4630ab7e23f3SJoe Perches			my $found = $1;
4631ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4632ab7e23f3SJoe Perches				WARN("CONST_CONST",
4633ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4634ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4635ab7e23f3SJoe Perches				WARN("CONST_CONST",
4636ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4637ab7e23f3SJoe Perches			}
4638ab7e23f3SJoe Perches		}
4639ab7e23f3SJoe Perches
464073169765SJoe Perches# check for const static or static <non ptr type> const declarations
464173169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
464273169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
464373169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
464473169765SJoe Perches			if (WARN("STATIC_CONST",
464573169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
464673169765SJoe Perches			    $fix) {
464773169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
464873169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
464973169765SJoe Perches			}
465073169765SJoe Perches		}
465173169765SJoe Perches
46529b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
46539b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
46549b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
46559b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
46569b0fa60dSJoe Perches				$herecurr);
46579b0fa60dSJoe Perches		}
46589b0fa60dSJoe Perches
4659b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4660b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4661b598b670SJoe Perches			my $array = $1;
4662b598b670SJoe 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*\))@) {
4663b598b670SJoe Perches				my $array_div = $1;
4664b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4665b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4666b598b670SJoe Perches				    $fix) {
4667b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4668b598b670SJoe Perches				}
4669b598b670SJoe Perches			}
4670b598b670SJoe Perches		}
4671b598b670SJoe Perches
4672b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
467316b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4674b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4675b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4676b36190c5SJoe Perches			    $fix) {
4677194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4678b36190c5SJoe Perches			}
4679b36190c5SJoe Perches		}
4680b36190c5SJoe Perches
4681653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4682653d4876SAndy Whitcroft# make sense.
4683653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
46848054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4685c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
46868ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
468746d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4688000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4689000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
46900a920b5bSAndy Whitcroft		}
46910a920b5bSAndy Whitcroft
46920a920b5bSAndy Whitcroft# * goes on variable not on type
469365863862SAndy Whitcroft		# (char*[ const])
4694bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4695bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
46963705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4697d8aaf121SAndy Whitcroft
469865863862SAndy Whitcroft			# Should start with a space.
469965863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
470065863862SAndy Whitcroft			# Should not end with a space.
470165863862SAndy Whitcroft			$to =~ s/\s+$//;
470265863862SAndy Whitcroft			# '*'s should not have spaces between.
4703f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
470465863862SAndy Whitcroft			}
4705d8aaf121SAndy Whitcroft
47063705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
470765863862SAndy Whitcroft			if ($from ne $to) {
47083705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
47093705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
47103705ce5bSJoe Perches				    $fix) {
47113705ce5bSJoe Perches					my $sub_from = $ident;
47123705ce5bSJoe Perches					my $sub_to = $ident;
47133705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4714194f66fcSJoe Perches					$fixed[$fixlinenr] =~
47153705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
47163705ce5bSJoe Perches				}
471765863862SAndy Whitcroft			}
4718bfcb2cc7SAndy Whitcroft		}
4719bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4720bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
47213705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4722d8aaf121SAndy Whitcroft
472365863862SAndy Whitcroft			# Should start with a space.
472465863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
472565863862SAndy Whitcroft			# Should not end with a space.
472665863862SAndy Whitcroft			$to =~ s/\s+$//;
472765863862SAndy Whitcroft			# '*'s should not have spaces between.
4728f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
472965863862SAndy Whitcroft			}
473065863862SAndy Whitcroft			# Modifiers should have spaces.
473165863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
473265863862SAndy Whitcroft
47333705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4734667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
47353705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
47363705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
47373705ce5bSJoe Perches				    $fix) {
47383705ce5bSJoe Perches
47393705ce5bSJoe Perches					my $sub_from = $match;
47403705ce5bSJoe Perches					my $sub_to = $match;
47413705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4742194f66fcSJoe Perches					$fixed[$fixlinenr] =~
47433705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
47443705ce5bSJoe Perches				}
474565863862SAndy Whitcroft			}
47460a920b5bSAndy Whitcroft		}
47470a920b5bSAndy Whitcroft
47489d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
47499d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
47500675a8fbSJean Delvare			my $msg_level = \&WARN;
47510675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
47520675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
47539d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
47549d3e3c70SJoe Perches		}
47550a920b5bSAndy Whitcroft
47569d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
47578905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4758000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4759000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
47608905a67cSAndy Whitcroft		}
47618905a67cSAndy Whitcroft
476217441227SJoe Perches# check for uses of printk_ratelimit
476317441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4764000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4765000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
476617441227SJoe Perches		}
476717441227SJoe Perches
4768eeef5733SJoe Perches# printk should use KERN_* levels
4769eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4770000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4771eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
477200df344fSAndy Whitcroft		}
47730a920b5bSAndy Whitcroft
4774f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4775f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4776f5eea3b0SJoe Perches			my $printk = $1;
4777f5eea3b0SJoe Perches			my $modifier = $2;
4778f5eea3b0SJoe Perches			my $orig = $3;
4779f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4780243f3803SJoe Perches			my $level = lc($orig);
4781243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
47828f26b837SJoe Perches			my $level2 = $level;
47838f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4784f5eea3b0SJoe Perches			$level .= $modifier;
4785f5eea3b0SJoe Perches			$level2 .= $modifier;
4786243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4787f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4788243f3803SJoe Perches		}
4789243f3803SJoe Perches
4790f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4791dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4792dc139313SJoe Perches			my $orig = $1;
4793dc139313SJoe Perches			my $level = lc($orig);
4794dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4795dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4796dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4797dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4798dc139313SJoe Perches		}
4799dc139313SJoe Perches
48008020b253SNicolas Boichat# trace_printk should not be used in production code.
48018020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
48028020b253SNicolas Boichat			WARN("TRACE_PRINTK",
48038020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
48048020b253SNicolas Boichat		}
48058020b253SNicolas Boichat
480691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
480791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
480891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
480991c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
481091c9afafSAndy Lutomirski			WARN("ENOSYS",
481191c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
481291c9afafSAndy Lutomirski		}
481391c9afafSAndy Lutomirski
48146b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
48156b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
48166b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
48176b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
48186b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
48196b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
48206b9ea5ffSJakub Kicinski			    $fix) {
48216b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
48226b9ea5ffSJakub Kicinski			}
48236b9ea5ffSJakub Kicinski		}
48246b9ea5ffSJakub Kicinski
4825653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4826653d4876SAndy Whitcroft# or if closed on same line
48275b57980dSJoe Perches		if ($perl_version_ok &&
48282d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
48292d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
48302d453e3bSJoe Perches		    $sline !~ /}/) {
48318d182478SJoe Perches			if (ERROR("OPEN_BRACE",
48322d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
48338d182478SJoe Perches			    $fix) {
48348d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
48358d182478SJoe Perches				my $fixed_line = $rawline;
483603f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
48378d182478SJoe Perches				my $line1 = $1;
48388d182478SJoe Perches				my $line2 = $2;
48398d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
48408d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
48418d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
48428d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
48438d182478SJoe Perches				}
48448d182478SJoe Perches			}
48450a920b5bSAndy Whitcroft		}
4846653d4876SAndy Whitcroft
48478905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
48488905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
48498905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
48508d182478SJoe Perches			if (ERROR("OPEN_BRACE",
48518d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
48528d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
48538d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
48548d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
48558d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
48568d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
48578d182478SJoe Perches				$fixedline = $rawline;
48588d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
48598d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
48608d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
48618d182478SJoe Perches				}
48628d182478SJoe Perches			}
48638905a67cSAndy Whitcroft		}
48648905a67cSAndy Whitcroft
48650c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
48663705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
48673705ce5bSJoe Perches			if (WARN("SPACING",
48683705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
48693705ce5bSJoe Perches			    $fix) {
4870194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48713705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
48723705ce5bSJoe Perches			}
48730c73b4ebSAndy Whitcroft		}
48740c73b4ebSAndy Whitcroft
487531070b5dSJoe Perches# Function pointer declarations
487631070b5dSJoe Perches# check spacing between type, funcptr, and args
487731070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
487891f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
487931070b5dSJoe Perches			my $declare = $1;
488031070b5dSJoe Perches			my $pre_pointer_space = $2;
488131070b5dSJoe Perches			my $post_pointer_space = $3;
488231070b5dSJoe Perches			my $funcname = $4;
488331070b5dSJoe Perches			my $post_funcname_space = $5;
488431070b5dSJoe Perches			my $pre_args_space = $6;
488531070b5dSJoe Perches
488691f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
488791f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
488891f72e9cSJoe Perches# don't need a space so don't warn for those.
488991f72e9cSJoe Perches			my $post_declare_space = "";
489091f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
489191f72e9cSJoe Perches				$post_declare_space = $1;
489291f72e9cSJoe Perches				$declare = rtrim($declare);
489391f72e9cSJoe Perches			}
489491f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
489531070b5dSJoe Perches				WARN("SPACING",
489631070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
489791f72e9cSJoe Perches				$post_declare_space = " ";
489831070b5dSJoe Perches			}
489931070b5dSJoe Perches
490031070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
490191f72e9cSJoe Perches# This test is not currently implemented because these declarations are
490291f72e9cSJoe Perches# equivalent to
490391f72e9cSJoe Perches#	int  foo(int bar, ...)
490491f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
490591f72e9cSJoe Perches#
490691f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
490791f72e9cSJoe Perches#				WARN("SPACING",
490891f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
490991f72e9cSJoe Perches#			}
491031070b5dSJoe Perches
491131070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
491231070b5dSJoe Perches			if (defined $pre_pointer_space &&
491331070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
491431070b5dSJoe Perches				WARN("SPACING",
491531070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
491631070b5dSJoe Perches			}
491731070b5dSJoe Perches
491831070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
491931070b5dSJoe Perches			if (defined $post_pointer_space &&
492031070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
492131070b5dSJoe Perches				WARN("SPACING",
492231070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
492331070b5dSJoe Perches			}
492431070b5dSJoe Perches
492531070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
492631070b5dSJoe Perches			if (defined $post_funcname_space &&
492731070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
492831070b5dSJoe Perches				WARN("SPACING",
492931070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
493031070b5dSJoe Perches			}
493131070b5dSJoe Perches
493231070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
493331070b5dSJoe Perches			if (defined $pre_args_space &&
493431070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
493531070b5dSJoe Perches				WARN("SPACING",
493631070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
493731070b5dSJoe Perches			}
493831070b5dSJoe Perches
493931070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4940194f66fcSJoe Perches				$fixed[$fixlinenr] =~
494191f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
494231070b5dSJoe Perches			}
494331070b5dSJoe Perches		}
494431070b5dSJoe Perches
49458d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
49468d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4947fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4948fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
49498d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
49508d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
49518d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4952fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
495338dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
49543705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
49553705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
49563705ce5bSJoe Perches				    $fix) {
4957194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
49583705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
49593705ce5bSJoe Perches				}
49608d31cfceSAndy Whitcroft			}
49618d31cfceSAndy Whitcroft		}
49628d31cfceSAndy Whitcroft
4963f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
49646c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4965c2fdda0dSAndy Whitcroft			my $name = $1;
4966773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4967773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4968c2fdda0dSAndy Whitcroft
4969c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4970773647a0SAndy Whitcroft			if ($name =~ /^(?:
4971773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4972773647a0SAndy Whitcroft				volatile|__volatile__|
4973773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4974773647a0SAndy Whitcroft				asm|__asm__)$/x)
4975773647a0SAndy Whitcroft			{
4976c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4977c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4978c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4979c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4980773647a0SAndy Whitcroft
4981773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4982c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4983c2fdda0dSAndy Whitcroft
4984c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4985c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4986773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4987c2fdda0dSAndy Whitcroft
4988c2fdda0dSAndy Whitcroft			} else {
49893705ce5bSJoe Perches				if (WARN("SPACING",
49903705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
49913705ce5bSJoe Perches					     $fix) {
4992194f66fcSJoe Perches					$fixed[$fixlinenr] =~
49933705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
49943705ce5bSJoe Perches				}
4995f0a594c1SAndy Whitcroft			}
49966c72ffaaSAndy Whitcroft		}
49979a4cad4eSEric Nelson
4998653d4876SAndy Whitcroft# Check operator spacing.
49990a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
50003705ce5bSJoe Perches			my $fixed_line = "";
50013705ce5bSJoe Perches			my $line_fixed = 0;
50023705ce5bSJoe Perches
50039c0ca6f9SAndy Whitcroft			my $ops = qr{
50049c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
50059c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
50069c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
50071f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
500884731623SJoe Perches				\?:|\?|:
50099c0ca6f9SAndy Whitcroft			}x;
5010cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
50113705ce5bSJoe Perches
50123705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
50133705ce5bSJoe Perches##			foreach my $el (@elements) {
50143705ce5bSJoe Perches##				print("el: <$el>\n");
50153705ce5bSJoe Perches##			}
50163705ce5bSJoe Perches
50173705ce5bSJoe Perches			my @fix_elements = ();
501800df344fSAndy Whitcroft			my $off = 0;
50196c72ffaaSAndy Whitcroft
50203705ce5bSJoe Perches			foreach my $el (@elements) {
50213705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
50223705ce5bSJoe Perches				$off += length($el);
50233705ce5bSJoe Perches			}
50243705ce5bSJoe Perches
50253705ce5bSJoe Perches			$off = 0;
50263705ce5bSJoe Perches
50276c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
5028b34c648bSJoe Perches			my $last_after = -1;
50296c72ffaaSAndy Whitcroft
50300a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
50313705ce5bSJoe Perches
50323705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
50333705ce5bSJoe Perches
50343705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
50353705ce5bSJoe Perches
50364a0df2efSAndy Whitcroft				$off += length($elements[$n]);
50374a0df2efSAndy Whitcroft
503825985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
5039773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
5040773647a0SAndy Whitcroft				my $cc = '';
5041773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
5042773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
5043773647a0SAndy Whitcroft				}
5044773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
5045773647a0SAndy Whitcroft
50464a0df2efSAndy Whitcroft				my $a = '';
50474a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
50484a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
5049cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
50504a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
50514a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
5052773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
50534a0df2efSAndy Whitcroft
50540a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
50554a0df2efSAndy Whitcroft
50564a0df2efSAndy Whitcroft				my $c = '';
50570a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
50584a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
50594a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
5060cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
50614a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
50624a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
50638b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
50644a0df2efSAndy Whitcroft				} else {
50654a0df2efSAndy Whitcroft					$c = 'E';
50660a920b5bSAndy Whitcroft				}
50670a920b5bSAndy Whitcroft
50684a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
50694a0df2efSAndy Whitcroft
50704a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
50714a0df2efSAndy Whitcroft
50726c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
5073de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
50740a920b5bSAndy Whitcroft
507574048ed8SAndy Whitcroft				# Pull out the value of this operator.
50766c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
50770a920b5bSAndy Whitcroft
50781f65f947SAndy Whitcroft				# Get the full operator variant.
50791f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
50801f65f947SAndy Whitcroft
508113214adfSAndy Whitcroft				# Ignore operators passed as parameters.
508213214adfSAndy Whitcroft				if ($op_type ne 'V' &&
5083d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
508413214adfSAndy Whitcroft
5085cf655043SAndy Whitcroft#				# Ignore comments
5086cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
508713214adfSAndy Whitcroft
5088d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
508913214adfSAndy Whitcroft				} elsif ($op eq ';') {
5090cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
5091cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
50923705ce5bSJoe Perches						if (ERROR("SPACING",
50933705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
5094b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
50953705ce5bSJoe Perches							$line_fixed = 1;
50963705ce5bSJoe Perches						}
5097d8aaf121SAndy Whitcroft					}
5098d8aaf121SAndy Whitcroft
5099d8aaf121SAndy Whitcroft				# // is a comment
5100d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
51010a920b5bSAndy Whitcroft
5102b00e4814SJoe Perches				#   :   when part of a bitfield
5103b00e4814SJoe Perches				} elsif ($opv eq ':B') {
5104b00e4814SJoe Perches					# skip the bitfield test for now
5105b00e4814SJoe Perches
51061f65f947SAndy Whitcroft				# No spaces for:
51071f65f947SAndy Whitcroft				#   ->
5108b00e4814SJoe Perches				} elsif ($op eq '->') {
51094a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
51103705ce5bSJoe Perches						if (ERROR("SPACING",
51113705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5112b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51133705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51143705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
51153705ce5bSJoe Perches							}
5116b34c648bSJoe Perches							$line_fixed = 1;
51173705ce5bSJoe Perches						}
51180a920b5bSAndy Whitcroft					}
51190a920b5bSAndy Whitcroft
51202381097bSJoe Perches				# , must not have a space before and must have a space on the right.
51210a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
51222381097bSJoe Perches					my $rtrim_before = 0;
51232381097bSJoe Perches					my $space_after = 0;
51242381097bSJoe Perches					if ($ctx =~ /Wx./) {
51252381097bSJoe Perches						if (ERROR("SPACING",
51262381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
51272381097bSJoe Perches							$line_fixed = 1;
51282381097bSJoe Perches							$rtrim_before = 1;
51292381097bSJoe Perches						}
51302381097bSJoe Perches					}
5131cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
51323705ce5bSJoe Perches						if (ERROR("SPACING",
51333705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
51343705ce5bSJoe Perches							$line_fixed = 1;
5135b34c648bSJoe Perches							$last_after = $n;
51362381097bSJoe Perches							$space_after = 1;
51372381097bSJoe Perches						}
51382381097bSJoe Perches					}
51392381097bSJoe Perches					if ($rtrim_before || $space_after) {
51402381097bSJoe Perches						if ($rtrim_before) {
51412381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51422381097bSJoe Perches						} else {
51432381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
51442381097bSJoe Perches						}
51452381097bSJoe Perches						if ($space_after) {
51462381097bSJoe Perches							$good .= " ";
51473705ce5bSJoe Perches						}
51480a920b5bSAndy Whitcroft					}
51490a920b5bSAndy Whitcroft
51509c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
515174048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
51529c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
51539c0ca6f9SAndy Whitcroft
51549c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
51559c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
51569c0ca6f9SAndy Whitcroft				# unary operator, or a cast
51579c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
515874048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
51590d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
5160cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
51613705ce5bSJoe Perches						if (ERROR("SPACING",
51623705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
5163b34c648bSJoe Perches							if ($n != $last_after + 2) {
5164b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
51653705ce5bSJoe Perches								$line_fixed = 1;
51663705ce5bSJoe Perches							}
51670a920b5bSAndy Whitcroft						}
5168b34c648bSJoe Perches					}
5169a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
5170171ae1a4SAndy Whitcroft						# A unary '*' may be const
5171171ae1a4SAndy Whitcroft
5172171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
51733705ce5bSJoe Perches						if (ERROR("SPACING",
51743705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5175b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
51763705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51773705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
51783705ce5bSJoe Perches							}
5179b34c648bSJoe Perches							$line_fixed = 1;
51803705ce5bSJoe Perches						}
51810a920b5bSAndy Whitcroft					}
51820a920b5bSAndy Whitcroft
51830a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
51840a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
5185773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
51863705ce5bSJoe Perches						if (ERROR("SPACING",
51873705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
5188b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
51893705ce5bSJoe Perches							$line_fixed = 1;
51903705ce5bSJoe Perches						}
51910a920b5bSAndy Whitcroft					}
5192773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
5193773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
51943705ce5bSJoe Perches						if (ERROR("SPACING",
51953705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5196b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51973705ce5bSJoe Perches							$line_fixed = 1;
51983705ce5bSJoe Perches						}
5199653d4876SAndy Whitcroft					}
5200773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
52013705ce5bSJoe Perches						if (ERROR("SPACING",
52023705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5203b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
52043705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
52053705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5206773647a0SAndy Whitcroft							}
5207b34c648bSJoe Perches							$line_fixed = 1;
52083705ce5bSJoe Perches						}
52093705ce5bSJoe Perches					}
52100a920b5bSAndy Whitcroft
52110a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
52129c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
52139c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
52149c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5215c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5216c2fdda0dSAndy Whitcroft					 $op eq '%')
52170a920b5bSAndy Whitcroft				{
5218d2e025f3SJoe Perches					if ($check) {
5219d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5220d2e025f3SJoe Perches							if (CHK("SPACING",
5221d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5222d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5223d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5224d2e025f3SJoe Perches								$line_fixed = 1;
5225d2e025f3SJoe Perches							}
5226d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5227d2e025f3SJoe Perches							if (CHK("SPACING",
5228d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5229d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5230d2e025f3SJoe Perches								$line_fixed = 1;
5231d2e025f3SJoe Perches							}
5232d2e025f3SJoe Perches						}
5233d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
52343705ce5bSJoe Perches						if (ERROR("SPACING",
52353705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5236b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5237b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5238b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5239b34c648bSJoe Perches							}
52403705ce5bSJoe Perches							$line_fixed = 1;
52413705ce5bSJoe Perches						}
52420a920b5bSAndy Whitcroft					}
52430a920b5bSAndy Whitcroft
52441f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
52451f65f947SAndy Whitcroft				# terminating a case value or a label.
52461f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
5247263afd39SChris Down					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
52483705ce5bSJoe Perches						if (ERROR("SPACING",
52493705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5250b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
52513705ce5bSJoe Perches							$line_fixed = 1;
52523705ce5bSJoe Perches						}
52531f65f947SAndy Whitcroft					}
52541f65f947SAndy Whitcroft
52550a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5256cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
52571f65f947SAndy Whitcroft					my $ok = 0;
52581f65f947SAndy Whitcroft
525922f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
52601f65f947SAndy Whitcroft					if (($op eq '<' &&
52611f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
52621f65f947SAndy Whitcroft					    ($op eq '>' &&
52631f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
52641f65f947SAndy Whitcroft					{
52651f65f947SAndy Whitcroft						$ok = 1;
52661f65f947SAndy Whitcroft					}
52671f65f947SAndy Whitcroft
5268e0df7e1fSJoe Perches					# for asm volatile statements
5269e0df7e1fSJoe Perches					# ignore a colon with another
5270e0df7e1fSJoe Perches					# colon immediately before or after
5271e0df7e1fSJoe Perches					if (($op eq ':') &&
5272e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5273e0df7e1fSJoe Perches						$ok = 1;
5274e0df7e1fSJoe Perches					}
5275e0df7e1fSJoe Perches
527684731623SJoe Perches					# messages are ERROR, but ?: are CHK
52771f65f947SAndy Whitcroft					if ($ok == 0) {
52780675a8fbSJean Delvare						my $msg_level = \&ERROR;
52790675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
528084731623SJoe Perches
52810675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
52823705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5283b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5284b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5285b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5286b34c648bSJoe Perches							}
52873705ce5bSJoe Perches							$line_fixed = 1;
52883705ce5bSJoe Perches						}
52890a920b5bSAndy Whitcroft					}
529022f2a2efSAndy Whitcroft				}
52914a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
52923705ce5bSJoe Perches
52933705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
52943705ce5bSJoe Perches
52953705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
52960a920b5bSAndy Whitcroft			}
52973705ce5bSJoe Perches
52983705ce5bSJoe Perches			if (($#elements % 2) == 0) {
52993705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
53003705ce5bSJoe Perches			}
53013705ce5bSJoe Perches
5302194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5303194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
53043705ce5bSJoe Perches			}
53053705ce5bSJoe Perches
53063705ce5bSJoe Perches
53070a920b5bSAndy Whitcroft		}
53080a920b5bSAndy Whitcroft
5309786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5310d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5311786b6326SJoe Perches			if (WARN("SPACING",
5312786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5313786b6326SJoe Perches			    $fix) {
5314194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5315786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5316786b6326SJoe Perches			}
5317786b6326SJoe Perches		}
5318786b6326SJoe Perches
5319f0a594c1SAndy Whitcroft# check for multiple assignments
5320f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5321000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5322000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5323f0a594c1SAndy Whitcroft		}
5324f0a594c1SAndy Whitcroft
532522f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
532622f2a2efSAndy Whitcroft## # continuation.
532722f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
532822f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
532922f2a2efSAndy Whitcroft##
533022f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5331e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
533222f2a2efSAndy Whitcroft## 			my $ln = $line;
533322f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
533422f2a2efSAndy Whitcroft## 			}
533522f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5336000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5337000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
533822f2a2efSAndy Whitcroft## 			}
533922f2a2efSAndy Whitcroft## 		}
5340f0a594c1SAndy Whitcroft
53410a920b5bSAndy Whitcroft#need space before brace following if, while, etc
53426b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
53436ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
53443705ce5bSJoe Perches			if (ERROR("SPACING",
53453705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
53463705ce5bSJoe Perches			    $fix) {
53476ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
53483705ce5bSJoe Perches			}
5349de7d4f0eSAndy Whitcroft		}
5350de7d4f0eSAndy Whitcroft
5351c4a62ef9SJoe Perches## # check for blank lines before declarations
5352c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5353c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5354c4a62ef9SJoe Perches##			WARN("SPACING",
5355c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5356c4a62ef9SJoe Perches##		}
5357c4a62ef9SJoe Perches##
5358c4a62ef9SJoe Perches
5359de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5360de7d4f0eSAndy Whitcroft# on the line
536194fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5362d5e616fcSJoe Perches			if (ERROR("SPACING",
5363d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5364d5e616fcSJoe Perches			    $fix) {
5365194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5366d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5367d5e616fcSJoe Perches			}
53680a920b5bSAndy Whitcroft		}
53690a920b5bSAndy Whitcroft
537022f2a2efSAndy Whitcroft# check spacing on square brackets
537122f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
53723705ce5bSJoe Perches			if (ERROR("SPACING",
53733705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
53743705ce5bSJoe Perches			    $fix) {
5375194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53763705ce5bSJoe Perches				    s/\[\s+/\[/;
53773705ce5bSJoe Perches			}
537822f2a2efSAndy Whitcroft		}
537922f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
53803705ce5bSJoe Perches			if (ERROR("SPACING",
53813705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
53823705ce5bSJoe Perches			    $fix) {
5383194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53843705ce5bSJoe Perches				    s/\s+\]/\]/;
53853705ce5bSJoe Perches			}
538622f2a2efSAndy Whitcroft		}
538722f2a2efSAndy Whitcroft
5388c45dcabdSAndy Whitcroft# check spacing on parentheses
53899c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
53909c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
53913705ce5bSJoe Perches			if (ERROR("SPACING",
53923705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
53933705ce5bSJoe Perches			    $fix) {
5394194f66fcSJoe Perches				$fixed[$fixlinenr] =~
53953705ce5bSJoe Perches				    s/\(\s+/\(/;
53963705ce5bSJoe Perches			}
539722f2a2efSAndy Whitcroft		}
539813214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5399c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5400c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
54013705ce5bSJoe Perches			if (ERROR("SPACING",
54023705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
54033705ce5bSJoe Perches			    $fix) {
5404194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54053705ce5bSJoe Perches				    s/\s+\)/\)/;
54063705ce5bSJoe Perches			}
540722f2a2efSAndy Whitcroft		}
540822f2a2efSAndy Whitcroft
5409e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5410e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5411e2826fd0SJoe Perches
5412e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5413ea4acbb1SJoe Perches			my $var = $1;
5414ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5415ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5416ea4acbb1SJoe Perches			    $fix) {
5417ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5418ea4acbb1SJoe Perches			}
5419ea4acbb1SJoe Perches		}
5420ea4acbb1SJoe Perches
5421ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5422ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5423ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5424ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5425ea4acbb1SJoe Perches			my $var = $2;
5426ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5427ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5428ea4acbb1SJoe Perches			    $fix) {
5429ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5430ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5431ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5432ea4acbb1SJoe Perches			}
5433e2826fd0SJoe Perches		}
5434e2826fd0SJoe Perches
543563b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5436a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5437a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
54385b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
543963b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
544063b7c73eSJoe Perches			my $if_stat = $1;
544163b7c73eSJoe Perches			my $test = substr($2, 1, -1);
544263b7c73eSJoe Perches			my $herectx;
544363b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
544463b7c73eSJoe Perches				my $match = $1;
544563b7c73eSJoe Perches				# avoid parentheses around potential macro args
544663b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
544763b7c73eSJoe Perches				if (!defined($herectx)) {
544863b7c73eSJoe Perches					$herectx = $here . "\n";
544963b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
545063b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
545163b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
545263b7c73eSJoe Perches						$herectx .=  $rl . "\n";
545363b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
545463b7c73eSJoe Perches					}
545563b7c73eSJoe Perches				}
545663b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
545763b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
545863b7c73eSJoe Perches			}
545963b7c73eSJoe Perches		}
546063b7c73eSJoe Perches
546169078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation)
546269078651SJoe Perches# and ignore bitfield definitions like foo:1
546369078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the :
546469078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels
546569078651SJoe Perches		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
546669078651SJoe Perches		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
546769078651SJoe Perches		    $sline !~ /^.\s+default:/) {
54683705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
54693705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
54703705ce5bSJoe Perches			    $fix) {
5471194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54723705ce5bSJoe Perches				    s/^(.)\s+/$1/;
54733705ce5bSJoe Perches			}
54740a920b5bSAndy Whitcroft		}
54750a920b5bSAndy Whitcroft
547640873abaSJoe Perches# check if a statement with a comma should be two statements like:
547740873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
547840873abaSJoe Perches#	bar = baz();
547940873abaSJoe Perches		if (defined($stat) &&
548040873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
548140873abaSJoe Perches			my $cnt = statement_rawlines($stat);
548240873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
548340873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
548440873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
548540873abaSJoe Perches		}
548640873abaSJoe Perches
54875b9553abSJoe Perches# return is not a function
5488507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5489c45dcabdSAndy Whitcroft			my $spacing = $1;
54905b57980dSJoe Perches			if ($perl_version_ok &&
54915b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
54925b9553abSJoe Perches				my $value = $1;
54935b9553abSJoe Perches				$value = deparenthesize($value);
54945b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5495000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5496000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
54975b9553abSJoe Perches				}
5498c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5499000d1cc1SJoe Perches				ERROR("SPACING",
5500000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5501c45dcabdSAndy Whitcroft			}
5502c45dcabdSAndy Whitcroft		}
5503507e5141SJoe Perches
5504b43ae21bSJoe Perches# unnecessary return in a void function
5505b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5506b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5507b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5508b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5509b43ae21bSJoe Perches		    $linenr >= 3 &&
5510b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5511b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
55129819cf25SJoe Perches			WARN("RETURN_VOID",
5513b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
55149819cf25SJoe Perches		}
55159819cf25SJoe Perches
5516189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
55175b57980dSJoe Perches		if ($perl_version_ok &&
5518189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5519189248d8SJoe Perches			my $openparens = $1;
5520189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5521189248d8SJoe Perches			my $msg = "";
5522189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5523189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5524189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5525189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5526189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5527189248d8SJoe Perches			}
5528189248d8SJoe Perches		}
5529189248d8SJoe Perches
5530c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5531c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5532c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5533c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
55345b57980dSJoe Perches		if ($perl_version_ok &&
5535c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5536c5595fa2SJoe Perches			my $lead = $1;
5537c5595fa2SJoe Perches			my $const = $2;
5538c5595fa2SJoe Perches			my $comp = $3;
5539c5595fa2SJoe Perches			my $to = $4;
5540c5595fa2SJoe Perches			my $newcomp = $comp;
5541f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5542c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5543c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5544c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5545c5595fa2SJoe Perches			    $fix) {
5546c5595fa2SJoe Perches				if ($comp eq "<") {
5547c5595fa2SJoe Perches					$newcomp = ">";
5548c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5549c5595fa2SJoe Perches					$newcomp = ">=";
5550c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5551c5595fa2SJoe Perches					$newcomp = "<";
5552c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5553c5595fa2SJoe Perches					$newcomp = "<=";
5554c5595fa2SJoe Perches				}
5555c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5556c5595fa2SJoe Perches			}
5557c5595fa2SJoe Perches		}
5558c5595fa2SJoe Perches
5559f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5560f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
556153a3c448SAndy Whitcroft			my $name = $1;
556246b85bf9SGuenter Roeck			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5563000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5564f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
556553a3c448SAndy Whitcroft			}
556653a3c448SAndy Whitcroft		}
5567c45dcabdSAndy Whitcroft
55680a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
55694a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
55703705ce5bSJoe Perches			if (ERROR("SPACING",
55713705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
55723705ce5bSJoe Perches			    $fix) {
5573194f66fcSJoe Perches				$fixed[$fixlinenr] =~
55743705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
55753705ce5bSJoe Perches			}
55760a920b5bSAndy Whitcroft		}
55770a920b5bSAndy Whitcroft
5578f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5579f5fe35ddSAndy Whitcroft# statements after the conditional.
5580170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
55813e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
55823e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
55833e469cdcSAndy Whitcroft					if (!defined $stat);
5584170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5585170d3a22SAndy Whitcroft						$remain_next, $off_next);
5586170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5587170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5588170d3a22SAndy Whitcroft
5589170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5590170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5591170d3a22SAndy Whitcroft				# then count those as offsets.
5592170d3a22SAndy Whitcroft				my ($whitespace) =
5593170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5594170d3a22SAndy Whitcroft				my $offset =
5595170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5596170d3a22SAndy Whitcroft
5597170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5598170d3a22SAndy Whitcroft								$offset} = 1;
5599170d3a22SAndy Whitcroft			}
5600170d3a22SAndy Whitcroft		}
5601170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5602c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5603170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5604171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
5605481efd7bSJoe Perches			my $fixed_assign_in_if = 0;
56068905a67cSAndy Whitcroft
5607b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
560865b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
560965b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
561065b64b3bSJoe Perches				    $fix && $perl_version_ok) {
561165b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
561265b64b3bSJoe Perches						my $space = $1;
561365b64b3bSJoe Perches						my $not = $2;
561465b64b3bSJoe Perches						my $statement = $3;
561565b64b3bSJoe Perches						my $assigned = $4;
561665b64b3bSJoe Perches						my $test = $8;
561765b64b3bSJoe Perches						my $against = $9;
561865b64b3bSJoe Perches						my $brace = $15;
561965b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
562065b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
562165b64b3bSJoe Perches						my $newline = "${space}if (";
562265b64b3bSJoe Perches						$newline .= '!' if defined($not);
562365b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
562465b64b3bSJoe Perches						$newline .= "$assigned";
562565b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
562665b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
562765b64b3bSJoe Perches						$newline .= ')';
562865b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
562965b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
5630481efd7bSJoe Perches						$fixed_assign_in_if = 1;
563165b64b3bSJoe Perches					}
563265b64b3bSJoe Perches				}
56338905a67cSAndy Whitcroft			}
56348905a67cSAndy Whitcroft
56358905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
56368905a67cSAndy Whitcroft			# conditional.
5637773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
56388905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
563913214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
564053210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
564153210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5642773647a0SAndy Whitcroft			{
5643bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5644bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5645bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
564642bdf74cSHidetoshi Seto				my $stat_real = '';
5647bb44ad39SAndy Whitcroft
564842bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
564942bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5650bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5651bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5652bb44ad39SAndy Whitcroft				}
5653bb44ad39SAndy Whitcroft
5654481efd7bSJoe Perches				if (ERROR("TRAILING_STATEMENTS",
5655481efd7bSJoe Perches					  "trailing statements should be on next line\n" . $herecurr . $stat_real) &&
5656481efd7bSJoe Perches				    !$fixed_assign_in_if &&
5657481efd7bSJoe Perches				    $cond_lines == 0 &&
5658481efd7bSJoe Perches				    $fix && $perl_version_ok &&
5659481efd7bSJoe Perches				    $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) {
5660481efd7bSJoe Perches					my $indent = $1;
5661481efd7bSJoe Perches					my $test = $2;
5662481efd7bSJoe Perches					my $rest = rtrim($4);
5663481efd7bSJoe Perches					if ($rest =~ /;$/) {
5664481efd7bSJoe Perches						$fixed[$fixlinenr] = "\+$indent$test";
5665481efd7bSJoe Perches						fix_insert_line($fixlinenr + 1, "$indent\t$rest");
5666481efd7bSJoe Perches					}
5667481efd7bSJoe Perches				}
56688905a67cSAndy Whitcroft			}
56698905a67cSAndy Whitcroft		}
56708905a67cSAndy Whitcroft
567113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
567213214adfSAndy Whitcroft		if ($line =~ /
567313214adfSAndy Whitcroft			(?:
567413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
567513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
567613214adfSAndy Whitcroft				(?:\&\&|\|\|)
567713214adfSAndy Whitcroft			|
567813214adfSAndy Whitcroft				(?:\&\&|\|\|)
567913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
568013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
568113214adfSAndy Whitcroft			)/x)
568213214adfSAndy Whitcroft		{
5683000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5684000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
568513214adfSAndy Whitcroft		}
568613214adfSAndy Whitcroft
56878905a67cSAndy Whitcroft# if and else should not have general statements after it
568813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
568913214adfSAndy Whitcroft			my $s = $1;
569013214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
569113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5692000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5693000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
56940a920b5bSAndy Whitcroft			}
569513214adfSAndy Whitcroft		}
569639667782SAndy Whitcroft# if should not continue a brace
569739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5698000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5699048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
570039667782SAndy Whitcroft				$herecurr);
570139667782SAndy Whitcroft		}
5702a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5703a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5704a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
57053fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5706a1080bf8SAndy Whitcroft			\s*return\s+
5707a1080bf8SAndy Whitcroft		    )/xg)
5708a1080bf8SAndy Whitcroft		{
5709000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5710000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5711a1080bf8SAndy Whitcroft		}
57120a920b5bSAndy Whitcroft
57130a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
57140a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
57158b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
57160a920b5bSAndy Whitcroft		    $previndent == $indent) {
57178b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
57188b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
57198b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
57208b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
57218b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
57228b8856f4SJoe Perches				my $fixedline = $prevrawline;
57238b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
57248b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
57258b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
57268b8856f4SJoe Perches				}
57278b8856f4SJoe Perches				$fixedline = $rawline;
57288b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
57298b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
57308b8856f4SJoe Perches			}
57310a920b5bSAndy Whitcroft		}
57320a920b5bSAndy Whitcroft
57338b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5734c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5735c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5736c2fdda0dSAndy Whitcroft
5737c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5738c2fdda0dSAndy Whitcroft			# conditional.
5739773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5740c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5741c2fdda0dSAndy Whitcroft
5742c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
57438b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
57448b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
57458b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
57468b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
57478b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
57488b8856f4SJoe Perches					my $fixedline = $prevrawline;
57498b8856f4SJoe Perches					my $trailing = $rawline;
57508b8856f4SJoe Perches					$trailing =~ s/^\+//;
57518b8856f4SJoe Perches					$trailing = trim($trailing);
57528b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
57538b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
57548b8856f4SJoe Perches				}
5755c2fdda0dSAndy Whitcroft			}
5756c2fdda0dSAndy Whitcroft		}
5757c2fdda0dSAndy Whitcroft
575895e2c602SJoe Perches#Specific variable tests
5759323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5760323c1260SJoe Perches			my $var = $1;
576195e2c602SJoe Perches
576295e2c602SJoe Perches#CamelCase
5763807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5764be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
57654104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
57664104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
576722735ce8SJoe Perches#Ignore Page<foo> variants
5768807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5769d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5770d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5771d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5772f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5773f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
5774f858e23aSAntonio Borneo				while ($var =~ m{\b($Ident)}g) {
57757e781f67SJoe Perches					my $word = $1;
57767e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5777d8b07710SJoe Perches					if ($check) {
5778d8b07710SJoe Perches						seed_camelcase_includes();
5779d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5780d8b07710SJoe Perches							seed_camelcase_file($realfile);
5781d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5782d8b07710SJoe Perches						}
5783d8b07710SJoe Perches					}
57847e781f67SJoe Perches					if (!defined $camelcase{$word}) {
57857e781f67SJoe Perches						$camelcase{$word} = 1;
5786be79794bSJoe Perches						CHK("CAMELCASE",
57877e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
57887e781f67SJoe Perches					}
5789323c1260SJoe Perches				}
5790323c1260SJoe Perches			}
57913445686aSJoe Perches		}
57920a920b5bSAndy Whitcroft
57930a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5794d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5795d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5796d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5797d5e616fcSJoe Perches			    $fix) {
5798194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5799d5e616fcSJoe Perches			}
58000a920b5bSAndy Whitcroft		}
58010a920b5bSAndy Whitcroft
58020e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
58030e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5804c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5805e09dec48SAndy Whitcroft			my $file = "$1.h";
5806e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5807e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5808e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
58097840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5810c45dcabdSAndy Whitcroft			{
58110e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
58120e212e0aSFabian Frederick				if ($asminclude > 0) {
5813e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5814000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5815000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5816e09dec48SAndy Whitcroft					} else {
5817000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5818000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5819e09dec48SAndy Whitcroft					}
58200a920b5bSAndy Whitcroft				}
58210a920b5bSAndy Whitcroft			}
58220e212e0aSFabian Frederick		}
58230a920b5bSAndy Whitcroft
5824653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5825653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5826cf655043SAndy Whitcroft# in a known good container
5827b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5828b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5829d8aaf121SAndy Whitcroft			my $ln = $linenr;
5830d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5831c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5832c45dcabdSAndy Whitcroft			my $ctx = '';
583308a2843eSJoe Perches			my $has_flow_statement = 0;
583408a2843eSJoe Perches			my $has_arg_concat = 0;
5835c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5836f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5837f74bd194SAndy Whitcroft			$ctx = $dstat;
5838c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5839a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5840c45dcabdSAndy Whitcroft
584108a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
584262e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
584308a2843eSJoe Perches
5844f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5845f59b64bfSJoe Perches			my $define_args = $1;
5846f59b64bfSJoe Perches			my $define_stmt = $dstat;
5847f59b64bfSJoe Perches			my @def_args = ();
5848f59b64bfSJoe Perches
5849f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5850f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5851f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
58528c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5853f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5854f59b64bfSJoe Perches			}
5855f59b64bfSJoe Perches
5856292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5857c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5858c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5859c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5860c45dcabdSAndy Whitcroft
5861c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
58622e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
58632e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
58642e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5865bf30d6edSAndy Whitcroft			{
5866c45dcabdSAndy Whitcroft			}
5867c45dcabdSAndy Whitcroft
5868342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
586933acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
587033acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5871e45bab8eSAndy Whitcroft			{
5872e45bab8eSAndy Whitcroft			}
5873e45bab8eSAndy Whitcroft
587442e15293SJoe Perches			# Make asm volatile uses seem like a generic function
587542e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
587642e15293SJoe Perches
5877c45dcabdSAndy Whitcroft			my $exceptions = qr{
5878c45dcabdSAndy Whitcroft				$Declare|
5879c45dcabdSAndy Whitcroft				module_param_named|
5880a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5881c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5882c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5883383099fdSAndy Whitcroft				__typeof__\(|
588422fd2d3eSStefani Seibold				union|
588522fd2d3eSStefani Seibold				struct|
5886ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
58876b10df42SVladimir Zapolskiy				^\"|\"$|
58886b10df42SVladimir Zapolskiy				^\[
5889c45dcabdSAndy Whitcroft			}x;
58905eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5891f59b64bfSJoe Perches
5892f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5893f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5894e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5895f59b64bfSJoe Perches
5896f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5897f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5898f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
58993cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5900356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5901f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5902f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5903e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
590472f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
59052e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5906f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5907f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5908f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
59094e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5910f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5911c45dcabdSAndy Whitcroft			{
5912e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5913e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5914e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5915e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5916f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5917f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5918f74bd194SAndy Whitcroft				} else {
5919000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5920388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5921d8aaf121SAndy Whitcroft				}
5922f59b64bfSJoe Perches
5923f59b64bfSJoe Perches			}
59245207649bSJoe Perches
59255207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
59265207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
59275207649bSJoe Perches			my $first = 1;
59285207649bSJoe Perches			$define_stmt = "";
59295207649bSJoe Perches			foreach my $l (@stmt_array) {
59305207649bSJoe Perches				$l =~ s/\\$//;
59315207649bSJoe Perches				if ($first) {
59325207649bSJoe Perches					$define_stmt = $l;
59335207649bSJoe Perches					$first = 0;
59345207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
59355207649bSJoe Perches					$define_stmt .= substr($l, 1);
59365207649bSJoe Perches				}
59375207649bSJoe Perches			}
59385207649bSJoe Perches			$define_stmt =~ s/$;//g;
59395207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
59405207649bSJoe Perches			$define_stmt = trim($define_stmt);
59415207649bSJoe Perches
5942f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5943f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5944f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
59459192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
59467fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
59477b844345SVincent Mailhol				$tmp_stmt =~ s/\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
59487fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
59497fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5950d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5951f59b64bfSJoe Perches				if ($use_cnt > 1) {
5952f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5953f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5954f59b64bfSJoe Perches				    }
59559192d41aSJoe Perches# check if any macro arguments may have other precedence issues
59567fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
59579192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
59589192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
59599192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
59609192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
59619192d41aSJoe Perches				}
59620a920b5bSAndy Whitcroft			}
59635023d347SJoe Perches
596408a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
596508a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
596608a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
596708a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5968e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
596908a2843eSJoe Perches
597008a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
597108a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
597208a2843eSJoe Perches			}
597308a2843eSJoe Perches
5974481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
59755023d347SJoe Perches
59765023d347SJoe Perches		} else {
59775023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5978481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5979481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
59805023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
59815023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
59825023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
59835023d347SJoe Perches			}
5984653d4876SAndy Whitcroft		}
59850a920b5bSAndy Whitcroft
5986b13edf7fSJoe Perches# do {} while (0) macro tests:
5987b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5988b13edf7fSJoe Perches# macro should not end with a semicolon
59895b57980dSJoe Perches		if ($perl_version_ok &&
5990b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5991b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5992b13edf7fSJoe Perches			my $ln = $linenr;
5993b13edf7fSJoe Perches			my $cnt = $realcnt;
5994b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5995b13edf7fSJoe Perches			my $ctx = '';
5996b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5997b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5998b13edf7fSJoe Perches			$ctx = $dstat;
5999b13edf7fSJoe Perches
6000b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
60011b36b201SJoe Perches			$dstat =~ s/$;/ /g;
6002b13edf7fSJoe Perches
6003b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
6004b13edf7fSJoe Perches				my $stmts = $2;
6005b13edf7fSJoe Perches				my $semis = $3;
6006b13edf7fSJoe Perches
6007b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
6008b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
6009e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6010b13edf7fSJoe Perches
6011ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
6012ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
6013b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
6014b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
6015b13edf7fSJoe Perches				}
6016b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
6017b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
6018b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
6019b13edf7fSJoe Perches				}
6020f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
6021f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
6022f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
6023e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6024f5ef95b1SJoe Perches
6025f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
6026f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
6027b13edf7fSJoe Perches			}
6028b13edf7fSJoe Perches		}
6029b13edf7fSJoe Perches
6030f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
603113214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
603213214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
6033cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
603413214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
6035cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
6036cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
6037aad4f614SJoe Perches				my @allowed = ();
6038aad4f614SJoe Perches				my $allow = 0;
603913214adfSAndy Whitcroft				my $seen = 0;
6040773647a0SAndy Whitcroft				my $herectx = $here . "\n";
6041cf655043SAndy Whitcroft				my $ln = $linenr - 1;
604213214adfSAndy Whitcroft				for my $chunk (@chunks) {
604313214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
604413214adfSAndy Whitcroft
6045773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
6046773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
6047773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
6048773647a0SAndy Whitcroft
6049aad4f614SJoe Perches					$allowed[$allow] = 0;
6050773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
6051773647a0SAndy Whitcroft
6052773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
6053773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
6054773647a0SAndy Whitcroft
6055773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
6056cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
6057cf655043SAndy Whitcroft
6058773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
605913214adfSAndy Whitcroft
606013214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
606113214adfSAndy Whitcroft
6062aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
6063cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
6064cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
6065aad4f614SJoe Perches						$allowed[$allow] = 1;
606613214adfSAndy Whitcroft					}
606713214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
6068cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
6069aad4f614SJoe Perches						$allowed[$allow] = 1;
607013214adfSAndy Whitcroft					}
6071cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
6072cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
6073aad4f614SJoe Perches						$allowed[$allow] = 1;
607413214adfSAndy Whitcroft					}
6075aad4f614SJoe Perches					$allow++;
607613214adfSAndy Whitcroft				}
6077aad4f614SJoe Perches				if ($seen) {
6078aad4f614SJoe Perches					my $sum_allowed = 0;
6079aad4f614SJoe Perches					foreach (@allowed) {
6080aad4f614SJoe Perches						$sum_allowed += $_;
6081aad4f614SJoe Perches					}
6082aad4f614SJoe Perches					if ($sum_allowed == 0) {
6083000d1cc1SJoe Perches						WARN("BRACES",
6084000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
6085aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
6086aad4f614SJoe Perches						 $seen != $allow) {
6087aad4f614SJoe Perches						CHK("BRACES",
6088aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
6089aad4f614SJoe Perches					}
609013214adfSAndy Whitcroft				}
609113214adfSAndy Whitcroft			}
609213214adfSAndy Whitcroft		}
6093773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
609413214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
6095cf655043SAndy Whitcroft			my $allowed = 0;
6096f0a594c1SAndy Whitcroft
6097cf655043SAndy Whitcroft			# Check the pre-context.
6098cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6099cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
6100cf655043SAndy Whitcroft				$allowed = 1;
6101f0a594c1SAndy Whitcroft			}
6102773647a0SAndy Whitcroft
6103773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
6104773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
6105773647a0SAndy Whitcroft
6106cf655043SAndy Whitcroft			# Check the condition.
6107cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
6108773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
6109cf655043SAndy Whitcroft			if (defined $cond) {
6110773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
6111cf655043SAndy Whitcroft			}
6112cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
6113cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
6114cf655043SAndy Whitcroft				$allowed = 1;
6115cf655043SAndy Whitcroft			}
6116cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
6117cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
6118cf655043SAndy Whitcroft				$allowed = 1;
6119cf655043SAndy Whitcroft			}
6120cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
6121cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
6122cf655043SAndy Whitcroft				$allowed = 1;
6123cf655043SAndy Whitcroft			}
6124cf655043SAndy Whitcroft			# Check the post-context.
6125cf655043SAndy Whitcroft			if (defined $chunks[1]) {
6126cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
6127cf655043SAndy Whitcroft				if (defined $cond) {
6128773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
6129cf655043SAndy Whitcroft				}
6130cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
6131cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6132cf655043SAndy Whitcroft					$allowed = 1;
6133cf655043SAndy Whitcroft				}
6134cf655043SAndy Whitcroft			}
6135cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6136f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
6137e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6138cf655043SAndy Whitcroft
6139000d1cc1SJoe Perches				WARN("BRACES",
6140000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6141f0a594c1SAndy Whitcroft			}
6142f0a594c1SAndy Whitcroft		}
6143f0a594c1SAndy Whitcroft
6144e4c5babdSJoe Perches# check for single line unbalanced braces
614595330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
614695330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
6147e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6148e4c5babdSJoe Perches		}
6149e4c5babdSJoe Perches
61500979ae66SJoe Perches# check for unnecessary blank lines around braces
615177b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6152f8e58219SJoe Perches			if (CHK("BRACES",
6153f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6154f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
6155f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
6156f8e58219SJoe Perches			}
61570979ae66SJoe Perches		}
615877b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
6159f8e58219SJoe Perches			if (CHK("BRACES",
6160f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6161f8e58219SJoe Perches			    $fix) {
6162f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
6163f8e58219SJoe Perches			}
61640979ae66SJoe Perches		}
61650979ae66SJoe Perches
61664a0df2efSAndy Whitcroft# no volatiles please
61676c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
61686c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6169000d1cc1SJoe Perches			WARN("VOLATILE",
61708c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
61714a0df2efSAndy Whitcroft		}
61724a0df2efSAndy Whitcroft
61735e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
61745e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
61755e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
61765e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
617733acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
61785e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
61795e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
61805e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
61815e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
61825e4f6ba5SJoe Perches				     $fix &&
61835e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
61845e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
61855e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
61865e4f6ba5SJoe Perches				my $comma_close = "";
61875e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
61885e4f6ba5SJoe Perches					$comma_close = $1;
61895e4f6ba5SJoe Perches				}
61905e4f6ba5SJoe Perches
61915e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
61925e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
61935e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
61945e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
61955e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
61965e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
61975e4f6ba5SJoe Perches				$fixedline = $rawline;
61985e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
61995e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
62005e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
62015e4f6ba5SJoe Perches				}
62025e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
62035e4f6ba5SJoe Perches			}
62045e4f6ba5SJoe Perches		}
62055e4f6ba5SJoe Perches
62065e4f6ba5SJoe Perches# check for missing a space in a string concatenation
62075e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
62085e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
62095e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
62105e4f6ba5SJoe Perches		}
62115e4f6ba5SJoe Perches
621277cb8546SJoe Perches# check for an embedded function name in a string when the function is known
6213e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
6214e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
6215e4b7d309SJoe Perches# function declarations
621677cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
621777cb8546SJoe Perches		    defined($context_function) &&
6218e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6219e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
622077cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
6221e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
622277cb8546SJoe Perches		}
622377cb8546SJoe Perches
6224adb2da82SJoe Perches# check for unnecessary function tracing like uses
6225adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6226adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6227adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6228adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6229adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6230adb2da82SJoe Perches			    $fix) {
6231adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6232adb2da82SJoe Perches			}
6233adb2da82SJoe Perches		}
6234adb2da82SJoe Perches
62355e4f6ba5SJoe Perches# check for spaces before a quoted newline
62365e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
62375e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
62385e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
62395e4f6ba5SJoe Perches			    $fix) {
62405e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
62415e4f6ba5SJoe Perches			}
62425e4f6ba5SJoe Perches
62435e4f6ba5SJoe Perches		}
62445e4f6ba5SJoe Perches
6245f17dba4fSJoe Perches# concatenated string without spaces between elements
6246d2af5aa6SJoe Perches		if ($line =~ /$String[A-Z_]/ ||
6247d2af5aa6SJoe Perches		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
624879682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
624979682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
625079682c0cSJoe Perches			    $fix) {
625179682c0cSJoe Perches				while ($line =~ /($String)/g) {
625279682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
625379682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
625479682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
625579682c0cSJoe Perches				}
625679682c0cSJoe Perches			}
6257f17dba4fSJoe Perches		}
6258f17dba4fSJoe Perches
625990ad30e5SJoe Perches# uncoalesced string fragments
6260d2af5aa6SJoe Perches		if ($line =~ /$String\s*[Lu]?"/) {
626179682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
626279682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
626379682c0cSJoe Perches			    $fix) {
626479682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
626579682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
626679682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
626779682c0cSJoe Perches				}
626879682c0cSJoe Perches			}
626990ad30e5SJoe Perches		}
627090ad30e5SJoe Perches
6271522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6272522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6273522b837cSAlexey Dobriyan		my $show_Z = 1;
62745e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6275522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
62765e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6277522b837cSAlexey Dobriyan			# check for %L
6278522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
62795e4f6ba5SJoe Perches				WARN("PRINTF_L",
6280522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6281522b837cSAlexey Dobriyan				$show_L = 0;
62825e4f6ba5SJoe Perches			}
6283522b837cSAlexey Dobriyan			# check for %Z
6284522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6285522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6286522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6287522b837cSAlexey Dobriyan				$show_Z = 0;
6288522b837cSAlexey Dobriyan			}
6289522b837cSAlexey Dobriyan			# check for 0x<decimal>
6290522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6291522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
62926e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
62936e300757SJoe Perches			}
62945e4f6ba5SJoe Perches		}
62955e4f6ba5SJoe Perches
62965e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
62973f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
62985e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
62995e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
63005e4f6ba5SJoe Perches		}
63015e4f6ba5SJoe Perches
630200df344fSAndy Whitcroft# warn about #if 0
6303c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
630460f89010SPrakruthi Deepak Heragu			WARN("IF_0",
630560f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
630660f89010SPrakruthi Deepak Heragu		}
630760f89010SPrakruthi Deepak Heragu
630860f89010SPrakruthi Deepak Heragu# warn about #if 1
630960f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
631060f89010SPrakruthi Deepak Heragu			WARN("IF_1",
631160f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
63124a0df2efSAndy Whitcroft		}
63134a0df2efSAndy Whitcroft
631403df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
631503df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6316100425deSJoe Perches			my $tested = quotemeta($1);
6317100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6318100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6319100425deSJoe Perches				my $func = $1;
6320100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6321100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6322100425deSJoe Perches				    $fix) {
6323100425deSJoe Perches					my $do_fix = 1;
6324100425deSJoe Perches					my $leading_tabs = "";
6325100425deSJoe Perches					my $new_leading_tabs = "";
6326100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6327100425deSJoe Perches						$leading_tabs = $1;
6328100425deSJoe Perches					} else {
6329100425deSJoe Perches						$do_fix = 0;
6330100425deSJoe Perches					}
6331100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6332100425deSJoe Perches						$new_leading_tabs = $1;
6333100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6334100425deSJoe Perches							$do_fix = 0;
6335100425deSJoe Perches						}
6336100425deSJoe Perches					} else {
6337100425deSJoe Perches						$do_fix = 0;
6338100425deSJoe Perches					}
6339100425deSJoe Perches					if ($do_fix) {
6340100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6341100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6342100425deSJoe Perches					}
6343100425deSJoe Perches				}
63444c432a8fSGreg Kroah-Hartman			}
63454c432a8fSGreg Kroah-Hartman		}
6346f0a594c1SAndy Whitcroft
6347ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6348ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6349ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6350ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6351ebfdc409SJoe Perches		    $linenr > 3) {
6352ebfdc409SJoe Perches			my $testval = $2;
6353ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6354ebfdc409SJoe Perches
6355ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6356ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6357ebfdc409SJoe Perches
6358e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6359e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6360ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6361ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6362ebfdc409SJoe Perches			}
6363ebfdc409SJoe Perches		}
6364ebfdc409SJoe Perches
6365f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6366dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6367f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6368f78d98f6SJoe Perches			my $level = $1;
6369f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6370f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6371f78d98f6SJoe Perches			    $fix) {
6372f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6373f78d98f6SJoe Perches			}
6374f78d98f6SJoe Perches		}
6375f78d98f6SJoe Perches
637645c55e92SJoe Perches# check for logging continuations
637745c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
637845c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
637945c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
638045c55e92SJoe Perches		}
638145c55e92SJoe Perches
638270eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
638370eb2275SDwaipayan Ray		if (defined $stat &&
638470eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
638570eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
638670eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
638770eb2275SDwaipayan Ray			$lc = $lc + $linenr;
638870eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
638970eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
639070eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
639170eb2275SDwaipayan Ray				my $pspec = $1;
639270eb2275SDwaipayan Ray				my $h = $2;
639370eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
639470eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
639570eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
639670eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
639770eb2275SDwaipayan Ray					my $nspec = $pspec;
639870eb2275SDwaipayan Ray					$nspec =~ s/h//g;
639970eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
640070eb2275SDwaipayan Ray				}
640170eb2275SDwaipayan Ray			}
640270eb2275SDwaipayan Ray		}
640370eb2275SDwaipayan Ray
6404abb08a53SJoe Perches# check for mask then right shift without a parentheses
64055b57980dSJoe Perches		if ($perl_version_ok &&
6406abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6407abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6408abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6409abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6410abb08a53SJoe Perches		}
6411abb08a53SJoe Perches
6412b75ac618SJoe Perches# check for pointer comparisons to NULL
64135b57980dSJoe Perches		if ($perl_version_ok) {
6414b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6415b75ac618SJoe Perches				my $val = $1;
6416b75ac618SJoe Perches				my $equal = "!";
6417b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6418b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6419b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6420b75ac618SJoe Perches					    $fix) {
6421b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6422b75ac618SJoe Perches				}
6423b75ac618SJoe Perches			}
6424b75ac618SJoe Perches		}
6425b75ac618SJoe Perches
64268716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
64278716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
64288716de38SJoe Perches			my $attr = $1;
64298716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
64308716de38SJoe Perches				my $ptr = $1;
64318716de38SJoe Perches				my $var = $2;
64328716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
64338716de38SJoe Perches				      ERROR("MISPLACED_INIT",
64348716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
64358716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
64368716de38SJoe Perches				      WARN("MISPLACED_INIT",
64378716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
64388716de38SJoe Perches				    $fix) {
6439194f66fcSJoe 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;
64408716de38SJoe Perches				}
64418716de38SJoe Perches			}
64428716de38SJoe Perches		}
64438716de38SJoe Perches
6444e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6445e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6446e970b884SJoe Perches			my $attr = $1;
6447e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6448e970b884SJoe Perches			my $attr_prefix = $1;
6449e970b884SJoe Perches			my $attr_type = $2;
6450e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6451e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6452e970b884SJoe Perches			    $fix) {
6453194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6454e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6455e970b884SJoe Perches			}
6456e970b884SJoe Perches		}
6457e970b884SJoe Perches
6458e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6459e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6460e970b884SJoe Perches			my $attr = $1;
6461e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6462e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6463e970b884SJoe Perches			    $fix) {
6464194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6465e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6466e970b884SJoe Perches				$lead = rtrim($1);
6467e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6468e970b884SJoe Perches				$lead = "${lead}const ";
6469194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6470e970b884SJoe Perches			}
6471e970b884SJoe Perches		}
6472e970b884SJoe Perches
6473c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6474c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6475c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6476c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6477c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6478c17893c7SJoe Perches			    $fix) {
6479c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6480c17893c7SJoe Perches			}
6481c17893c7SJoe Perches		}
6482c17893c7SJoe Perches
6483fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6484fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6485fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6486fbdb8138SJoe Perches			my $constant_func = $1;
6487fbdb8138SJoe Perches			my $func = $constant_func;
6488fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6489fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6490fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6491fbdb8138SJoe Perches			    $fix) {
6492194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6493fbdb8138SJoe Perches			}
6494fbdb8138SJoe Perches		}
6495fbdb8138SJoe Perches
64961a15a250SPatrick Pannuto# prefer usleep_range over udelay
649737581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
649843c1d77cSJoe Perches			my $delay = $1;
64991a15a250SPatrick Pannuto			# ignore udelay's < 10, however
650043c1d77cSJoe Perches			if (! ($delay < 10) ) {
6501000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6502458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
650343c1d77cSJoe Perches			}
650443c1d77cSJoe Perches			if ($delay > 2000) {
650543c1d77cSJoe Perches				WARN("LONG_UDELAY",
650643c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
65071a15a250SPatrick Pannuto			}
65081a15a250SPatrick Pannuto		}
65091a15a250SPatrick Pannuto
651009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
651109ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
651209ef8725SPatrick Pannuto			if ($1 < 20) {
6513000d1cc1SJoe Perches				WARN("MSLEEP",
6514458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
651509ef8725SPatrick Pannuto			}
651609ef8725SPatrick Pannuto		}
651709ef8725SPatrick Pannuto
651836ec1939SJoe Perches# check for comparisons of jiffies
651936ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
652036ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
652136ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
652236ec1939SJoe Perches		}
652336ec1939SJoe Perches
65249d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
65259d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
65269d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
65279d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
65289d7a34a5SJoe Perches		}
65299d7a34a5SJoe Perches
653000df344fSAndy Whitcroft# warn about #ifdefs in C files
6531c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
653200df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
653300df344fSAndy Whitcroft#			print "$herecurr";
653400df344fSAndy Whitcroft#			$clean = 0;
653500df344fSAndy Whitcroft#		}
653600df344fSAndy Whitcroft
653722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6538c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
65393705ce5bSJoe Perches			if (ERROR("SPACING",
65403705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
65413705ce5bSJoe Perches			    $fix) {
6542194f66fcSJoe Perches				$fixed[$fixlinenr] =~
65433705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
65443705ce5bSJoe Perches			}
65453705ce5bSJoe Perches
654622f2a2efSAndy Whitcroft		}
654722f2a2efSAndy Whitcroft
65484a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6549171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6550171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
65514a0df2efSAndy Whitcroft			my $which = $1;
65524a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6553000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6554000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
65554a0df2efSAndy Whitcroft			}
65564a0df2efSAndy Whitcroft		}
65574a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6558402c2553SMichael S. Tsirkin
6559402c2553SMichael S. Tsirkin		my $barriers = qr{
6560402c2553SMichael S. Tsirkin			mb|
6561402c2553SMichael S. Tsirkin			rmb|
6562ad83ec6cSWill Deacon			wmb
6563402c2553SMichael S. Tsirkin		}x;
6564402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6565402c2553SMichael S. Tsirkin			mb__before_atomic|
6566402c2553SMichael S. Tsirkin			mb__after_atomic|
6567402c2553SMichael S. Tsirkin			store_release|
6568402c2553SMichael S. Tsirkin			load_acquire|
6569402c2553SMichael S. Tsirkin			store_mb|
6570402c2553SMichael S. Tsirkin			(?:$barriers)
6571402c2553SMichael S. Tsirkin		}x;
6572402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6573402c2553SMichael S. Tsirkin			(?:$barriers)|
657443e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
657543e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6576402c2553SMichael S. Tsirkin		}x;
6577402c2553SMichael S. Tsirkin
6578402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
65794a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6580c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6581000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
65824a0df2efSAndy Whitcroft			}
65834a0df2efSAndy Whitcroft		}
65843ad81779SPaul E. McKenney
6585f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6586f4073b0fSMichael S. Tsirkin
6587f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6588f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6589f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6590f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6591f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6592f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6593f4073b0fSMichael S. Tsirkin		}
6594f4073b0fSMichael S. Tsirkin
6595cb426e99SJoe Perches# check for waitqueue_active without a comment.
6596cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6597cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6598cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6599cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6600cb426e99SJoe Perches			}
6601cb426e99SJoe Perches		}
66023ad81779SPaul E. McKenney
66035099a722SMarco Elver# check for data_race without a comment.
66045099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
66055099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
66065099a722SMarco Elver				WARN("DATA_RACE",
66075099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
66085099a722SMarco Elver			}
66095099a722SMarco Elver		}
66105099a722SMarco Elver
66114a0df2efSAndy Whitcroft# check of hardware specific defines
6612c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6613000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6614000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
66150a920b5bSAndy Whitcroft		}
6616653d4876SAndy Whitcroft
6617596ed45bSJoe Perches# check that the storage class is not after a type
6618596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6619000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6620596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6621596ed45bSJoe Perches		}
6622596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6623596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6624596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6625596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6626596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6627596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6628596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6629d4977c78STobias Klauser		}
6630d4977c78STobias Klauser
6631de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6632de7d4f0eSAndy Whitcroft# storage class and type.
66339c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
66349c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6635000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6636000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6637de7d4f0eSAndy Whitcroft		}
6638de7d4f0eSAndy Whitcroft
66398905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
66402b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
66412b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6642d5e616fcSJoe Perches			if (WARN("INLINE",
6643d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6644d5e616fcSJoe Perches			    $fix) {
6645194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6646d5e616fcSJoe Perches
6647d5e616fcSJoe Perches			}
66488905a67cSAndy Whitcroft		}
66498905a67cSAndy Whitcroft
66507ebe1d17SDwaipayan Ray# Check for compiler attributes
66512b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
66527ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
66537ebe1d17SDwaipayan Ray			my $attr = $1;
66547ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
66557ebe1d17SDwaipayan Ray
66567ebe1d17SDwaipayan Ray			my %attr_list = (
66570830aab0SJoe Perches				"alias"				=> "__alias",
66587ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
66597ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
66607ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
66617ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
66627ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
66637ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
66647ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
66657ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
66667ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
66677ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
66687ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
66697ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
66707ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
66717ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
66727ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
66737ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
66747ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
66757ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
66767ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6677339f29d9SJoe Perches				"section"			=> "__section",
66780830aab0SJoe Perches				"used"				=> "__used",
66790830aab0SJoe Perches				"weak"				=> "__weak"
66807ebe1d17SDwaipayan Ray			);
66817ebe1d17SDwaipayan Ray
66827ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6683339f29d9SJoe Perches				my $orig_attr = $1;
66847ebe1d17SDwaipayan Ray				my $params = '';
66857ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6686339f29d9SJoe Perches				my $curr_attr = $orig_attr;
66877ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
66887ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6689339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
66907ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
66917ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6692339f29d9SJoe Perches						$new = "__$1\($2";
66937ebe1d17SDwaipayan Ray					} else {
6694339f29d9SJoe Perches						$new = "$new$params";
66957ebe1d17SDwaipayan Ray					}
66967ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6697339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
66987ebe1d17SDwaipayan Ray					    $fix) {
6699339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6700339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6701339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6702339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6703339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
67047ebe1d17SDwaipayan Ray					}
670539b7e287SJoe Perches				}
6706462811d9SJoe Perches			}
6707462811d9SJoe Perches
67087ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
67097ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
67107ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
67117ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6712d5e616fcSJoe Perches			}
67136061d949SJoe Perches		}
67146061d949SJoe Perches
6715619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
67165b57980dSJoe Perches		if ($perl_version_ok &&
6717619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6718619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6719619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6720619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6721619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6722619a908aSJoe Perches		}
6723619a908aSJoe Perches
6724fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6725e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6726fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6727e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6728e6176fa4SJoe Perches			my $type = $1;
6729e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6730e6176fa4SJoe Perches				$type = $1;
6731e6176fa4SJoe Perches				my $kernel_type = 'u';
6732e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6733e6176fa4SJoe Perches				$type =~ /(\d+)/;
6734e6176fa4SJoe Perches				$kernel_type .= $1;
6735e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6736e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6737e6176fa4SJoe Perches				    $fix) {
6738e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6739e6176fa4SJoe Perches				}
6740e6176fa4SJoe Perches			}
6741e6176fa4SJoe Perches		}
6742e6176fa4SJoe Perches
6743938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6744938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6745938224b5SJoe Perches			my $cast = $1;
6746938224b5SJoe Perches			my $const = $2;
6747938224b5SJoe Perches			my $suffix = "";
6748938224b5SJoe Perches			my $newconst = $const;
6749938224b5SJoe Perches			$newconst =~ s/${Int_type}$//;
6750938224b5SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6751938224b5SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6752938224b5SJoe Perches			    $suffix .= 'LL';
6753938224b5SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6754938224b5SJoe Perches			    $suffix .= 'L';
6755938224b5SJoe Perches			}
67560972b8bfSJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
67570972b8bfSJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
67580972b8bfSJoe Perches			    $fix) {
6759938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6760938224b5SJoe Perches			}
6761938224b5SJoe Perches		}
6762938224b5SJoe Perches
67638f53a9b8SJoe Perches# check for sizeof(&)
67648f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6765000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6766000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
67678f53a9b8SJoe Perches		}
67688f53a9b8SJoe Perches
676966c80b60SJoe Perches# check for sizeof without parenthesis
677066c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6771d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6772d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6773d5e616fcSJoe Perches			    $fix) {
6774194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6775d5e616fcSJoe Perches			}
677666c80b60SJoe Perches		}
677766c80b60SJoe Perches
677888982feaSJoe Perches# check for struct spinlock declarations
677988982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
678088982feaSJoe Perches			WARN("USE_SPINLOCK_T",
678188982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
678288982feaSJoe Perches		}
678388982feaSJoe Perches
6784a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
678506668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6786a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6787caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6788caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6789d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6790d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6791d5e616fcSJoe Perches				    $fix) {
6792194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6793d5e616fcSJoe Perches				}
6794a6962d72SJoe Perches			}
6795a6962d72SJoe Perches		}
6796a6962d72SJoe Perches
67970b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
67985b57980dSJoe Perches		if ($perl_version_ok &&
67990b523769SJoe Perches		    defined $stat &&
68000b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
68010b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6802e3c6bc95STobin C. Harding			my $stat_real;
6803e3c6bc95STobin C. Harding
68040b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
68050b523769SJoe Perches			$lc = $lc + $linenr;
68060b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6807ffe07513SJoe Perches				my $specifier;
6808ffe07513SJoe Perches				my $extension;
68093bd32d6aSSakari Ailus				my $qualifier;
6810ffe07513SJoe Perches				my $bad_specifier = "";
68110b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
68120b523769SJoe Perches				$fmt =~ s/%%//g;
6813e3c6bc95STobin C. Harding
68143bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6815e3c6bc95STobin C. Harding					$specifier = $1;
6816e3c6bc95STobin C. Harding					$extension = $2;
68173bd32d6aSSakari Ailus					$qualifier = $3;
6818af612e43SSakari Ailus					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
68193bd32d6aSSakari Ailus					    ($extension eq "f" &&
6820af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^w/) ||
6821af612e43SSakari Ailus					    ($extension eq "4" &&
6822af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^cc/)) {
6823e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
68240b523769SJoe Perches						last;
68250b523769SJoe Perches					}
6826e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6827e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6828e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
68290b523769SJoe Perches						}
6830e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6831e3c6bc95STobin 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");
6832e3c6bc95STobin C. Harding					}
6833e3c6bc95STobin C. Harding				}
6834e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
68352a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
68361df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
68371df7338aSSergey Senozhatsky					my $use = "";
6838e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
68391df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6840e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
68411df7338aSSergey Senozhatsky					}
68422a9f9d85STobin C. Harding
68430b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6844e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6845e3c6bc95STobin C. Harding				}
68460b523769SJoe Perches			}
68470b523769SJoe Perches		}
68480b523769SJoe Perches
6849554e165cSAndy Whitcroft# Check for misused memsets
68505b57980dSJoe Perches		if ($perl_version_ok &&
6851d1fe9c09SJoe Perches		    defined $stat &&
68529e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6853554e165cSAndy Whitcroft
6854d7c76ba7SJoe Perches			my $ms_addr = $2;
6855d1fe9c09SJoe Perches			my $ms_val = $7;
6856d1fe9c09SJoe Perches			my $ms_size = $12;
6857d7c76ba7SJoe Perches
6858554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6859554e165cSAndy Whitcroft				ERROR("MEMSET",
6860d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6861554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6862554e165cSAndy Whitcroft				WARN("MEMSET",
6863d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6864d7c76ba7SJoe Perches			}
6865d7c76ba7SJoe Perches		}
6866d7c76ba7SJoe Perches
686798a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
68685b57980dSJoe Perches#		if ($perl_version_ok &&
6869f333195dSJoe Perches#		    defined $stat &&
6870f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6871f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6872f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6873f333195dSJoe Perches#			    $fix) {
6874f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6875f333195dSJoe Perches#			}
6876f333195dSJoe Perches#		}
687798a9bba5SJoe Perches
6878b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
68795b57980dSJoe Perches#		if ($perl_version_ok &&
6880f333195dSJoe Perches#		    defined $stat &&
6881f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6882f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6883f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6884f333195dSJoe Perches#		}
6885b6117d17SMateusz Kulikowski
68868617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
68878617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
68885b57980dSJoe Perches#		if ($perl_version_ok &&
6889f333195dSJoe Perches#		    defined $stat &&
6890f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6891f333195dSJoe Perches#
6892f333195dSJoe Perches#			my $ms_val = $7;
6893f333195dSJoe Perches#
6894f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6895f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6896f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6897f333195dSJoe Perches#				    $fix) {
6898f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6899f333195dSJoe Perches#				}
6900f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6901f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6902f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6903f333195dSJoe Perches#				    $fix) {
6904f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6905f333195dSJoe Perches#				}
6906f333195dSJoe Perches#			}
6907f333195dSJoe Perches#		}
69088617cd09SMateusz Kulikowski
69095dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
69105dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
69115dbdb2d8SJoe Perches			WARN("STRLCPY",
69125dbdb2d8SJoe Perches			     "Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\@mail.gmail.com/\n" . $herecurr);
69135dbdb2d8SJoe Perches		}
69145dbdb2d8SJoe Perches
6915d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
69165b57980dSJoe Perches		if ($perl_version_ok &&
6917d1fe9c09SJoe Perches		    defined $stat &&
6918d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6919d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6920d7c76ba7SJoe Perches				my $call = $1;
6921d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6922d7c76ba7SJoe Perches				my $arg1 = $3;
6923d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6924d1fe9c09SJoe Perches				my $arg2 = $8;
6925d7c76ba7SJoe Perches				my $cast;
6926d7c76ba7SJoe Perches
6927d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6928d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6929d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6930d7c76ba7SJoe Perches					$cast = $cast1;
6931d7c76ba7SJoe Perches				} else {
6932d7c76ba7SJoe Perches					$cast = $cast2;
6933d7c76ba7SJoe Perches				}
6934d7c76ba7SJoe Perches				WARN("MINMAX",
6935d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6936554e165cSAndy Whitcroft			}
6937554e165cSAndy Whitcroft		}
6938554e165cSAndy Whitcroft
69394a273195SJoe Perches# check usleep_range arguments
69405b57980dSJoe Perches		if ($perl_version_ok &&
69414a273195SJoe Perches		    defined $stat &&
69424a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
69434a273195SJoe Perches			my $min = $1;
69444a273195SJoe Perches			my $max = $7;
69454a273195SJoe Perches			if ($min eq $max) {
69464a273195SJoe Perches				WARN("USLEEP_RANGE",
6947458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
69484a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
69494a273195SJoe Perches				 $min > $max) {
69504a273195SJoe Perches				WARN("USLEEP_RANGE",
6951458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
69524a273195SJoe Perches			}
69534a273195SJoe Perches		}
69544a273195SJoe Perches
6955823b794cSJoe Perches# check for naked sscanf
69565b57980dSJoe Perches		if ($perl_version_ok &&
6957823b794cSJoe Perches		    defined $stat &&
69586c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6959823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6960823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6961823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6962823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6963823b794cSJoe Perches			$lc = $lc + $linenr;
69642a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6965823b794cSJoe Perches			WARN("NAKED_SSCANF",
6966823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6967823b794cSJoe Perches		}
6968823b794cSJoe Perches
6969afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
69705b57980dSJoe Perches		if ($perl_version_ok &&
6971afc819abSJoe Perches		    defined $stat &&
6972afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6973afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6974afc819abSJoe Perches			$lc = $lc + $linenr;
69752a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6976afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6977afc819abSJoe Perches				my $format = $6;
6978afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6979afc819abSJoe Perches				if ($count == 1 &&
6980afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6981afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6982afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6983afc819abSJoe Perches				}
6984afc819abSJoe Perches			}
6985afc819abSJoe Perches		}
6986afc819abSJoe Perches
698770dc8a48SJoe Perches# check for new externs in .h files.
698870dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
698970dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6990d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
699170dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
699270dc8a48SJoe Perches			    $fix) {
6993194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
699470dc8a48SJoe Perches			}
699570dc8a48SJoe Perches		}
699670dc8a48SJoe Perches
6997de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6998171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6999c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
7000171ae1a4SAndy Whitcroft		{
7001c45dcabdSAndy Whitcroft			my $function_name = $1;
7002c45dcabdSAndy Whitcroft			my $paren_space = $2;
7003171ae1a4SAndy Whitcroft
7004171ae1a4SAndy Whitcroft			my $s = $stat;
7005171ae1a4SAndy Whitcroft			if (defined $cond) {
7006171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
7007171ae1a4SAndy Whitcroft			}
7008d8b44b58SKees Cook			if ($s =~ /^\s*;/)
7009c45dcabdSAndy Whitcroft			{
7010000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
7011000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
7012de7d4f0eSAndy Whitcroft			}
7013de7d4f0eSAndy Whitcroft
7014171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
7015000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
7016000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
7017171ae1a4SAndy Whitcroft			}
70189c9ba34eSAndy Whitcroft
70199c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
70209c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
70219c9ba34eSAndy Whitcroft		{
7022000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
7023000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
7024171ae1a4SAndy Whitcroft		}
7025171ae1a4SAndy Whitcroft
7026a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
7027a0ad7596SJoe Perches		if (defined $stat &&
7028d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
7029d8b44b58SKees Cook		    $1 ne "void") {
7030d8b44b58SKees Cook			my $args = trim($1);
7031ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
7032ca0d8929SJoe Perches				my $arg = trim($1);
7033d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
7034ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
7035ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
7036ca0d8929SJoe Perches				}
7037ca0d8929SJoe Perches			}
7038ca0d8929SJoe Perches		}
7039ca0d8929SJoe Perches
7040a0ad7596SJoe Perches# check for function definitions
70415b57980dSJoe Perches		if ($perl_version_ok &&
7042a0ad7596SJoe Perches		    defined $stat &&
7043a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
7044a0ad7596SJoe Perches			$context_function = $1;
7045a0ad7596SJoe Perches
7046a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
7047a0ad7596SJoe Perches			my $ok = 0;
7048a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
7049a0ad7596SJoe Perches			my $herectx = $here . "\n";
7050a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
7051a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
7052a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
7053a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
7054a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
7055a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
7056a0ad7596SJoe Perches			}
7057a0ad7596SJoe Perches			if (!$ok) {
7058a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
7059a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
7060a0ad7596SJoe Perches			}
7061a0ad7596SJoe Perches		}
7062a0ad7596SJoe Perches
7063de7d4f0eSAndy Whitcroft# checks for new __setup's
7064de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
7065de7d4f0eSAndy Whitcroft			my $name = $1;
7066de7d4f0eSAndy Whitcroft
7067de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
7068000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
70692581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
7070de7d4f0eSAndy Whitcroft			}
7071653d4876SAndy Whitcroft		}
70729c0ca6f9SAndy Whitcroft
7073e29a70f1SJoe Perches# check for pointless casting of alloc functions
7074e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
7075000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
7076000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
70779c0ca6f9SAndy Whitcroft		}
707813214adfSAndy Whitcroft
7079a640d25cSJoe Perches# alloc style
7080a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
70815b57980dSJoe Perches		if ($perl_version_ok &&
7082e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
7083a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
7084a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
7085a640d25cSJoe Perches		}
7086a640d25cSJoe Perches
708773f1d07eSGustavo A. R. Silva# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc
70885b57980dSJoe Perches		if ($perl_version_ok &&
70891b4a2ed4SJoe Perches		    defined $stat &&
709073f1d07eSGustavo A. R. Silva		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
709160a55369SJoe Perches			my $oldfunc = $3;
709260a55369SJoe Perches			my $a1 = $4;
709360a55369SJoe Perches			my $a2 = $10;
709460a55369SJoe Perches			my $newfunc = "kmalloc_array";
709573f1d07eSGustavo A. R. Silva			$newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");
709673f1d07eSGustavo A. R. Silva			$newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");
709760a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
709860a55369SJoe Perches			my $r1 = $a1;
709960a55369SJoe Perches			my $r2 = $a2;
710060a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
710160a55369SJoe Perches				$r1 = $a2;
710260a55369SJoe Perches				$r2 = $a1;
710360a55369SJoe Perches			}
7104e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
7105e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
71061b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
7107e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
7108e3d95a2aSTobin C. Harding
7109e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
71101b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
71111b4a2ed4SJoe Perches				    $cnt == 1 &&
7112e367455aSJoe Perches				    $fix) {
711373f1d07eSGustavo A. R. Silva					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
711460a55369SJoe Perches				}
711560a55369SJoe Perches			}
711660a55369SJoe Perches		}
711760a55369SJoe Perches
7118972fdea2SJoe Perches# check for krealloc arg reuse
71195b57980dSJoe Perches		if ($perl_version_ok &&
71204cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
71214cab63ceSJoe Perches		    $1 eq $3) {
7122972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
7123972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7124972fdea2SJoe Perches		}
7125972fdea2SJoe Perches
71265ce59ae0SJoe Perches# check for alloc argument mismatch
71277e6cdd7fSChristophe JAILLET		if ($line =~ /\b((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {
71285ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
71295ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
71305ce59ae0SJoe Perches		}
71315ce59ae0SJoe Perches
7132caf2a54fSJoe Perches# check for multiple semicolons
7133caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
7134d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
7135d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7136d5e616fcSJoe Perches			    $fix) {
7137194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7138d5e616fcSJoe Perches			}
7139d1e2ad07SJoe Perches		}
7140d1e2ad07SJoe Perches
7141cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7142cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
7143cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
71440ab90191SJoe Perches			my $ull = "";
71450ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
71460ab90191SJoe Perches			if (CHK("BIT_MACRO",
71470ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
71480ab90191SJoe Perches			    $fix) {
71490ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
71500ab90191SJoe Perches			}
71510ab90191SJoe Perches		}
71520ab90191SJoe Perches
715350161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
71543e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
715550161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
71563e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
715750161266SJoe Perches		}
715850161266SJoe Perches
71592d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
71603e89ad85SJerome 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*$/) {
71612d632745SJoe Perches			my $config = $1;
71622d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
71633e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
71642d632745SJoe Perches			    $fix) {
71652d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
71662d632745SJoe Perches			}
71672d632745SJoe Perches		}
71682d632745SJoe Perches
7169f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
7170f36d3eb8SJoe Perches		my @fallthroughs = (
7171f36d3eb8SJoe Perches			'fallthrough',
7172f36d3eb8SJoe Perches			'@fallthrough@',
7173f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
7174f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7175f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7176f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7177f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7178f36d3eb8SJoe Perches		    );
7179f36d3eb8SJoe Perches		if ($raw_comment ne '') {
7180f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
7181f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
7182f36d3eb8SJoe Perches					my $msg_level = \&WARN;
7183f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
7184f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
7185f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7186f36d3eb8SJoe Perches					last;
7187f36d3eb8SJoe Perches				}
7188f36d3eb8SJoe Perches			}
7189f36d3eb8SJoe Perches		}
7190f36d3eb8SJoe Perches
7191d1e2ad07SJoe Perches# check for switch/default statements without a break;
71925b57980dSJoe Perches		if ($perl_version_ok &&
7193d1e2ad07SJoe Perches		    defined $stat &&
7194d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7195d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
7196e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
7197e3d95a2aSTobin C. Harding
7198d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
7199d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
7200caf2a54fSJoe Perches		}
7201caf2a54fSJoe Perches
720213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
7203d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
7204d5e616fcSJoe Perches			if (WARN("USE_FUNC",
7205d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
7206d5e616fcSJoe Perches			    $fix) {
7207194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7208d5e616fcSJoe Perches			}
720913214adfSAndy Whitcroft		}
7210773647a0SAndy Whitcroft
721162ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
721262ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
721362ec818fSJoe Perches			ERROR("DATE_TIME",
721462ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
721562ec818fSJoe Perches		}
721662ec818fSJoe Perches
72172c92488aSJoe Perches# check for use of yield()
72182c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
72192c92488aSJoe Perches			WARN("YIELD",
72202c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
72212c92488aSJoe Perches		}
72222c92488aSJoe Perches
7223179f8f40SJoe Perches# check for comparisons against true and false
7224179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7225179f8f40SJoe Perches			my $lead = $1;
7226179f8f40SJoe Perches			my $arg = $2;
7227179f8f40SJoe Perches			my $test = $3;
7228179f8f40SJoe Perches			my $otype = $4;
7229179f8f40SJoe Perches			my $trail = $5;
7230179f8f40SJoe Perches			my $op = "!";
7231179f8f40SJoe Perches
7232179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7233179f8f40SJoe Perches
7234179f8f40SJoe Perches			my $type = lc($otype);
7235179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7236179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7237179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7238179f8f40SJoe Perches					$op = "";
7239179f8f40SJoe Perches				}
7240179f8f40SJoe Perches
7241179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7242179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7243179f8f40SJoe Perches
7244179f8f40SJoe Perches## maybe suggesting a correct construct would better
7245179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7246179f8f40SJoe Perches
7247179f8f40SJoe Perches			}
7248179f8f40SJoe Perches		}
7249179f8f40SJoe Perches
72504882720bSThomas Gleixner# check for semaphores initialized locked
72514882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7252000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7253000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7254773647a0SAndy Whitcroft		}
72556712d858SJoe Perches
725667d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
725767d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7258000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
725967d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7260773647a0SAndy Whitcroft		}
72616712d858SJoe Perches
7262ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7263f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7264000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7265ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7266f3db6639SMichael Ellerman		}
72676712d858SJoe Perches
72683d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
72693d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
72703d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
72713d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
72723d709ab5SPaul E. McKenney		}
72733d709ab5SPaul E. McKenney
72749189c7e7SJoe Perches# check for deprecated apis
72759189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
72769189c7e7SJoe Perches			my $deprecated_api = $1;
72779189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
72789189c7e7SJoe Perches			WARN("DEPRECATED_API",
72799189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
72809189c7e7SJoe Perches		}
72819189c7e7SJoe Perches
72820f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7283d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7284ced69da1SQuentin Monnet		if (defined($const_structs) &&
7285ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7286d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7287000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7288d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
72892b6db5cbSAndy Whitcroft		}
7290773647a0SAndy Whitcroft
7291773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7292773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
729335cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7294773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7295c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7296c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7297171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7298171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
729935cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
730035cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7301773647a0SAndy Whitcroft		{
7302000d1cc1SJoe Perches			WARN("NR_CPUS",
7303000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7304773647a0SAndy Whitcroft		}
73059c9ba34eSAndy Whitcroft
730652ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
730752ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
730852ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
730952ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
731052ea8506SJoe Perches		}
731152ea8506SJoe Perches
7312acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
73135b57980dSJoe Perches		if ($perl_version_ok &&
7314acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7315acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7316acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7317acd9362cSJoe Perches		}
7318acd9362cSJoe Perches
7319fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline
7320fbe74541SJoe Perches		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7321fbe74541SJoe Perches		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7322fbe74541SJoe Perches			my $offset = $+[6] - 1;
7323fbe74541SJoe Perches			if (WARN("SYSFS_EMIT",
7324fbe74541SJoe Perches				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7325fbe74541SJoe Perches			    $fix) {
7326fbe74541SJoe Perches				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7327fbe74541SJoe Perches			}
7328fbe74541SJoe Perches		}
7329fbe74541SJoe Perches
7330de3f186fSDenis Efremov# nested likely/unlikely calls
7331de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7332de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7333de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7334de3f186fSDenis Efremov		}
7335de3f186fSDenis Efremov
7336691d77b6SAndy Whitcroft# whine mightly about in_atomic
7337691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7338691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7339000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7340000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7341f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7342000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7343000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7344691d77b6SAndy Whitcroft			}
7345691d77b6SAndy Whitcroft		}
73461704f47bSPeter Zijlstra
73471704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
73481704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
73491704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
73501704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
73511704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
73521704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7353000d1cc1SJoe Perches				ERROR("LOCKDEP",
7354000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
73551704f47bSPeter Zijlstra			}
73561704f47bSPeter Zijlstra		}
735788f8831cSDave Jones
7358b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7359b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7360000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7361000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
736288f8831cSDave Jones		}
73632435880fSJoe Perches
736400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
736500180468SJoe Perches# and whether or not function naming is typical and if
736600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
73675b57980dSJoe Perches		if ($perl_version_ok &&
736800180468SJoe Perches		    defined $stat &&
736900180468SJoe 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*\)/) {
737000180468SJoe Perches			my $var = $1;
737100180468SJoe Perches			my $perms = $2;
737200180468SJoe Perches			my $show = $3;
737300180468SJoe Perches			my $store = $4;
737400180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
737500180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
737600180468SJoe Perches			    $store =~ /^${var}_store$/ &&
737700180468SJoe Perches			    $octal_perms eq "0644") {
737800180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
737900180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
738000180468SJoe Perches				    $fix) {
738100180468SJoe 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})/;
738200180468SJoe Perches				}
738300180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
738400180468SJoe Perches				 $store =~ /^NULL$/ &&
738500180468SJoe Perches				 $octal_perms eq "0444") {
738600180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
738700180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
738800180468SJoe Perches				    $fix) {
738900180468SJoe 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})/;
739000180468SJoe Perches				}
739100180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
739200180468SJoe Perches				 $store =~ /^${var}_store$/ &&
739300180468SJoe Perches				 $octal_perms eq "0200") {
739400180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
739500180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
739600180468SJoe Perches				    $fix) {
739700180468SJoe 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})/;
739800180468SJoe Perches				}
739900180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
740000180468SJoe Perches				 $octal_perms eq "0444" ||
740100180468SJoe Perches				 $octal_perms eq "0200") {
740200180468SJoe Perches				my $newshow = "$show";
740300180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
740400180468SJoe Perches				my $newstore = $store;
740500180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
740600180468SJoe Perches				my $rename = "";
740700180468SJoe Perches				if ($show ne $newshow) {
740800180468SJoe Perches					$rename .= " '$show' to '$newshow'";
740900180468SJoe Perches				}
741000180468SJoe Perches				if ($store ne $newstore) {
741100180468SJoe Perches					$rename .= " '$store' to '$newstore'";
741200180468SJoe Perches				}
741300180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
741400180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
741500180468SJoe Perches			} else {
741600180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
741700180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
741800180468SJoe Perches			}
741900180468SJoe Perches		}
742000180468SJoe Perches
7421515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7422515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
742373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
742473121534SJoe Perches#   specific definition of not visible in sysfs.
742573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
742673121534SJoe Perches#   use the default permissions
74275b57980dSJoe Perches		if ($perl_version_ok &&
7428459cf0aeSJoe Perches		    defined $stat &&
7429515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
74302435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
74312435880fSJoe Perches				my $func = $entry->[0];
74322435880fSJoe Perches				my $arg_pos = $entry->[1];
74332435880fSJoe Perches
7434459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7435459cf0aeSJoe Perches				$lc = $lc + $linenr;
74362a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7437459cf0aeSJoe Perches
74382435880fSJoe Perches				my $skip_args = "";
74392435880fSJoe Perches				if ($arg_pos > 1) {
74402435880fSJoe Perches					$arg_pos--;
74412435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
74422435880fSJoe Perches				}
7443f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7444459cf0aeSJoe Perches				if ($stat =~ /$test/) {
74452435880fSJoe Perches					my $val = $1;
74462435880fSJoe Perches					$val = $6 if ($skip_args ne "");
744773121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
744873121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
744973121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
74502435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7451459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7452f90774e1SJoe Perches					}
7453f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7454c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7455459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
74562435880fSJoe Perches					}
7457459cf0aeSJoe Perches				}
7458459cf0aeSJoe Perches			}
7459459cf0aeSJoe Perches		}
7460459cf0aeSJoe Perches
7461459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7462bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
746300180468SJoe Perches			my $oval = $1;
746400180468SJoe Perches			my $octal = perms_to_octal($oval);
7465f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7466459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7467f90774e1SJoe Perches			    $fix) {
746800180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
74692435880fSJoe Perches			}
747013214adfSAndy Whitcroft		}
74715a6d20ceSBjorn Andersson
74725a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
74735a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
74745a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
74755a6d20ceSBjorn Andersson			my $valid_licenses = qr{
74765a6d20ceSBjorn Andersson						GPL|
74775a6d20ceSBjorn Andersson						GPL\ v2|
74785a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
74795a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
74805a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
74815a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
74825a6d20ceSBjorn Andersson						Proprietary
74835a6d20ceSBjorn Andersson					}x;
74845a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
74855a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
74865a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
74875a6d20ceSBjorn Andersson			}
74886e8f42dcSJoe Perches			if (!$file && $extracted_string eq '"GPL v2"') {
74896e8f42dcSJoe Perches				if (WARN("MODULE_LICENSE",
74906e8f42dcSJoe Perches				     "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&
74916e8f42dcSJoe Perches				    $fix) {
74926e8f42dcSJoe Perches					$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;
74936e8f42dcSJoe Perches				}
74946e8f42dcSJoe Perches			}
74955a6d20ceSBjorn Andersson		}
74966a8d76cbSMatteo Croce
74976a8d76cbSMatteo Croce# check for sysctl duplicate constants
74986a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
74996a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
75006a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
75016a8d76cbSMatteo Croce		}
7502515a235eSJoe Perches	}
750313214adfSAndy Whitcroft
750413214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
750513214adfSAndy Whitcroft	# so just keep quiet.
750613214adfSAndy Whitcroft	if ($#rawlines == -1) {
750713214adfSAndy Whitcroft		exit(0);
75080a920b5bSAndy Whitcroft	}
75090a920b5bSAndy Whitcroft
75108905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
75118905a67cSAndy Whitcroft	# things that appear to be patches.
75128905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
75138905a67cSAndy Whitcroft		exit(0);
75148905a67cSAndy Whitcroft	}
75158905a67cSAndy Whitcroft
7516e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
75178905a67cSAndy Whitcroft	# just keep quiet.
75188905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
75198905a67cSAndy Whitcroft		exit(0);
75208905a67cSAndy Whitcroft	}
75218905a67cSAndy Whitcroft
7522a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7523000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7524000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
75250a920b5bSAndy Whitcroft	}
7526cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7527cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7528000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7529000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
753048ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
753148ca2d8aSDwaipayan Ray			# authorsignoff values:
753248ca2d8aSDwaipayan Ray			# 0 -> missing sign off
753348ca2d8aSDwaipayan Ray			# 1 -> sign off identical
753448ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
753548ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
753648ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
753748ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
753848ca2d8aSDwaipayan Ray
753948ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
754048ca2d8aSDwaipayan Ray
754148ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
754248ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7543cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
754448ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
754548ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
754648ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
754748ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
754848ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
754948ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
755048ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
755148ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
755248ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
755348ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
755448ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
755548ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
755648ca2d8aSDwaipayan Ray			}
7557cd261496SGeert Uytterhoeven		}
75580a920b5bSAndy Whitcroft	}
75590a920b5bSAndy Whitcroft
7560f0a594c1SAndy Whitcroft	print report_dump();
756113214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
756213214adfSAndy Whitcroft		print "$filename " if ($summary_file);
75636c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
75646c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
75656c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
75666c72ffaaSAndy Whitcroft	}
75678905a67cSAndy Whitcroft
7568d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7569ef212196SJoe Perches		# If there were any defects found and not already fixing them
7570ef212196SJoe Perches		if (!$clean and !$fix) {
7571ef212196SJoe Perches			print << "EOM"
7572ef212196SJoe Perches
7573ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7574ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7575ef212196SJoe PerchesEOM
7576ef212196SJoe Perches		}
7577d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7578d2c0a235SAndy Whitcroft		# then suggest that.
7579d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7580b0781216SMike Frysinger			$rpt_cleaners = 0;
7581d8469f16SJoe Perches			print << "EOM"
7582d8469f16SJoe Perches
7583d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7584d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7585d8469f16SJoe PerchesEOM
7586d2c0a235SAndy Whitcroft		}
7587d2c0a235SAndy Whitcroft	}
7588d2c0a235SAndy Whitcroft
7589d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7590d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7591d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
75929624b8d6SJoe Perches		my $newfile = $filename;
75939624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
75943705ce5bSJoe Perches		my $linecount = 0;
75953705ce5bSJoe Perches		my $f;
75963705ce5bSJoe Perches
7597d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7598d752fcc8SJoe Perches
75993705ce5bSJoe Perches		open($f, '>', $newfile)
76003705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
76013705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
76023705ce5bSJoe Perches			$linecount++;
76033705ce5bSJoe Perches			if ($file) {
76043705ce5bSJoe Perches				if ($linecount > 3) {
76053705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
76063705ce5bSJoe Perches					print $f $fixed_line . "\n";
76073705ce5bSJoe Perches				}
76083705ce5bSJoe Perches			} else {
76093705ce5bSJoe Perches				print $f $fixed_line . "\n";
76103705ce5bSJoe Perches			}
76113705ce5bSJoe Perches		}
76123705ce5bSJoe Perches		close($f);
76133705ce5bSJoe Perches
76143705ce5bSJoe Perches		if (!$quiet) {
76153705ce5bSJoe Perches			print << "EOM";
7616d8469f16SJoe Perches
76173705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
76183705ce5bSJoe Perches
76193705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
76203705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
76213705ce5bSJoe Perches
76223705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
76233705ce5bSJoe PerchesNo warranties, expressed or implied...
76243705ce5bSJoe PerchesEOM
76253705ce5bSJoe Perches		}
76263705ce5bSJoe Perches	}
76273705ce5bSJoe Perches
7628d8469f16SJoe Perches	if ($quiet == 0) {
7629d8469f16SJoe Perches		print "\n";
7630d8469f16SJoe Perches		if ($clean == 1) {
7631d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7632d8469f16SJoe Perches		} else {
7633d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
76340a920b5bSAndy Whitcroft		}
76350a920b5bSAndy Whitcroft	}
76360a920b5bSAndy Whitcroft	return $clean;
76370a920b5bSAndy Whitcroft}
7638