xref: /linux-6.15/scripts/checkpatch.pl (revision 2f9dadba)
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
775b2c7334SJim Cromiemy %maybe_linker_symbol; # for externs in c exceptions, when seen in *vmlinux.lds.h
785b2c7334SJim Cromie
7977f5b10aSHannes Edersub help {
8077f5b10aSHannes Eder	my ($exitcode) = @_;
8177f5b10aSHannes Eder
8277f5b10aSHannes Eder	print << "EOM";
8377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
8477f5b10aSHannes EderVersion: $V
8577f5b10aSHannes Eder
8677f5b10aSHannes EderOptions:
8777f5b10aSHannes Eder  -q, --quiet                quiet
8852178ce0SDwaipayan Ray  -v, --verbose              verbose mode
8977f5b10aSHannes Eder  --no-tree                  run without a kernel tree
9077f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
9177f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
9277f5b10aSHannes Eder  --emacs                    emacs compile window format
9377f5b10aSHannes Eder  --terse                    one line per report
9434d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
954a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
964a593c34SDu, Changbin                             single git commit with:
974a593c34SDu, Changbin                               <rev>
984a593c34SDu, Changbin                               <rev>^
994a593c34SDu, Changbin                               <rev>~n
1004a593c34SDu, Changbin                             multiple git commits with:
1014a593c34SDu, Changbin                               <rev1>..<rev2>
1024a593c34SDu, Changbin                               <rev1>...<rev2>
1034a593c34SDu, Changbin                               <rev>-<count>
1044a593c34SDu, Changbin                             git merges are ignored
10577f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
10677f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
1073beb42ecSJoe Perches  --list-types               list the possible message types
10891bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
109000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
1103beb42ecSJoe Perches  --show-types               show the specific message type in the output
111bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
112bdc48fa1SJoe Perches                             if exceeded, warn on patches
113bdc48fa1SJoe Perches                             requires --strict for use with --file
11456193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
115bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
11677f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
11777f5b10aSHannes Eder  --no-summary               suppress the per-file summary
11877f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
11977f5b10aSHannes Eder  --summary-file             include the filename in summary
12077f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
12177f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
12277f5b10aSHannes Eder                             is all off)
12377f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
12477f5b10aSHannes Eder                             literally
1253705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1263705ce5bSJoe Perches                             If correctable single-line errors exist, create
1273705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1283705ce5bSJoe Perches                             with potential errors corrected to the preferred
1293705ce5bSJoe Perches                             checkpatch style
1309624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1319624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1329624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
133d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
134d62a201fSDave Hansen                             runtime errors.
135ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
1360ee3e7b8SPeter Ujfalusi                             (default:$codespellfile)
137ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
13875ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
139737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
140737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
1413e89ad85SJerome Forissier  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default
1423e89ad85SJerome Forissier                             ${CONFIG_})
14377f5b10aSHannes Eder  -h, --help, --version      display this help and exit
14477f5b10aSHannes Eder
14577f5b10aSHannes EderWhen FILE is - read standard input.
14677f5b10aSHannes EderEOM
14777f5b10aSHannes Eder
14877f5b10aSHannes Eder	exit($exitcode);
14977f5b10aSHannes Eder}
15077f5b10aSHannes Eder
1513beb42ecSJoe Perchessub uniq {
1523beb42ecSJoe Perches	my %seen;
1533beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1543beb42ecSJoe Perches}
1553beb42ecSJoe Perches
1563beb42ecSJoe Perchessub list_types {
1573beb42ecSJoe Perches	my ($exitcode) = @_;
1583beb42ecSJoe Perches
1593beb42ecSJoe Perches	my $count = 0;
1603beb42ecSJoe Perches
1613beb42ecSJoe Perches	local $/ = undef;
1623beb42ecSJoe Perches
1633beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1643beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1653beb42ecSJoe Perches
1663beb42ecSJoe Perches	my $text = <$script>;
1673beb42ecSJoe Perches	close($script);
1683beb42ecSJoe Perches
16952178ce0SDwaipayan Ray	my %types = ();
1700547fa58SJean Delvare	# Also catch when type or level is passed through a variable
17152178ce0SDwaipayan Ray	while ($text =~ /(?:(\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
17252178ce0SDwaipayan Ray		if (defined($1)) {
17352178ce0SDwaipayan Ray			if (exists($types{$2})) {
17452178ce0SDwaipayan Ray				$types{$2} .= ",$1" if ($types{$2} ne $1);
17552178ce0SDwaipayan Ray			} else {
17652178ce0SDwaipayan Ray				$types{$2} = $1;
1773beb42ecSJoe Perches			}
17852178ce0SDwaipayan Ray		} else {
17952178ce0SDwaipayan Ray			$types{$2} = "UNDETERMINED";
18052178ce0SDwaipayan Ray		}
18152178ce0SDwaipayan Ray	}
18252178ce0SDwaipayan Ray
1833beb42ecSJoe Perches	print("#\tMessage type\n\n");
18452178ce0SDwaipayan Ray	if ($color) {
18552178ce0SDwaipayan Ray		print(" ( Color coding: ");
18652178ce0SDwaipayan Ray		print(RED . "ERROR" . RESET);
18752178ce0SDwaipayan Ray		print(" | ");
18852178ce0SDwaipayan Ray		print(YELLOW . "WARNING" . RESET);
18952178ce0SDwaipayan Ray		print(" | ");
19052178ce0SDwaipayan Ray		print(GREEN . "CHECK" . RESET);
19152178ce0SDwaipayan Ray		print(" | ");
19252178ce0SDwaipayan Ray		print("Multiple levels / Undetermined");
19352178ce0SDwaipayan Ray		print(" )\n\n");
19452178ce0SDwaipayan Ray	}
19552178ce0SDwaipayan Ray
19652178ce0SDwaipayan Ray	foreach my $type (sort keys %types) {
19752178ce0SDwaipayan Ray		my $orig_type = $type;
19852178ce0SDwaipayan Ray		if ($color) {
19952178ce0SDwaipayan Ray			my $level = $types{$type};
20052178ce0SDwaipayan Ray			if ($level eq "ERROR") {
20152178ce0SDwaipayan Ray				$type = RED . $type . RESET;
20252178ce0SDwaipayan Ray			} elsif ($level eq "WARN") {
20352178ce0SDwaipayan Ray				$type = YELLOW . $type . RESET;
20452178ce0SDwaipayan Ray			} elsif ($level eq "CHK") {
20552178ce0SDwaipayan Ray				$type = GREEN . $type . RESET;
20652178ce0SDwaipayan Ray			}
20752178ce0SDwaipayan Ray		}
2083beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
20952178ce0SDwaipayan Ray		if ($verbose && exists($verbose_messages{$orig_type})) {
21052178ce0SDwaipayan Ray			my $message = $verbose_messages{$orig_type};
21152178ce0SDwaipayan Ray			$message =~ s/\n/\n\t/g;
21252178ce0SDwaipayan Ray			print("\t" . $message . "\n\n");
21352178ce0SDwaipayan Ray		}
2143beb42ecSJoe Perches	}
2153beb42ecSJoe Perches
2163beb42ecSJoe Perches	exit($exitcode);
2173beb42ecSJoe Perches}
2183beb42ecSJoe Perches
219000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
220000d1cc1SJoe Perchesif (-f $conf) {
221000d1cc1SJoe Perches	my @conf_args;
222000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
223000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
224000d1cc1SJoe Perches
225000d1cc1SJoe Perches	while (<$conffile>) {
226000d1cc1SJoe Perches		my $line = $_;
227000d1cc1SJoe Perches
228000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
229000d1cc1SJoe Perches		$line =~ s/^\s*//g;
230000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
231000d1cc1SJoe Perches
232000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
233000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
234000d1cc1SJoe Perches
235000d1cc1SJoe Perches		my @words = split(" ", $line);
236000d1cc1SJoe Perches		foreach my $word (@words) {
237000d1cc1SJoe Perches			last if ($word =~ m/^#/);
238000d1cc1SJoe Perches			push (@conf_args, $word);
239000d1cc1SJoe Perches		}
240000d1cc1SJoe Perches	}
241000d1cc1SJoe Perches	close($conffile);
242000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
243000d1cc1SJoe Perches}
244000d1cc1SJoe Perches
24552178ce0SDwaipayan Raysub load_docs {
24652178ce0SDwaipayan Ray	open(my $docs, '<', "$docsfile")
24752178ce0SDwaipayan Ray	    or warn "$P: Can't read the documentation file $docsfile $!\n";
24852178ce0SDwaipayan Ray
24952178ce0SDwaipayan Ray	my $type = '';
25052178ce0SDwaipayan Ray	my $desc = '';
25152178ce0SDwaipayan Ray	my $in_desc = 0;
25252178ce0SDwaipayan Ray
25352178ce0SDwaipayan Ray	while (<$docs>) {
25452178ce0SDwaipayan Ray		chomp;
25552178ce0SDwaipayan Ray		my $line = $_;
25652178ce0SDwaipayan Ray		$line =~ s/\s+$//;
25752178ce0SDwaipayan Ray
25852178ce0SDwaipayan Ray		if ($line =~ /^\s*\*\*(.+)\*\*$/) {
25952178ce0SDwaipayan Ray			if ($desc ne '') {
26052178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
26152178ce0SDwaipayan Ray			}
26252178ce0SDwaipayan Ray			$type = $1;
26352178ce0SDwaipayan Ray			$desc = '';
26452178ce0SDwaipayan Ray			$in_desc = 1;
26552178ce0SDwaipayan Ray		} elsif ($in_desc) {
26652178ce0SDwaipayan Ray			if ($line =~ /^(?:\s{4,}|$)/) {
26752178ce0SDwaipayan Ray				$line =~ s/^\s{4}//;
26852178ce0SDwaipayan Ray				$desc .= $line;
26952178ce0SDwaipayan Ray				$desc .= "\n";
27052178ce0SDwaipayan Ray			} else {
27152178ce0SDwaipayan Ray				$verbose_messages{$type} = trim($desc);
27252178ce0SDwaipayan Ray				$type = '';
27352178ce0SDwaipayan Ray				$desc = '';
27452178ce0SDwaipayan Ray				$in_desc = 0;
27552178ce0SDwaipayan Ray			}
27652178ce0SDwaipayan Ray		}
27752178ce0SDwaipayan Ray	}
27852178ce0SDwaipayan Ray
27952178ce0SDwaipayan Ray	if ($desc ne '') {
28052178ce0SDwaipayan Ray		$verbose_messages{$type} = trim($desc);
28152178ce0SDwaipayan Ray	}
28252178ce0SDwaipayan Ray	close($docs);
28352178ce0SDwaipayan Ray}
28452178ce0SDwaipayan Ray
285737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
286737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
287737c0767SJohn Brooksforeach (@ARGV) {
288737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
289737c0767SJohn Brooks		$_ = "--color=$color";
290737c0767SJohn Brooks	}
291737c0767SJohn Brooks}
292737c0767SJohn Brooks
2930a920b5bSAndy WhitcroftGetOptions(
2946c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
29552178ce0SDwaipayan Ray	'v|verbose!'	=> \$verbose,
2960a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2970a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2980a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2996c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
3008905a67cSAndy Whitcroft	'terse!'	=> \$terse,
30134d8815fSJoe Perches	'showfile!'	=> \$showfile,
30277f5b10aSHannes Eder	'f|file!'	=> \$file,
3034a593c34SDu, Changbin	'g|git!'	=> \$git,
3046c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
3056c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
306000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
30791bfe484SJoe Perches	'types=s'	=> \@use,
308000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
3093beb42ecSJoe Perches	'list-types!'	=> \$list_types,
3106cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
31156193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
312713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
3136c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
3148905a67cSAndy Whitcroft	'summary!'	=> \$summary,
3158905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
31613214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
3173705ce5bSJoe Perches	'fix!'		=> \$fix,
3189624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
319d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
320c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
321773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
322ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
3230ee3e7b8SPeter Ujfalusi	'codespellfile=s'	=> \$user_codespellfile,
32475ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
325737c0767SJohn Brooks	'color=s'	=> \$color,
326737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
327737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
3283e89ad85SJerome Forissier	'kconfig-prefix=s'	=> \${CONFIG_},
32977f5b10aSHannes Eder	'h|help'	=> \$help,
33077f5b10aSHannes Eder	'version'	=> \$help
3310ee3e7b8SPeter Ujfalusi) or $help = 2;
33277f5b10aSHannes Eder
3330ee3e7b8SPeter Ujfalusiif ($user_codespellfile) {
3340ee3e7b8SPeter Ujfalusi	# Use the user provided codespell file unconditionally
3350ee3e7b8SPeter Ujfalusi	$codespellfile = $user_codespellfile;
3360ee3e7b8SPeter Ujfalusi} elsif (!(-f $codespellfile)) {
3370ee3e7b8SPeter Ujfalusi	# If /usr/share/codespell/dictionary.txt is not present, try to find it
3380ee3e7b8SPeter Ujfalusi	# under codespell's install directory: <codespell_root>/data/dictionary.txt
339c882c6b1SSagar Patel	if (($codespell || $help) && which("python3") ne "") {
3400ee3e7b8SPeter Ujfalusi		my $python_codespell_dict = << "EOF";
3410ee3e7b8SPeter Ujfalusi
3420ee3e7b8SPeter Ujfalusiimport os.path as op
3430ee3e7b8SPeter Ujfalusiimport codespell_lib
3440ee3e7b8SPeter Ujfalusicodespell_dir = op.dirname(codespell_lib.__file__)
3450ee3e7b8SPeter Ujfalusicodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')
3460ee3e7b8SPeter Ujfalusiprint(codespell_file, end='')
3470ee3e7b8SPeter UjfalusiEOF
3480ee3e7b8SPeter Ujfalusi
349c882c6b1SSagar Patel		my $codespell_dict = `python3 -c "$python_codespell_dict" 2> /dev/null`;
3500ee3e7b8SPeter Ujfalusi		$codespellfile = $codespell_dict if (-f $codespell_dict);
3510ee3e7b8SPeter Ujfalusi	}
3520ee3e7b8SPeter Ujfalusi}
3530ee3e7b8SPeter Ujfalusi
3540ee3e7b8SPeter Ujfalusi# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0
3550ee3e7b8SPeter Ujfalusi# $help is 2 if invalid option is passed - exitcode: 1
3560ee3e7b8SPeter Ujfalusihelp($help - 1) if ($help);
3570a920b5bSAndy Whitcroft
35852178ce0SDwaipayan Raydie "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix));
35952178ce0SDwaipayan Raydie "$P: --verbose cannot be used with --terse\n" if ($verbose && $terse);
36052178ce0SDwaipayan Ray
36152178ce0SDwaipayan Rayif ($color =~ /^[01]$/) {
36252178ce0SDwaipayan Ray	$color = !$color;
36352178ce0SDwaipayan Ray} elsif ($color =~ /^always$/i) {
36452178ce0SDwaipayan Ray	$color = 1;
36552178ce0SDwaipayan Ray} elsif ($color =~ /^never$/i) {
36652178ce0SDwaipayan Ray	$color = 0;
36752178ce0SDwaipayan Ray} elsif ($color =~ /^auto$/i) {
36852178ce0SDwaipayan Ray	$color = (-t STDOUT);
36952178ce0SDwaipayan Ray} else {
37052178ce0SDwaipayan Ray	die "$P: Invalid color mode: $color\n";
37152178ce0SDwaipayan Ray}
37252178ce0SDwaipayan Ray
37352178ce0SDwaipayan Rayload_docs() if ($verbose);
3743beb42ecSJoe Percheslist_types(0) if ($list_types);
3753beb42ecSJoe Perches
3769624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
3772ac73b4fSJoe Perches$check_orig = $check;
3789624b8d6SJoe Perches
3790a920b5bSAndy Whitcroftmy $exit = 0;
3800a920b5bSAndy Whitcroft
3815b57980dSJoe Perchesmy $perl_version_ok = 1;
382d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
3835b57980dSJoe Perches	$perl_version_ok = 0;
384d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
3855b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
386d62a201fSDave Hansen}
387d62a201fSDave Hansen
38845107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
3890a920b5bSAndy Whitcroftif ($#ARGV < 0) {
39045107ff6SAllen Hubbe	push(@ARGV, '-');
3910a920b5bSAndy Whitcroft}
3920a920b5bSAndy Whitcroft
393713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
39432f30ca9SJoe Perchesdie "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2);
395713a09deSAntonio Borneo
39691bfe484SJoe Perchessub hash_save_array_words {
39791bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
39891bfe484SJoe Perches
39991bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
40091bfe484SJoe Perches	foreach my $word (@array) {
401000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
402000d1cc1SJoe Perches		$word =~ s/^\s*//g;
403000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
404000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
405000d1cc1SJoe Perches
406000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
407000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
408000d1cc1SJoe Perches
40991bfe484SJoe Perches		$hashRef->{$word}++;
410000d1cc1SJoe Perches	}
41191bfe484SJoe Perches}
41291bfe484SJoe Perches
41391bfe484SJoe Perchessub hash_show_words {
41491bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
41591bfe484SJoe Perches
4163c816e49SJoe Perches	if (keys %$hashRef) {
417d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
41858cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
41991bfe484SJoe Perches			print " $word";
42091bfe484SJoe Perches		}
421d8469f16SJoe Perches		print "\n";
42291bfe484SJoe Perches	}
42391bfe484SJoe Perches}
42491bfe484SJoe Perches
42591bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
42691bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
427000d1cc1SJoe Perches
428c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
429c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
4307429c690SAndy Whitcroftmy $dbg_type = 0;
431a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
432c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
43321caa13cSAndy Whitcroft	## no critic
43421caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
43521caa13cSAndy Whitcroft	die "$@" if ($@);
436c2fdda0dSAndy Whitcroft}
437c2fdda0dSAndy Whitcroft
438d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
439d2c0a235SAndy Whitcroft
4408905a67cSAndy Whitcroftif ($terse) {
4418905a67cSAndy Whitcroft	$emacs = 1;
4428905a67cSAndy Whitcroft	$quiet++;
4438905a67cSAndy Whitcroft}
4448905a67cSAndy Whitcroft
4456c72ffaaSAndy Whitcroftif ($tree) {
4466c72ffaaSAndy Whitcroft	if (defined $root) {
4476c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
4486c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
4496c72ffaaSAndy Whitcroft		}
4506c72ffaaSAndy Whitcroft	} else {
4516c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
4526c72ffaaSAndy Whitcroft			$root = '.';
4536c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
4546c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
4556c72ffaaSAndy Whitcroft			$root = $1;
4566c72ffaaSAndy Whitcroft		}
4576c72ffaaSAndy Whitcroft	}
4586c72ffaaSAndy Whitcroft
4596c72ffaaSAndy Whitcroft	if (!defined $root) {
4600a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
4610a920b5bSAndy Whitcroft		exit(2);
4620a920b5bSAndy Whitcroft	}
4636c72ffaaSAndy Whitcroft}
4646c72ffaaSAndy Whitcroft
4656c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
4666c72ffaaSAndy Whitcroft
4672ceb532bSAndy Whitcroftour $Ident	= qr{
4682ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
4692ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
4702ceb532bSAndy Whitcroft		}x;
4716c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
4726c72ffaaSAndy Whitcroftour $Sparse	= qr{
4736c72ffaaSAndy Whitcroft			__user|
4746c72ffaaSAndy Whitcroft			__kernel|
4756c72ffaaSAndy Whitcroft			__force|
4766c72ffaaSAndy Whitcroft			__iomem|
4776c72ffaaSAndy Whitcroft			__must_check|
478417495edSAndy Whitcroft			__kprobes|
479165e72a6SSven Eckelmann			__ref|
48033aa4597SGeert Uytterhoeven			__refconst|
48133aa4597SGeert Uytterhoeven			__refdata|
482ad315455SBoqun Feng			__rcu|
483ad315455SBoqun Feng			__private
4846c72ffaaSAndy Whitcroft		}x;
485e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
486e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
487e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
488e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
489e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
4908716de38SJoe Perches
49152131292SWolfram Sang# Notes to $Attribute:
49252131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
4936c72ffaaSAndy Whitcroftour $Attribute	= qr{
4946c72ffaaSAndy Whitcroft			const|
495b5e8736aSJoe Perches			volatile|
49603f1df7dSJoe Perches			__percpu|
49703f1df7dSJoe Perches			__nocast|
49803f1df7dSJoe Perches			__safe|
49946d832f5SMichael S. Tsirkin			__bitwise|
50003f1df7dSJoe Perches			__packed__|
50103f1df7dSJoe Perches			__packed2__|
50203f1df7dSJoe Perches			__naked|
50303f1df7dSJoe Perches			__maybe_unused|
50403f1df7dSJoe Perches			__always_unused|
50503f1df7dSJoe Perches			__noreturn|
50603f1df7dSJoe Perches			__used|
50703f1df7dSJoe Perches			__cold|
508e23ef1f3SJoe Perches			__pure|
50903f1df7dSJoe Perches			__noclone|
51003f1df7dSJoe Perches			__deprecated|
5116c72ffaaSAndy Whitcroft			__read_mostly|
512c5967e98SJoe Perches			__ro_after_init|
5136c72ffaaSAndy Whitcroft			__kprobes|
5148716de38SJoe Perches			$InitAttribute|
515*2f9dadbaSMarcelo Schmitt			__aligned\s*\(.*\)|
51624e1d81aSAndy Whitcroft			____cacheline_aligned|
51724e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
5185fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
51986cffecdSKees Cook			__weak|
52086cffecdSKees Cook			__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\)
5216c72ffaaSAndy Whitcroft		  }x;
522c45dcabdSAndy Whitcroftour $Modifier;
52391cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
5246c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
5256c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
5266c72ffaaSAndy Whitcroft
52795e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
52895e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
52995e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
53095e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
5312435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
532d2af5aa6SJoe Perchesour $String	= qr{(?:\b[Lu])?"[X\t]*"};
533326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
534326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
535326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
53674349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
5372435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
538326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
539447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
54023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
5416c72ffaaSAndy Whitcroftour $Operators	= qr{
5426c72ffaaSAndy Whitcroft			<=|>=|==|!=|
5436c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
54423f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
5456c72ffaaSAndy Whitcroft		  }x;
5466c72ffaaSAndy Whitcroft
54791cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
54891cb5195SJoe Perches
549ab7e23f3SJoe Perchesour $BasicType;
5508905a67cSAndy Whitcroftour $NonptrType;
5511813087dSJoe Perchesour $NonptrTypeMisordered;
5528716de38SJoe Perchesour $NonptrTypeWithAttr;
5538905a67cSAndy Whitcroftour $Type;
5541813087dSJoe Perchesour $TypeMisordered;
5558905a67cSAndy Whitcroftour $Declare;
5561813087dSJoe Perchesour $DeclareMisordered;
5578905a67cSAndy Whitcroft
55815662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
55915662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
560171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
561171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
562171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
563171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
564171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
565171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
566171ae1a4SAndy Whitcroft}x;
567171ae1a4SAndy Whitcroft
56815662b3eSJoe Perchesour $UTF8	= qr{
56915662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
57015662b3eSJoe Perches	| $NON_ASCII_UTF8
57115662b3eSJoe Perches}x;
57215662b3eSJoe Perches
573e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
574021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
575021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
576021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
577021158b4SJoe Perches)};
578e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
579fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
5808ed22cadSAndy Whitcroft	atomic_t
5818ed22cadSAndy Whitcroft)};
5828ea0114eSMickaël Salaünour $typeStdioTypedefs = qr{(?x:
5838ea0114eSMickaël Salaün	FILE
5848ea0114eSMickaël Salaün)};
585e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
586e6176fa4SJoe Perches	$typeC99Typedefs\b|
587e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
5888ea0114eSMickaël Salaün	$typeKernelTypedefs\b|
5898ea0114eSMickaël Salaün	$typeStdioTypedefs\b
590e6176fa4SJoe Perches)};
5918ed22cadSAndy Whitcroft
5926d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
5936d32f7a3SJoe Perches
594691e669bSJoe Perchesour $logFunctions = qr{(?x:
595758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
5967d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
59787bd499aSJoe Perches	TP_printk|
5986e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
599b0531722SJoe Perches	panic|
60006668727SJoe Perches	MODULE_[A-Z_]+|
60106668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
602691e669bSJoe Perches)};
603691e669bSJoe Perches
604e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
605e29a70f1SJoe Perches	(?:(?:devm_)?
60658f02267SJoe Perches		(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |
607e29a70f1SJoe Perches		kstrdup(?:_const)? |
608e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
609461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
610e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
611e29a70f1SJoe Perches	dma_alloc_coherent
612e29a70f1SJoe Perches)};
613e29a70f1SJoe Perches
61420112475SJoe Perchesour $signature_tags = qr{(?xi:
61520112475SJoe Perches	Signed-off-by:|
616d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
61720112475SJoe Perches	Acked-by:|
61820112475SJoe Perches	Tested-by:|
61920112475SJoe Perches	Reviewed-by:|
62020112475SJoe Perches	Reported-by:|
6218543ae12SMugunthan V N	Suggested-by:|
62220112475SJoe Perches	To:|
62320112475SJoe Perches	Cc:
62420112475SJoe Perches)};
62520112475SJoe Perches
62644c31888SMatthieu Baertsour @link_tags = qw(Link Closes);
627f94e40eaSMatthieu Baerts
628f94e40eaSMatthieu Baerts#Create a search and print patterns for all these strings to be used directly below
629f94e40eaSMatthieu Baertsour $link_tags_search = "";
630f94e40eaSMatthieu Baertsour $link_tags_print = "";
631f94e40eaSMatthieu Baertsforeach my $entry (@link_tags) {
632f94e40eaSMatthieu Baerts	if ($link_tags_search ne "") {
633f94e40eaSMatthieu Baerts		$link_tags_search .= '|';
634f94e40eaSMatthieu Baerts		$link_tags_print .= ' or ';
635f94e40eaSMatthieu Baerts	}
636f94e40eaSMatthieu Baerts	$entry .= ':';
637f94e40eaSMatthieu Baerts	$link_tags_search .= $entry;
638f94e40eaSMatthieu Baerts	$link_tags_print .= "'$entry'";
639f94e40eaSMatthieu Baerts}
640f94e40eaSMatthieu Baerts$link_tags_search = "(?:${link_tags_search})";
641f94e40eaSMatthieu Baerts
642adb2da82SJoe Perchesour $tracing_logging_tags = qr{(?xi:
643adb2da82SJoe Perches	[=-]*> |
644adb2da82SJoe Perches	<[=-]* |
645adb2da82SJoe Perches	\[ |
646adb2da82SJoe Perches	\] |
647adb2da82SJoe Perches	start |
648adb2da82SJoe Perches	called |
649adb2da82SJoe Perches	entered |
650adb2da82SJoe Perches	entry |
651adb2da82SJoe Perches	enter |
652adb2da82SJoe Perches	in |
653adb2da82SJoe Perches	inside |
654adb2da82SJoe Perches	here |
655adb2da82SJoe Perches	begin |
656adb2da82SJoe Perches	exit |
657adb2da82SJoe Perches	end |
658adb2da82SJoe Perches	done |
659adb2da82SJoe Perches	leave |
660adb2da82SJoe Perches	completed |
661adb2da82SJoe Perches	out |
662adb2da82SJoe Perches	return |
663adb2da82SJoe Perches	[\.\!:\s]*
664adb2da82SJoe Perches)};
665adb2da82SJoe Perches
666831242abSAditya Srivastavasub edit_distance_min {
667831242abSAditya Srivastava	my (@arr) = @_;
668831242abSAditya Srivastava	my $len = scalar @arr;
669831242abSAditya Srivastava	if ((scalar @arr) < 1) {
670831242abSAditya Srivastava		# if underflow, return
671831242abSAditya Srivastava		return;
672831242abSAditya Srivastava	}
673831242abSAditya Srivastava	my $min = $arr[0];
674831242abSAditya Srivastava	for my $i (0 .. ($len-1)) {
675831242abSAditya Srivastava		if ($arr[$i] < $min) {
676831242abSAditya Srivastava			$min = $arr[$i];
677831242abSAditya Srivastava		}
678831242abSAditya Srivastava	}
679831242abSAditya Srivastava	return $min;
680831242abSAditya Srivastava}
681831242abSAditya Srivastava
682831242abSAditya Srivastavasub get_edit_distance {
683831242abSAditya Srivastava	my ($str1, $str2) = @_;
684831242abSAditya Srivastava	$str1 = lc($str1);
685831242abSAditya Srivastava	$str2 = lc($str2);
686831242abSAditya Srivastava	$str1 =~ s/-//g;
687831242abSAditya Srivastava	$str2 =~ s/-//g;
688831242abSAditya Srivastava	my $len1 = length($str1);
689831242abSAditya Srivastava	my $len2 = length($str2);
690831242abSAditya Srivastava	# two dimensional array storing minimum edit distance
691831242abSAditya Srivastava	my @distance;
692831242abSAditya Srivastava	for my $i (0 .. $len1) {
693831242abSAditya Srivastava		for my $j (0 .. $len2) {
694831242abSAditya Srivastava			if ($i == 0) {
695831242abSAditya Srivastava				$distance[$i][$j] = $j;
696831242abSAditya Srivastava			} elsif ($j == 0) {
697831242abSAditya Srivastava				$distance[$i][$j] = $i;
698831242abSAditya Srivastava			} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {
699831242abSAditya Srivastava				$distance[$i][$j] = $distance[$i - 1][$j - 1];
700831242abSAditya Srivastava			} else {
701831242abSAditya Srivastava				my $dist1 = $distance[$i][$j - 1]; #insert distance
702831242abSAditya Srivastava				my $dist2 = $distance[$i - 1][$j]; # remove
703831242abSAditya Srivastava				my $dist3 = $distance[$i - 1][$j - 1]; #replace
704831242abSAditya Srivastava				$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);
705831242abSAditya Srivastava			}
706831242abSAditya Srivastava		}
707831242abSAditya Srivastava	}
708831242abSAditya Srivastava	return $distance[$len1][$len2];
709831242abSAditya Srivastava}
710831242abSAditya Srivastava
711831242abSAditya Srivastavasub find_standard_signature {
712831242abSAditya Srivastava	my ($sign_off) = @_;
713831242abSAditya Srivastava	my @standard_signature_tags = (
714831242abSAditya Srivastava		'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',
715831242abSAditya Srivastava		'Reviewed-by:', 'Reported-by:', 'Suggested-by:'
716831242abSAditya Srivastava	);
717831242abSAditya Srivastava	foreach my $signature (@standard_signature_tags) {
718831242abSAditya Srivastava		return $signature if (get_edit_distance($sign_off, $signature) <= 2);
719831242abSAditya Srivastava	}
720831242abSAditya Srivastava
721831242abSAditya Srivastava	return "";
722831242abSAditya Srivastava}
723831242abSAditya Srivastava
7249b71f79fSBjorn Helgaasour $obsolete_archives = qr{(?xi:
7259b71f79fSBjorn Helgaas	\Qfreedesktop.org/archives/dri-devel\E |
7269b71f79fSBjorn Helgaas	\Qlists.infradead.org\E |
7279b71f79fSBjorn Helgaas	\Qlkml.org\E |
7289b71f79fSBjorn Helgaas	\Qmail-archive.com\E |
7299b71f79fSBjorn Helgaas	\Qmailman.alsa-project.org/pipermail\E |
7309b71f79fSBjorn Helgaas	\Qmarc.info\E |
7319b71f79fSBjorn Helgaas	\Qozlabs.org/pipermail\E |
7329b71f79fSBjorn Helgaas	\Qspinics.net\E
7339b71f79fSBjorn Helgaas)};
7349b71f79fSBjorn Helgaas
7351813087dSJoe Perchesour @typeListMisordered = (
7361813087dSJoe Perches	qr{char\s+(?:un)?signed},
7371813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
7381813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
7391813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
7401813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
7411813087dSJoe Perches	qr{short\s+(?:un)?signed},
7421813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
7431813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
7441813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
7451813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
7461813087dSJoe Perches	qr{int\s+(?:un)?signed},
7471813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
7481813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
7491813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
7501813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
7511813087dSJoe Perches	qr{long\s+(?:un)?signed},
7521813087dSJoe Perches);
7531813087dSJoe Perches
7548905a67cSAndy Whitcroftour @typeList = (
7558905a67cSAndy Whitcroft	qr{void},
7560c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
7570c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
7580c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
7590c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
7600c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
7610c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
7620c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
7630c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
7640c773d9dSJoe Perches	qr{(?:un)?signed},
7658905a67cSAndy Whitcroft	qr{float},
7668905a67cSAndy Whitcroft	qr{double},
7678905a67cSAndy Whitcroft	qr{bool},
7688905a67cSAndy Whitcroft	qr{struct\s+$Ident},
7698905a67cSAndy Whitcroft	qr{union\s+$Ident},
7708905a67cSAndy Whitcroft	qr{enum\s+$Ident},
7718905a67cSAndy Whitcroft	qr{${Ident}_t},
7728905a67cSAndy Whitcroft	qr{${Ident}_handler},
7738905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
7741813087dSJoe Perches	@typeListMisordered,
7758905a67cSAndy Whitcroft);
776938224b5SJoe Perches
777938224b5SJoe Perchesour $C90_int_types = qr{(?x:
778938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
779938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
780938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
781938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
782938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
783938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
784938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
785938224b5SJoe Perches
786938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
787938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
788938224b5SJoe Perches	long\s+(?:un)?signed|
789938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
790938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
791938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
792938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
793938224b5SJoe Perches
794938224b5SJoe Perches	int\s+(?:un)?signed|
795938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
796938224b5SJoe Perches)};
797938224b5SJoe Perches
798485ff23eSAlex Dowadour @typeListFile = ();
7998716de38SJoe Perchesour @typeListWithAttr = (
8008716de38SJoe Perches	@typeList,
8018716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
8028716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
8038716de38SJoe Perches);
8048716de38SJoe Perches
805c45dcabdSAndy Whitcroftour @modifierList = (
806c45dcabdSAndy Whitcroft	qr{fastcall},
807c45dcabdSAndy Whitcroft);
808485ff23eSAlex Dowadour @modifierListFile = ();
8098905a67cSAndy Whitcroft
8102435880fSJoe Perchesour @mode_permission_funcs = (
8112435880fSJoe Perches	["module_param", 3],
8122435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
8132435880fSJoe Perches	["module_param_array_named", 5],
8142435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
8152435880fSJoe Perches	["proc_create(?:_data|)", 2],
816459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
817459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
818459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
819459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
820459cf0aeSJoe Perches	["__ATTR", 2],
8212435880fSJoe Perches);
8222435880fSJoe Perches
8231a3dcf2eSJoe Perchesmy $word_pattern = '\b[A-Z]?[a-z]{2,}\b';
8241a3dcf2eSJoe Perches
825515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
826515a235eSJoe Perchesour $mode_perms_search = "";
827515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
828515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
829515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
830515a235eSJoe Perches}
83100180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
832515a235eSJoe Perches
8339189c7e7SJoe Perchesour %deprecated_apis = (
8349189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
8359189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
8369189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
8379189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
8389189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
8399189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
8409189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
8419189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
8429189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
8439189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
844defdaff1SIra Weiny	"kmap"					=> "kmap_local_page",
845a3ea42ffSIra Weiny	"kunmap"				=> "kunmap_local",
846defdaff1SIra Weiny	"kmap_atomic"				=> "kmap_local_page",
847a3ea42ffSIra Weiny	"kunmap_atomic"				=> "kunmap_local",
8489189c7e7SJoe Perches);
8499189c7e7SJoe Perches
8509189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
8519189c7e7SJoe Perchesour $deprecated_apis_search = "";
8529189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
8539189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
8549189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
8559189c7e7SJoe Perches}
8569189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
8579189c7e7SJoe Perches
858b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
859b392c64fSJoe Perches	S_IWUGO		|
860b392c64fSJoe Perches	S_IWOTH		|
861b392c64fSJoe Perches	S_IRWXUGO	|
862b392c64fSJoe Perches	S_IALLUGO	|
863b392c64fSJoe Perches	0[0-7][0-7][2367]
864b392c64fSJoe Perches}x;
865b392c64fSJoe Perches
866f90774e1SJoe Perchesour %mode_permission_string_types = (
867f90774e1SJoe Perches	"S_IRWXU" => 0700,
868f90774e1SJoe Perches	"S_IRUSR" => 0400,
869f90774e1SJoe Perches	"S_IWUSR" => 0200,
870f90774e1SJoe Perches	"S_IXUSR" => 0100,
871f90774e1SJoe Perches	"S_IRWXG" => 0070,
872f90774e1SJoe Perches	"S_IRGRP" => 0040,
873f90774e1SJoe Perches	"S_IWGRP" => 0020,
874f90774e1SJoe Perches	"S_IXGRP" => 0010,
875f90774e1SJoe Perches	"S_IRWXO" => 0007,
876f90774e1SJoe Perches	"S_IROTH" => 0004,
877f90774e1SJoe Perches	"S_IWOTH" => 0002,
878f90774e1SJoe Perches	"S_IXOTH" => 0001,
879f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
880f90774e1SJoe Perches	"S_IRUGO" => 0444,
881f90774e1SJoe Perches	"S_IWUGO" => 0222,
882f90774e1SJoe Perches	"S_IXUGO" => 0111,
883f90774e1SJoe Perches);
884f90774e1SJoe Perches
885f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
886f90774e1SJoe Perchesour $mode_perms_string_search = "";
887f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
888f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
889f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
890f90774e1SJoe Perches}
89100180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
89200180468SJoe Perchesour $multi_mode_perms_string_search = qr{
89300180468SJoe Perches	${single_mode_perms_string_search}
89400180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
89500180468SJoe Perches}x;
89600180468SJoe Perches
89700180468SJoe Perchessub perms_to_octal {
89800180468SJoe Perches	my ($string) = @_;
89900180468SJoe Perches
90000180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
90100180468SJoe Perches
90200180468SJoe Perches	my $val = "";
90300180468SJoe Perches	my $oval = "";
90400180468SJoe Perches	my $to = 0;
90500180468SJoe Perches	my $curpos = 0;
90600180468SJoe Perches	my $lastpos = 0;
90700180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
90800180468SJoe Perches		$curpos = pos($string);
90900180468SJoe Perches		my $match = $2;
91000180468SJoe Perches		my $omatch = $1;
91100180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
91200180468SJoe Perches		$lastpos = $curpos;
91300180468SJoe Perches		$to |= $mode_permission_string_types{$match};
91400180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
91500180468SJoe Perches		$val .= $match;
91600180468SJoe Perches		$oval .= $omatch;
91700180468SJoe Perches	}
91800180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
91900180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
92000180468SJoe Perches	return sprintf("%04o", $to);
92100180468SJoe Perches}
922f90774e1SJoe Perches
9237840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
9247840a94cSWolfram Sang	irq|
925cdcee686SSergey Ryazanov	memory|
926cdcee686SSergey Ryazanov	time|
927cdcee686SSergey Ryazanov	reboot
9287840a94cSWolfram Sang)};
9297840a94cSWolfram Sang# memory.h: ARM has a custom one
9307840a94cSWolfram Sang
93166b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
93266b47b4aSKees Cookmy $misspellings;
93366b47b4aSKees Cookmy %spelling_fix;
93436061e38SJoe Perches
93536061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
93666b47b4aSKees Cook	while (<$spelling>) {
93766b47b4aSKees Cook		my $line = $_;
93866b47b4aSKees Cook
93966b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
94066b47b4aSKees Cook		$line =~ s/^\s*//g;
94166b47b4aSKees Cook
94266b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
94366b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
94466b47b4aSKees Cook
94566b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
94666b47b4aSKees Cook
94766b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
94866b47b4aSKees Cook	}
94966b47b4aSKees Cook	close($spelling);
95036061e38SJoe Perches} else {
95136061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
95236061e38SJoe Perches}
95366b47b4aSKees Cook
954ebfd7d62SJoe Perchesif ($codespell) {
955ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
956ebfd7d62SJoe Perches		while (<$spelling>) {
957ebfd7d62SJoe Perches			my $line = $_;
958ebfd7d62SJoe Perches
959ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
960ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
961ebfd7d62SJoe Perches
962ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
963ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
964ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
965ebfd7d62SJoe Perches
966ebfd7d62SJoe Perches			$line =~ s/,.*$//;
967ebfd7d62SJoe Perches
968ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
969ebfd7d62SJoe Perches
970ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
971ebfd7d62SJoe Perches		}
972ebfd7d62SJoe Perches		close($spelling);
973ebfd7d62SJoe Perches	} else {
974ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
975ebfd7d62SJoe Perches	}
976ebfd7d62SJoe Perches}
977ebfd7d62SJoe Perches
978ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
979ebfd7d62SJoe Perches
98075ad8c57SJerome Forissiersub read_words {
98175ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
98275ad8c57SJerome Forissier
98375ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
98475ad8c57SJerome Forissier		while (<$words>) {
985bf1fa1daSJoe Perches			my $line = $_;
986bf1fa1daSJoe Perches
987bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
988bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
989bf1fa1daSJoe Perches
990bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
991bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
992bf1fa1daSJoe Perches			if ($line =~ /\s/) {
99375ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
994bf1fa1daSJoe Perches				next;
995bf1fa1daSJoe Perches			}
996bf1fa1daSJoe Perches
997ced69da1SQuentin Monnet			$$wordsRef .= '|' if (defined $$wordsRef);
99875ad8c57SJerome Forissier			$$wordsRef .= $line;
999bf1fa1daSJoe Perches		}
100075ad8c57SJerome Forissier		close($file);
100175ad8c57SJerome Forissier		return 1;
1002bf1fa1daSJoe Perches	}
1003bf1fa1daSJoe Perches
100475ad8c57SJerome Forissier	return 0;
100575ad8c57SJerome Forissier}
100675ad8c57SJerome Forissier
1007ced69da1SQuentin Monnetmy $const_structs;
1008ced69da1SQuentin Monnetif (show_type("CONST_STRUCT")) {
100975ad8c57SJerome Forissier	read_words(\$const_structs, $conststructsfile)
101075ad8c57SJerome Forissier	    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
1011ced69da1SQuentin Monnet}
101275ad8c57SJerome Forissier
1013ced69da1SQuentin Monnetif (defined($typedefsfile)) {
1014ced69da1SQuentin Monnet	my $typeOtherTypedefs;
101575ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
101675ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
1017ced69da1SQuentin Monnet	$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);
101875ad8c57SJerome Forissier}
101975ad8c57SJerome Forissier
10208905a67cSAndy Whitcroftsub build_types {
1021485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
1022485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
10231813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
10248716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
1025c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
1026ab7e23f3SJoe Perches	$BasicType	= qr{
1027ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
1028ab7e23f3SJoe Perches				(?:${all}\b)
1029ab7e23f3SJoe Perches		}x;
10308905a67cSAndy Whitcroft	$NonptrType	= qr{
1031d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
1032cf655043SAndy Whitcroft			(?:
10336b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
10348ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
1035c45dcabdSAndy Whitcroft				(?:${all}\b)
1036cf655043SAndy Whitcroft			)
1037c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
10388905a67cSAndy Whitcroft		  }x;
10391813087dSJoe Perches	$NonptrTypeMisordered	= qr{
10401813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
10411813087dSJoe Perches			(?:
10421813087dSJoe Perches				(?:${Misordered}\b)
10431813087dSJoe Perches			)
10441813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
10451813087dSJoe Perches		  }x;
10468716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
10478716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
10488716de38SJoe Perches			(?:
10498716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
10508716de38SJoe Perches				(?:$typeTypedefs\b)|
10518716de38SJoe Perches				(?:${allWithAttr}\b)
10528716de38SJoe Perches			)
10538716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
10548716de38SJoe Perches		  }x;
10558905a67cSAndy Whitcroft	$Type	= qr{
1056c45dcabdSAndy Whitcroft			$NonptrType
10577b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
1058c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
10598905a67cSAndy Whitcroft		  }x;
10601813087dSJoe Perches	$TypeMisordered	= qr{
10611813087dSJoe Perches			$NonptrTypeMisordered
10627b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
10631813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
10641813087dSJoe Perches		  }x;
106591cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
10661813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
10678905a67cSAndy Whitcroft}
10688905a67cSAndy Whitcroftbuild_types();
10696c72ffaaSAndy Whitcroft
10707d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
1071d1fe9c09SJoe Perches
1072d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
1073d1fe9c09SJoe Perches# requires at least perl version v5.10.0
1074d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
1075d1fe9c09SJoe Perches
1076d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
10772435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
1078c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
10797d2367afSJoe Perches
1080f8422308SJoe Perchesour $declaration_macros = qr{(?x:
10813e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
1082fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
1083dcea7964SJoe Perches	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(|
1084dcea7964SJoe Perches	(?:$Storage\s+)?(?:XA_STATE|XA_STATE_ORDER)\s*\(
1085f8422308SJoe Perches)};
1086f8422308SJoe Perches
10878d0325ccSAditya Srivastavaour %allow_repeated_words = (
10888d0325ccSAditya Srivastava	add => '',
10898d0325ccSAditya Srivastava	added => '',
10908d0325ccSAditya Srivastava	bad => '',
10918d0325ccSAditya Srivastava	be => '',
10928d0325ccSAditya Srivastava);
10938d0325ccSAditya Srivastava
10947d2367afSJoe Perchessub deparenthesize {
10957d2367afSJoe Perches	my ($string) = @_;
10967d2367afSJoe Perches	return "" if (!defined($string));
10975b9553abSJoe Perches
10985b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
10995b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
11005b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
11015b9553abSJoe Perches	}
11025b9553abSJoe Perches
11037d2367afSJoe Perches	$string =~ s@\s+@ @g;
11045b9553abSJoe Perches
11057d2367afSJoe Perches	return $string;
11067d2367afSJoe Perches}
11077d2367afSJoe Perches
11083445686aSJoe Perchessub seed_camelcase_file {
11093445686aSJoe Perches	my ($file) = @_;
11103445686aSJoe Perches
11113445686aSJoe Perches	return if (!(-f $file));
11123445686aSJoe Perches
11133445686aSJoe Perches	local $/;
11143445686aSJoe Perches
11153445686aSJoe Perches	open(my $include_file, '<', "$file")
11163445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
11173445686aSJoe Perches	my $text = <$include_file>;
11183445686aSJoe Perches	close($include_file);
11193445686aSJoe Perches
11203445686aSJoe Perches	my @lines = split('\n', $text);
11213445686aSJoe Perches
11223445686aSJoe Perches	foreach my $line (@lines) {
11233445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
11243445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
11253445686aSJoe Perches			$camelcase{$1} = 1;
112611ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
112711ea516aSJoe Perches			$camelcase{$1} = 1;
112811ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
11293445686aSJoe Perches			$camelcase{$1} = 1;
11303445686aSJoe Perches		}
11313445686aSJoe Perches	}
11323445686aSJoe Perches}
11333445686aSJoe Perches
1134cd28b119SJoe Perchesour %maintained_status = ();
1135cd28b119SJoe Perches
113685b0ee18SJoe Perchessub is_maintained_obsolete {
113785b0ee18SJoe Perches	my ($filename) = @_;
113885b0ee18SJoe Perches
1139f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
114085b0ee18SJoe Perches
1141cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
1142cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
1143cd28b119SJoe Perches	}
114485b0ee18SJoe Perches
1145cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
114685b0ee18SJoe Perches}
114785b0ee18SJoe Perches
11483b6e8ac9SJoe Perchessub is_SPDX_License_valid {
11493b6e8ac9SJoe Perches	my ($license) = @_;
11503b6e8ac9SJoe Perches
1151f9363b31SGuenter Roeck	return 1 if (!$tree || which("python3") eq "" || !(-x "$root/scripts/spdxcheck.py") || !(-e "$gitroot"));
11523b6e8ac9SJoe Perches
115356294112SJoe Perches	my $root_path = abs_path($root);
1154f9363b31SGuenter Roeck	my $status = `cd "$root_path"; echo "$license" | scripts/spdxcheck.py -`;
11553b6e8ac9SJoe Perches	return 0 if ($status ne "");
11563b6e8ac9SJoe Perches	return 1;
11573b6e8ac9SJoe Perches}
11583b6e8ac9SJoe Perches
11593445686aSJoe Perchesmy $camelcase_seeded = 0;
11603445686aSJoe Perchessub seed_camelcase_includes {
11613445686aSJoe Perches	return if ($camelcase_seeded);
11623445686aSJoe Perches
11633445686aSJoe Perches	my $files;
1164c707a81dSJoe Perches	my $camelcase_cache = "";
1165c707a81dSJoe Perches	my @include_files = ();
1166c707a81dSJoe Perches
1167c707a81dSJoe Perches	$camelcase_seeded = 1;
1168351b2a1fSJoe Perches
11690f7f635bSJoe Perches	if (-e "$gitroot") {
1170dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
1171351b2a1fSJoe Perches		chomp $git_last_include_commit;
1172c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
1173c707a81dSJoe Perches	} else {
1174c707a81dSJoe Perches		my $last_mod_date = 0;
1175c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
1176c707a81dSJoe Perches		@include_files = split('\n', $files);
1177c707a81dSJoe Perches		foreach my $file (@include_files) {
1178c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
1179c707a81dSJoe Perches						   localtime((stat $file)[9]));
1180c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
1181c707a81dSJoe Perches		}
1182c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
1183c707a81dSJoe Perches	}
1184c707a81dSJoe Perches
1185c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
1186c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
1187c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
1188351b2a1fSJoe Perches		while (<$camelcase_file>) {
1189351b2a1fSJoe Perches			chomp;
1190351b2a1fSJoe Perches			$camelcase{$_} = 1;
1191351b2a1fSJoe Perches		}
1192351b2a1fSJoe Perches		close($camelcase_file);
1193351b2a1fSJoe Perches
1194351b2a1fSJoe Perches		return;
1195351b2a1fSJoe Perches	}
1196c707a81dSJoe Perches
11970f7f635bSJoe Perches	if (-e "$gitroot") {
1198dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
1199c707a81dSJoe Perches		@include_files = split('\n', $files);
12003445686aSJoe Perches	}
1201c707a81dSJoe Perches
12023445686aSJoe Perches	foreach my $file (@include_files) {
12033445686aSJoe Perches		seed_camelcase_file($file);
12043445686aSJoe Perches	}
1205351b2a1fSJoe Perches
1206c707a81dSJoe Perches	if ($camelcase_cache ne "") {
1207351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
1208c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
1209c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
1210351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
1211351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
1212351b2a1fSJoe Perches		}
1213351b2a1fSJoe Perches		close($camelcase_file);
1214351b2a1fSJoe Perches	}
12153445686aSJoe Perches}
12163445686aSJoe Perches
1217f5f61325SJoe Perchessub git_is_single_file {
1218f5f61325SJoe Perches	my ($filename) = @_;
1219f5f61325SJoe Perches
1220f5f61325SJoe Perches	return 0 if ((which("git") eq "") || !(-e "$gitroot"));
1221f5f61325SJoe Perches
1222f5f61325SJoe Perches	my $output = `${git_command} ls-files -- $filename 2>/dev/null`;
1223f5f61325SJoe Perches	my $count = $output =~ tr/\n//;
1224f5f61325SJoe Perches	return $count eq 1 && $output =~ m{^${filename}$};
1225f5f61325SJoe Perches}
1226f5f61325SJoe Perches
1227d311cd44SJoe Perchessub git_commit_info {
1228d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
1229d311cd44SJoe Perches
12300f7f635bSJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot"));
1231d311cd44SJoe Perches
1232dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
1233d311cd44SJoe Perches	$output =~ s/^\s*//gm;
1234d311cd44SJoe Perches	my @lines = split("\n", $output);
1235d311cd44SJoe Perches
12360d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
12370d7835fcSJoe Perches
12385a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
1239d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
1240d311cd44SJoe Perches# all matching commit ids, but it's very slow...
1241d311cd44SJoe Perches#
1242d311cd44SJoe Perches#		echo "checking commits $1..."
1243d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
1244d311cd44SJoe Perches#		while read line ; do
1245d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
1246d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
1247d311cd44SJoe Perches#		done
12484ce9f970SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./ ||
12494ce9f970SJoe Perches		 $lines[0] =~ /^fatal: bad object $commit/) {
1250948b133aSHeinrich Schuchardt		$id = undef;
1251d311cd44SJoe Perches	} else {
1252d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
1253d311cd44SJoe Perches		$desc = substr($lines[0], 41);
1254d311cd44SJoe Perches	}
1255d311cd44SJoe Perches
1256d311cd44SJoe Perches	return ($id, $desc);
1257d311cd44SJoe Perches}
1258d311cd44SJoe Perches
12596c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
12600a920b5bSAndy Whitcroft
126100df344fSAndy Whitcroftmy @rawlines = ();
1262c2fdda0dSAndy Whitcroftmy @lines = ();
12633705ce5bSJoe Perchesmy @fixed = ();
1264d752fcc8SJoe Perchesmy @fixed_inserted = ();
1265d752fcc8SJoe Perchesmy @fixed_deleted = ();
1266194f66fcSJoe Perchesmy $fixlinenr = -1;
1267194f66fcSJoe Perches
12684a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
12694a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
12700f7f635bSJoe Perchesdie "$P: No git repository found\n" if ($git && !-e "$gitroot");
12714a593c34SDu, Changbin
12724a593c34SDu, Changbinif ($git) {
12734a593c34SDu, Changbin	my @commits = ();
12740dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
12754a593c34SDu, Changbin		my $git_range;
127628898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
127728898fd1SJoe Perches			$git_range = "-$2 $1";
12784a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
12794a593c34SDu, Changbin			$git_range = "$commit_expr";
12804a593c34SDu, Changbin		} else {
12810dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
12820dea9f1eSJoe Perches		}
1283dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
12840dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
128528898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
128628898fd1SJoe Perches			next if (!defined($1) || !defined($2));
12870dea9f1eSJoe Perches			my $sha1 = $1;
12880dea9f1eSJoe Perches			my $subject = $2;
12890dea9f1eSJoe Perches			unshift(@commits, $sha1);
12900dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
12914a593c34SDu, Changbin		}
12924a593c34SDu, Changbin	}
12934a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
12944a593c34SDu, Changbin	@ARGV = @commits;
12954a593c34SDu, Changbin}
12964a593c34SDu, Changbin
1297c2fdda0dSAndy Whitcroftmy $vname;
129898005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
12996c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
130021caa13cSAndy Whitcroft	my $FILE;
1301f5f61325SJoe Perches	my $is_git_file = git_is_single_file($filename);
1302f5f61325SJoe Perches	my $oldfile = $file;
1303f5f61325SJoe Perches	$file = 1 if ($is_git_file);
13044a593c34SDu, Changbin	if ($git) {
13054a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
13064a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
13074a593c34SDu, Changbin	} elsif ($file) {
130821caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
13096c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
131021caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
131121caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
13126c72ffaaSAndy Whitcroft	} else {
131321caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
13146c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
13156c72ffaaSAndy Whitcroft	}
1316c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1317c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
13184a593c34SDu, Changbin	} elsif ($git) {
13190dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1320c2fdda0dSAndy Whitcroft	} else {
1321c2fdda0dSAndy Whitcroft		$vname = $filename;
1322c2fdda0dSAndy Whitcroft	}
132321caa13cSAndy Whitcroft	while (<$FILE>) {
13240a920b5bSAndy Whitcroft		chomp;
132500df344fSAndy Whitcroft		push(@rawlines, $_);
1326c7f574d0SGeert Uytterhoeven		$vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i);
13276c72ffaaSAndy Whitcroft	}
132821caa13cSAndy Whitcroft	close($FILE);
1329d8469f16SJoe Perches
1330d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1331d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1332d8469f16SJoe Perches		print "$vname\n";
1333d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1334d8469f16SJoe Perches	}
1335d8469f16SJoe Perches
1336c2fdda0dSAndy Whitcroft	if (!process($filename)) {
13370a920b5bSAndy Whitcroft		$exit = 1;
13380a920b5bSAndy Whitcroft	}
133900df344fSAndy Whitcroft	@rawlines = ();
134013214adfSAndy Whitcroft	@lines = ();
13413705ce5bSJoe Perches	@fixed = ();
1342d752fcc8SJoe Perches	@fixed_inserted = ();
1343d752fcc8SJoe Perches	@fixed_deleted = ();
1344194f66fcSJoe Perches	$fixlinenr = -1;
1345485ff23eSAlex Dowad	@modifierListFile = ();
1346485ff23eSAlex Dowad	@typeListFile = ();
1347485ff23eSAlex Dowad	build_types();
1348f5f61325SJoe Perches	$file = $oldfile if ($is_git_file);
13490a920b5bSAndy Whitcroft}
13500a920b5bSAndy Whitcroft
1351d8469f16SJoe Perchesif (!$quiet) {
13523c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
13533c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
13543c816e49SJoe Perches
13555b57980dSJoe Perches	if (!$perl_version_ok) {
1356d8469f16SJoe Perches		print << "EOM"
1357d8469f16SJoe Perches
1358d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
13595b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1360d8469f16SJoe PerchesEOM
1361d8469f16SJoe Perches	}
1362d8469f16SJoe Perches	if ($exit) {
1363d8469f16SJoe Perches		print << "EOM"
1364d8469f16SJoe Perches
1365d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1366d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1367d8469f16SJoe PerchesEOM
1368d8469f16SJoe Perches	}
1369d8469f16SJoe Perches}
1370d8469f16SJoe Perches
13710a920b5bSAndy Whitcroftexit($exit);
13720a920b5bSAndy Whitcroft
13730a920b5bSAndy Whitcroftsub top_of_kernel_tree {
13746c72ffaaSAndy Whitcroft	my ($root) = @_;
13756c72ffaaSAndy Whitcroft
13766c72ffaaSAndy Whitcroft	my @tree_check = (
13776c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
13786c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
13796c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
13806c72ffaaSAndy Whitcroft	);
13816c72ffaaSAndy Whitcroft
13826c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
13836c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
13840a920b5bSAndy Whitcroft			return 0;
13850a920b5bSAndy Whitcroft		}
13866c72ffaaSAndy Whitcroft	}
13876c72ffaaSAndy Whitcroft	return 1;
13886c72ffaaSAndy Whitcroft}
13890a920b5bSAndy Whitcroft
139020112475SJoe Perchessub parse_email {
139120112475SJoe Perches	my ($formatted_email) = @_;
139220112475SJoe Perches
139320112475SJoe Perches	my $name = "";
1394fccaebf0SDwaipayan Ray	my $quoted = "";
1395dfa05c28SJoe Perches	my $name_comment = "";
139620112475SJoe Perches	my $address = "";
139720112475SJoe Perches	my $comment = "";
139820112475SJoe Perches
139920112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
140020112475SJoe Perches		$name = $1;
140120112475SJoe Perches		$address = $2;
140220112475SJoe Perches		$comment = $3 if defined $3;
140320112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
140420112475SJoe Perches		$address = $1;
140520112475SJoe Perches		$comment = $2 if defined $2;
140620112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
140720112475SJoe Perches		$address = $1;
140820112475SJoe Perches		$comment = $2 if defined $2;
140985e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
141020112475SJoe Perches		$name = $formatted_email;
14113705ce5bSJoe Perches		$name = trim($name);
141220112475SJoe Perches		$name =~ s/^\"|\"$//g;
141320112475SJoe Perches		# If there's a name left after stripping spaces and
141420112475SJoe Perches		# leading quotes, and the address doesn't have both
141520112475SJoe Perches		# leading and trailing angle brackets, the address
141620112475SJoe Perches		# is invalid. ie:
141720112475SJoe Perches		#   "joe smith [email protected]" bad
141820112475SJoe Perches		#   "joe smith <[email protected]" bad
141920112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
142020112475SJoe Perches			$name = "";
142120112475SJoe Perches			$address = "";
142220112475SJoe Perches			$comment = "";
142320112475SJoe Perches		}
142420112475SJoe Perches	}
142520112475SJoe Perches
1426fccaebf0SDwaipayan Ray	# Extract comments from names excluding quoted parts
1427fccaebf0SDwaipayan Ray	# "John D. (Doe)" - Do not extract
1428fccaebf0SDwaipayan Ray	if ($name =~ s/\"(.+)\"//) {
1429fccaebf0SDwaipayan Ray		$quoted = $1;
1430dfa05c28SJoe Perches	}
1431fccaebf0SDwaipayan Ray	while ($name =~ s/\s*($balanced_parens)\s*/ /) {
1432fccaebf0SDwaipayan Ray		$name_comment .= trim($1);
1433fccaebf0SDwaipayan Ray	}
1434fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
1435fccaebf0SDwaipayan Ray	$name = trim("$quoted $name");
1436fccaebf0SDwaipayan Ray
14373705ce5bSJoe Perches	$address = trim($address);
143820112475SJoe Perches	$address =~ s/^\<|\>$//g;
1439fccaebf0SDwaipayan Ray	$comment = trim($comment);
144020112475SJoe Perches
144120112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
144220112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
144320112475SJoe Perches		$name = "\"$name\"";
144420112475SJoe Perches	}
144520112475SJoe Perches
1446dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
144720112475SJoe Perches}
144820112475SJoe Perches
144920112475SJoe Perchessub format_email {
145048ca2d8aSDwaipayan Ray	my ($name, $name_comment, $address, $comment) = @_;
145120112475SJoe Perches
145220112475SJoe Perches	my $formatted_email;
145320112475SJoe Perches
1454fccaebf0SDwaipayan Ray	$name =~ s/^[ \"]+|[ \"]+$//g;
14553705ce5bSJoe Perches	$address = trim($address);
1456fccaebf0SDwaipayan Ray	$address =~ s/(?:\.|\,|\")+$//; ##trailing commas, dots or quotes
145720112475SJoe Perches
145820112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
145920112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
146020112475SJoe Perches		$name = "\"$name\"";
146120112475SJoe Perches	}
146220112475SJoe Perches
1463fccaebf0SDwaipayan Ray	$name_comment = trim($name_comment);
1464fccaebf0SDwaipayan Ray	$name_comment = " $name_comment" if ($name_comment ne "");
1465fccaebf0SDwaipayan Ray	$comment = trim($comment);
1466fccaebf0SDwaipayan Ray	$comment = " $comment" if ($comment ne "");
1467fccaebf0SDwaipayan Ray
146820112475SJoe Perches	if ("$name" eq "") {
146920112475SJoe Perches		$formatted_email = "$address";
147020112475SJoe Perches	} else {
147148ca2d8aSDwaipayan Ray		$formatted_email = "$name$name_comment <$address>";
147220112475SJoe Perches	}
147348ca2d8aSDwaipayan Ray	$formatted_email .= "$comment";
147420112475SJoe Perches	return $formatted_email;
147520112475SJoe Perches}
147620112475SJoe Perches
1477dfa05c28SJoe Perchessub reformat_email {
1478dfa05c28SJoe Perches	my ($email) = @_;
1479dfa05c28SJoe Perches
1480dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
148148ca2d8aSDwaipayan Ray	return format_email($email_name, $name_comment, $email_address, $comment);
1482dfa05c28SJoe Perches}
1483dfa05c28SJoe Perches
1484dfa05c28SJoe Perchessub same_email_addresses {
1485fccaebf0SDwaipayan Ray	my ($email1, $email2) = @_;
1486dfa05c28SJoe Perches
1487dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1488dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1489dfa05c28SJoe Perches
149048ca2d8aSDwaipayan Ray	return $email1_name eq $email2_name &&
149148ca2d8aSDwaipayan Ray	       $email1_address eq $email2_address &&
149248ca2d8aSDwaipayan Ray	       $name1_comment eq $name2_comment &&
149348ca2d8aSDwaipayan Ray	       $comment1 eq $comment2;
149448ca2d8aSDwaipayan Ray}
1495dfa05c28SJoe Perches
1496d311cd44SJoe Perchessub which {
1497d311cd44SJoe Perches	my ($bin) = @_;
1498d311cd44SJoe Perches
1499d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1500d311cd44SJoe Perches		if (-e "$path/$bin") {
1501d311cd44SJoe Perches			return "$path/$bin";
1502d311cd44SJoe Perches		}
1503d311cd44SJoe Perches	}
1504d311cd44SJoe Perches
1505d311cd44SJoe Perches	return "";
1506d311cd44SJoe Perches}
1507d311cd44SJoe Perches
1508000d1cc1SJoe Perchessub which_conf {
1509000d1cc1SJoe Perches	my ($conf) = @_;
1510000d1cc1SJoe Perches
1511000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1512000d1cc1SJoe Perches		if (-e "$path/$conf") {
1513000d1cc1SJoe Perches			return "$path/$conf";
1514000d1cc1SJoe Perches		}
1515000d1cc1SJoe Perches	}
1516000d1cc1SJoe Perches
1517000d1cc1SJoe Perches	return "";
1518000d1cc1SJoe Perches}
1519000d1cc1SJoe Perches
15200a920b5bSAndy Whitcroftsub expand_tabs {
15210a920b5bSAndy Whitcroft	my ($str) = @_;
15220a920b5bSAndy Whitcroft
15230a920b5bSAndy Whitcroft	my $res = '';
15240a920b5bSAndy Whitcroft	my $n = 0;
15250a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
15260a920b5bSAndy Whitcroft		if ($c eq "\t") {
15270a920b5bSAndy Whitcroft			$res .= ' ';
15280a920b5bSAndy Whitcroft			$n++;
1529713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
15300a920b5bSAndy Whitcroft				$res .= ' ';
15310a920b5bSAndy Whitcroft			}
15320a920b5bSAndy Whitcroft			next;
15330a920b5bSAndy Whitcroft		}
15340a920b5bSAndy Whitcroft		$res .= $c;
15350a920b5bSAndy Whitcroft		$n++;
15360a920b5bSAndy Whitcroft	}
15370a920b5bSAndy Whitcroft
15380a920b5bSAndy Whitcroft	return $res;
15390a920b5bSAndy Whitcroft}
15406c72ffaaSAndy Whitcroftsub copy_spacing {
1541773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
15426c72ffaaSAndy Whitcroft	return $res;
15436c72ffaaSAndy Whitcroft}
15440a920b5bSAndy Whitcroft
15454a0df2efSAndy Whitcroftsub line_stats {
15464a0df2efSAndy Whitcroft	my ($line) = @_;
15474a0df2efSAndy Whitcroft
15484a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
15494a0df2efSAndy Whitcroft	$line =~ s/^.//;
15504a0df2efSAndy Whitcroft	$line = expand_tabs($line);
15514a0df2efSAndy Whitcroft
15524a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
15534a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
15544a0df2efSAndy Whitcroft
15554a0df2efSAndy Whitcroft	return (length($line), length($white));
15564a0df2efSAndy Whitcroft}
15574a0df2efSAndy Whitcroft
1558773647a0SAndy Whitcroftmy $sanitise_quote = '';
1559773647a0SAndy Whitcroft
1560773647a0SAndy Whitcroftsub sanitise_line_reset {
1561773647a0SAndy Whitcroft	my ($in_comment) = @_;
1562773647a0SAndy Whitcroft
1563773647a0SAndy Whitcroft	if ($in_comment) {
1564773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1565773647a0SAndy Whitcroft	} else {
1566773647a0SAndy Whitcroft		$sanitise_quote = '';
1567773647a0SAndy Whitcroft	}
1568773647a0SAndy Whitcroft}
156900df344fSAndy Whitcroftsub sanitise_line {
157000df344fSAndy Whitcroft	my ($line) = @_;
157100df344fSAndy Whitcroft
157200df344fSAndy Whitcroft	my $res = '';
157300df344fSAndy Whitcroft	my $l = '';
157400df344fSAndy Whitcroft
1575c2fdda0dSAndy Whitcroft	my $qlen = 0;
1576773647a0SAndy Whitcroft	my $off = 0;
1577773647a0SAndy Whitcroft	my $c;
157800df344fSAndy Whitcroft
1579773647a0SAndy Whitcroft	# Always copy over the diff marker.
1580773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1581773647a0SAndy Whitcroft
1582773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1583773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1584773647a0SAndy Whitcroft
15858d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1586773647a0SAndy Whitcroft		# and end, all to $;.
1587773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1588773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1589773647a0SAndy Whitcroft
1590773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1591773647a0SAndy Whitcroft			$off++;
159200df344fSAndy Whitcroft			next;
1593773647a0SAndy Whitcroft		}
159481bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1595773647a0SAndy Whitcroft			$sanitise_quote = '';
1596773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1597773647a0SAndy Whitcroft			$off++;
1598773647a0SAndy Whitcroft			next;
1599773647a0SAndy Whitcroft		}
1600113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1601113f04a8SDaniel Walker			$sanitise_quote = '//';
1602113f04a8SDaniel Walker
1603113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1604113f04a8SDaniel Walker			$off++;
1605113f04a8SDaniel Walker			next;
1606113f04a8SDaniel Walker		}
1607773647a0SAndy Whitcroft
1608773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1609773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1610773647a0SAndy Whitcroft		    $c eq "\\") {
1611773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1612773647a0SAndy Whitcroft			$off++;
1613773647a0SAndy Whitcroft			next;
1614773647a0SAndy Whitcroft		}
1615773647a0SAndy Whitcroft		# Regular quotes.
1616773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1617773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1618773647a0SAndy Whitcroft				$sanitise_quote = $c;
1619773647a0SAndy Whitcroft
1620773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1621773647a0SAndy Whitcroft				next;
1622773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1623773647a0SAndy Whitcroft				$sanitise_quote = '';
162400df344fSAndy Whitcroft			}
162500df344fSAndy Whitcroft		}
1626773647a0SAndy Whitcroft
1627fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1628773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1629773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1630113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1631113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1632773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1633773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
163400df344fSAndy Whitcroft		} else {
1635773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
163600df344fSAndy Whitcroft		}
1637c2fdda0dSAndy Whitcroft	}
1638c2fdda0dSAndy Whitcroft
1639113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1640113f04a8SDaniel Walker		$sanitise_quote = '';
1641113f04a8SDaniel Walker	}
1642113f04a8SDaniel Walker
1643c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1644c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1645c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1646c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1647c2fdda0dSAndy Whitcroft
1648c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1649c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1650c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1651c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1652c2fdda0dSAndy Whitcroft	}
1653c2fdda0dSAndy Whitcroft
1654dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1655dadf680dSJoe Perches		my $match = $1;
1656dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1657dadf680dSJoe Perches	}
1658dadf680dSJoe Perches
165900df344fSAndy Whitcroft	return $res;
166000df344fSAndy Whitcroft}
166100df344fSAndy Whitcroft
1662a6962d72SJoe Perchessub get_quoted_string {
1663a6962d72SJoe Perches	my ($line, $rawline) = @_;
1664a6962d72SJoe Perches
1665478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
166633acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1667a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1668a6962d72SJoe Perches}
1669a6962d72SJoe Perches
16708905a67cSAndy Whitcroftsub ctx_statement_block {
16718905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16728905a67cSAndy Whitcroft	my $line = $linenr - 1;
16738905a67cSAndy Whitcroft	my $blk = '';
16748905a67cSAndy Whitcroft	my $soff = $off;
16758905a67cSAndy Whitcroft	my $coff = $off - 1;
1676773647a0SAndy Whitcroft	my $coff_set = 0;
16778905a67cSAndy Whitcroft
167813214adfSAndy Whitcroft	my $loff = 0;
167913214adfSAndy Whitcroft
16808905a67cSAndy Whitcroft	my $type = '';
16818905a67cSAndy Whitcroft	my $level = 0;
1682a2750645SAndy Whitcroft	my @stack = ();
1683cf655043SAndy Whitcroft	my $p;
16848905a67cSAndy Whitcroft	my $c;
16858905a67cSAndy Whitcroft	my $len = 0;
168613214adfSAndy Whitcroft
168713214adfSAndy Whitcroft	my $remainder;
16888905a67cSAndy Whitcroft	while (1) {
1689a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1690a2750645SAndy Whitcroft
1691773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
16928905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
16938905a67cSAndy Whitcroft		# context.
16948905a67cSAndy Whitcroft		if ($off >= $len) {
16958905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1696dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1697c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
16988905a67cSAndy Whitcroft				$remain--;
169913214adfSAndy Whitcroft				$loff = $len;
1700c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
17018905a67cSAndy Whitcroft				$len = length($blk);
17028905a67cSAndy Whitcroft				$line++;
17038905a67cSAndy Whitcroft				last;
17048905a67cSAndy Whitcroft			}
17058905a67cSAndy Whitcroft			# Bail if there is no further context.
17068905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
170713214adfSAndy Whitcroft			if ($off >= $len) {
17088905a67cSAndy Whitcroft				last;
17098905a67cSAndy Whitcroft			}
1710f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1711f74bd194SAndy Whitcroft				$level++;
1712f74bd194SAndy Whitcroft				$type = '#';
1713f74bd194SAndy Whitcroft			}
17148905a67cSAndy Whitcroft		}
1715cf655043SAndy Whitcroft		$p = $c;
17168905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
171713214adfSAndy Whitcroft		$remainder = substr($blk, $off);
17188905a67cSAndy Whitcroft
1719773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
17204635f4fbSAndy Whitcroft
17214635f4fbSAndy Whitcroft		# Handle nested #if/#else.
17224635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
17234635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
17244635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
17254635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
17264635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
17274635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
17284635f4fbSAndy Whitcroft		}
17294635f4fbSAndy Whitcroft
17308905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
17318905a67cSAndy Whitcroft		# outermost level.
17328905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
17338905a67cSAndy Whitcroft			last;
17348905a67cSAndy Whitcroft		}
17358905a67cSAndy Whitcroft
173613214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1737773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1738773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1739773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1740773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1741773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1742773647a0SAndy Whitcroft			$coff_set = 1;
1743773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1744773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
174513214adfSAndy Whitcroft		}
174613214adfSAndy Whitcroft
17478905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
17488905a67cSAndy Whitcroft			$level++;
17498905a67cSAndy Whitcroft			$type = '(';
17508905a67cSAndy Whitcroft		}
17518905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
17528905a67cSAndy Whitcroft			$level--;
17538905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
17548905a67cSAndy Whitcroft
17558905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
17568905a67cSAndy Whitcroft				$coff = $off;
1757773647a0SAndy Whitcroft				$coff_set = 1;
1758773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
17598905a67cSAndy Whitcroft			}
17608905a67cSAndy Whitcroft		}
17618905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
17628905a67cSAndy Whitcroft			$level++;
17638905a67cSAndy Whitcroft			$type = '{';
17648905a67cSAndy Whitcroft		}
17658905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
17668905a67cSAndy Whitcroft			$level--;
17678905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
17688905a67cSAndy Whitcroft
17698905a67cSAndy Whitcroft			if ($level == 0) {
1770b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1771b998e001SPatrick Pannuto					$off++;
1772b998e001SPatrick Pannuto				}
17738905a67cSAndy Whitcroft				last;
17748905a67cSAndy Whitcroft			}
17758905a67cSAndy Whitcroft		}
1776f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1777f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1778f74bd194SAndy Whitcroft			$level--;
1779f74bd194SAndy Whitcroft			$type = '';
1780f74bd194SAndy Whitcroft			$off++;
1781f74bd194SAndy Whitcroft			last;
1782f74bd194SAndy Whitcroft		}
17838905a67cSAndy Whitcroft		$off++;
17848905a67cSAndy Whitcroft	}
1785a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
178613214adfSAndy Whitcroft	if ($off == $len) {
1787a3bb97a7SAndy Whitcroft		$loff = $len + 1;
178813214adfSAndy Whitcroft		$line++;
178913214adfSAndy Whitcroft		$remain--;
179013214adfSAndy Whitcroft	}
17918905a67cSAndy Whitcroft
17928905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
17938905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
17948905a67cSAndy Whitcroft
17958905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
17968905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
17978905a67cSAndy Whitcroft
1798773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
179913214adfSAndy Whitcroft
180013214adfSAndy Whitcroft	return ($statement, $condition,
180113214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
180213214adfSAndy Whitcroft}
180313214adfSAndy Whitcroft
1804cf655043SAndy Whitcroftsub statement_lines {
1805cf655043SAndy Whitcroft	my ($stmt) = @_;
1806cf655043SAndy Whitcroft
1807cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1808cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1809cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1810cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1811cf655043SAndy Whitcroft
1812cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1813cf655043SAndy Whitcroft
1814cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1815cf655043SAndy Whitcroft}
1816cf655043SAndy Whitcroft
1817cf655043SAndy Whitcroftsub statement_rawlines {
1818cf655043SAndy Whitcroft	my ($stmt) = @_;
1819cf655043SAndy Whitcroft
1820cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1821cf655043SAndy Whitcroft
1822cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1823cf655043SAndy Whitcroft}
1824cf655043SAndy Whitcroft
1825cf655043SAndy Whitcroftsub statement_block_size {
1826cf655043SAndy Whitcroft	my ($stmt) = @_;
1827cf655043SAndy Whitcroft
1828cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1829cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1830cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1831cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1832cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1833cf655043SAndy Whitcroft
1834cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1835cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1836cf655043SAndy Whitcroft
1837cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1838cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1839cf655043SAndy Whitcroft
1840cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1841cf655043SAndy Whitcroft		return $stmt_lines;
1842cf655043SAndy Whitcroft	} else {
1843cf655043SAndy Whitcroft		return $stmt_statements;
1844cf655043SAndy Whitcroft	}
1845cf655043SAndy Whitcroft}
1846cf655043SAndy Whitcroft
184713214adfSAndy Whitcroftsub ctx_statement_full {
184813214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
184913214adfSAndy Whitcroft	my ($statement, $condition, $level);
185013214adfSAndy Whitcroft
185113214adfSAndy Whitcroft	my (@chunks);
185213214adfSAndy Whitcroft
1853cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
185413214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
185513214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1856773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
185713214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1858cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1859cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1860cf655043SAndy Whitcroft	}
1861cf655043SAndy Whitcroft
1862cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1863cf655043SAndy Whitcroft	# could continue the statement.
1864cf655043SAndy Whitcroft	for (;;) {
186513214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
186613214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1867cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1868773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1869cf655043SAndy Whitcroft		#print "C: push\n";
1870cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
187113214adfSAndy Whitcroft	}
187213214adfSAndy Whitcroft
187313214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
18748905a67cSAndy Whitcroft}
18758905a67cSAndy Whitcroft
18764a0df2efSAndy Whitcroftsub ctx_block_get {
1877f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
18784a0df2efSAndy Whitcroft	my $line;
18794a0df2efSAndy Whitcroft	my $start = $linenr - 1;
18804a0df2efSAndy Whitcroft	my $blk = '';
18814a0df2efSAndy Whitcroft	my @o;
18824a0df2efSAndy Whitcroft	my @c;
18834a0df2efSAndy Whitcroft	my @res = ();
18844a0df2efSAndy Whitcroft
1885f0a594c1SAndy Whitcroft	my $level = 0;
18864635f4fbSAndy Whitcroft	my @stack = ($level);
188700df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
188800df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
188900df344fSAndy Whitcroft		$remain--;
189000df344fSAndy Whitcroft
189100df344fSAndy Whitcroft		$blk .= $rawlines[$line];
18924635f4fbSAndy Whitcroft
18934635f4fbSAndy Whitcroft		# Handle nested #if/#else.
189401464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
18954635f4fbSAndy Whitcroft			push(@stack, $level);
189601464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
18974635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
189801464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
18994635f4fbSAndy Whitcroft			$level = pop(@stack);
19004635f4fbSAndy Whitcroft		}
19014635f4fbSAndy Whitcroft
190201464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1903f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1904f0a594c1SAndy Whitcroft			if ($off > 0) {
1905f0a594c1SAndy Whitcroft				$off--;
1906f0a594c1SAndy Whitcroft				next;
1907f0a594c1SAndy Whitcroft			}
19084a0df2efSAndy Whitcroft
1909f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1910f0a594c1SAndy Whitcroft				$level--;
1911f0a594c1SAndy Whitcroft				last if ($level == 0);
1912f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1913f0a594c1SAndy Whitcroft				$level++;
1914f0a594c1SAndy Whitcroft			}
1915f0a594c1SAndy Whitcroft		}
19164a0df2efSAndy Whitcroft
1917f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
191800df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
19194a0df2efSAndy Whitcroft		}
19204a0df2efSAndy Whitcroft
1921f0a594c1SAndy Whitcroft		last if ($level == 0);
19224a0df2efSAndy Whitcroft	}
19234a0df2efSAndy Whitcroft
1924f0a594c1SAndy Whitcroft	return ($level, @res);
19254a0df2efSAndy Whitcroft}
19264a0df2efSAndy Whitcroftsub ctx_block_outer {
19274a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
19284a0df2efSAndy Whitcroft
1929f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1930f0a594c1SAndy Whitcroft	return @r;
19314a0df2efSAndy Whitcroft}
19324a0df2efSAndy Whitcroftsub ctx_block {
19334a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
19344a0df2efSAndy Whitcroft
1935f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1936f0a594c1SAndy Whitcroft	return @r;
1937653d4876SAndy Whitcroft}
1938653d4876SAndy Whitcroftsub ctx_statement {
1939f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1940f0a594c1SAndy Whitcroft
1941f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1942f0a594c1SAndy Whitcroft	return @r;
1943f0a594c1SAndy Whitcroft}
1944f0a594c1SAndy Whitcroftsub ctx_block_level {
1945653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1946653d4876SAndy Whitcroft
1947f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
19484a0df2efSAndy Whitcroft}
19499c0ca6f9SAndy Whitcroftsub ctx_statement_level {
19509c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
19519c0ca6f9SAndy Whitcroft
19529c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
19539c0ca6f9SAndy Whitcroft}
19544a0df2efSAndy Whitcroft
19554a0df2efSAndy Whitcroftsub ctx_locate_comment {
19564a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19574a0df2efSAndy Whitcroft
1958a55ee0ccSJoe Perches	# If c99 comment on the current line, or the line before or after
1959a55ee0ccSJoe Perches	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@);
1960a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1961a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@);
1962a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1963a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@);
1964a55ee0ccSJoe Perches	return $current_comment if (defined $current_comment);
1965a55ee0ccSJoe Perches
19664a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1967a55ee0ccSJoe Perches	($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
19684a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
19694a0df2efSAndy Whitcroft
19704a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
19714a0df2efSAndy Whitcroft	# comment.
19724a0df2efSAndy Whitcroft	my $in_comment = 0;
19734a0df2efSAndy Whitcroft	$current_comment = '';
19744a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
197500df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
197600df344fSAndy Whitcroft		#warn "           $line\n";
19774a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
19784a0df2efSAndy Whitcroft			$in_comment = 1;
19794a0df2efSAndy Whitcroft		}
19804a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
19814a0df2efSAndy Whitcroft			$in_comment = 1;
19824a0df2efSAndy Whitcroft		}
19834a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
19844a0df2efSAndy Whitcroft			$current_comment = '';
19854a0df2efSAndy Whitcroft		}
19864a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
19874a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
19884a0df2efSAndy Whitcroft			$in_comment = 0;
19894a0df2efSAndy Whitcroft		}
19904a0df2efSAndy Whitcroft	}
19914a0df2efSAndy Whitcroft
19924a0df2efSAndy Whitcroft	chomp($current_comment);
19934a0df2efSAndy Whitcroft	return($current_comment);
19944a0df2efSAndy Whitcroft}
19954a0df2efSAndy Whitcroftsub ctx_has_comment {
19964a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
19974a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
19984a0df2efSAndy Whitcroft
199900df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
20004a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
20014a0df2efSAndy Whitcroft
20024a0df2efSAndy Whitcroft	return ($cmt ne '');
20034a0df2efSAndy Whitcroft}
20044a0df2efSAndy Whitcroft
20054d001e4dSAndy Whitcroftsub raw_line {
20064d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
20074d001e4dSAndy Whitcroft
20084d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
20094d001e4dSAndy Whitcroft	$cnt++;
20104d001e4dSAndy Whitcroft
20114d001e4dSAndy Whitcroft	my $line;
20124d001e4dSAndy Whitcroft	while ($cnt) {
20134d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
20144d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
20154d001e4dSAndy Whitcroft		$cnt--;
20164d001e4dSAndy Whitcroft	}
20174d001e4dSAndy Whitcroft
20184d001e4dSAndy Whitcroft	return $line;
20194d001e4dSAndy Whitcroft}
20204d001e4dSAndy Whitcroft
20212a9f9d85STobin C. Hardingsub get_stat_real {
20222a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
20232a9f9d85STobin C. Harding
20242a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
20252a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
20262a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
20272a9f9d85STobin C. Harding	}
20282a9f9d85STobin C. Harding
20292a9f9d85STobin C. Harding	return $stat_real;
20302a9f9d85STobin C. Harding}
20312a9f9d85STobin C. Harding
2032e3d95a2aSTobin C. Hardingsub get_stat_here {
2033e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
2034e3d95a2aSTobin C. Harding
2035e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
2036e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
2037e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
2038e3d95a2aSTobin C. Harding	}
2039e3d95a2aSTobin C. Harding
2040e3d95a2aSTobin C. Harding	return $herectx;
2041e3d95a2aSTobin C. Harding}
2042e3d95a2aSTobin C. Harding
20430a920b5bSAndy Whitcroftsub cat_vet {
20440a920b5bSAndy Whitcroft	my ($vet) = @_;
20459c0ca6f9SAndy Whitcroft	my ($res, $coded);
20460a920b5bSAndy Whitcroft
20479c0ca6f9SAndy Whitcroft	$res = '';
20486c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
20496c72ffaaSAndy Whitcroft		$res .= $1;
20506c72ffaaSAndy Whitcroft		if ($2 ne '') {
20519c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
20526c72ffaaSAndy Whitcroft			$res .= $coded;
20536c72ffaaSAndy Whitcroft		}
20549c0ca6f9SAndy Whitcroft	}
20559c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
20560a920b5bSAndy Whitcroft
20579c0ca6f9SAndy Whitcroft	return $res;
20580a920b5bSAndy Whitcroft}
20590a920b5bSAndy Whitcroft
2060c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
2061cf655043SAndy Whitcroftmy $av_pending;
2062c2fdda0dSAndy Whitcroftmy @av_paren_type;
20631f65f947SAndy Whitcroftmy $av_pend_colon;
2064c2fdda0dSAndy Whitcroft
2065c2fdda0dSAndy Whitcroftsub annotate_reset {
2066c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
2067cf655043SAndy Whitcroft	$av_pending = '_';
2068cf655043SAndy Whitcroft	@av_paren_type = ('E');
20691f65f947SAndy Whitcroft	$av_pend_colon = 'O';
2070c2fdda0dSAndy Whitcroft}
2071c2fdda0dSAndy Whitcroft
20726c72ffaaSAndy Whitcroftsub annotate_values {
20736c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
20746c72ffaaSAndy Whitcroft
20756c72ffaaSAndy Whitcroft	my $res;
20761f65f947SAndy Whitcroft	my $var = '_' x length($stream);
20776c72ffaaSAndy Whitcroft	my $cur = $stream;
20786c72ffaaSAndy Whitcroft
2079c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
20806c72ffaaSAndy Whitcroft
20816c72ffaaSAndy Whitcroft	while (length($cur)) {
2082773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
2083cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
2084171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
20856c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
2086c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
2087c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
2088cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
2089c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
20906c72ffaaSAndy Whitcroft			}
20916c72ffaaSAndy Whitcroft
2092c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
20939446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
20949446ef56SAndy Whitcroft			push(@av_paren_type, $type);
2095addcdceaSAndy Whitcroft			$type = 'c';
20969446ef56SAndy Whitcroft
2097e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
2098c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
20996c72ffaaSAndy Whitcroft			$type = 'T';
21006c72ffaaSAndy Whitcroft
2101389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
2102389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
2103389a2fe5SAndy Whitcroft			$type = 'T';
2104389a2fe5SAndy Whitcroft
2105c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
2106171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
2107c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2108171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
2109171ae1a4SAndy Whitcroft			if ($2 ne '') {
2110cf655043SAndy Whitcroft				$av_pending = 'N';
2111171ae1a4SAndy Whitcroft			}
2112171ae1a4SAndy Whitcroft			$type = 'E';
2113171ae1a4SAndy Whitcroft
2114c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
2115171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
2116171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
2117171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
21186c72ffaaSAndy Whitcroft
2119c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
2120cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
2121c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
2122cf655043SAndy Whitcroft
2123cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2124cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2125171ae1a4SAndy Whitcroft			$type = 'E';
2126cf655043SAndy Whitcroft
2127c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
2128cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
2129cf655043SAndy Whitcroft			$av_preprocessor = 1;
2130cf655043SAndy Whitcroft
2131cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
2132cf655043SAndy Whitcroft
2133171ae1a4SAndy Whitcroft			$type = 'E';
2134cf655043SAndy Whitcroft
2135c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
2136cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
2137cf655043SAndy Whitcroft
2138cf655043SAndy Whitcroft			$av_preprocessor = 1;
2139cf655043SAndy Whitcroft
2140cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
2141cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
2142cf655043SAndy Whitcroft			pop(@av_paren_type);
2143cf655043SAndy Whitcroft			push(@av_paren_type, $type);
2144171ae1a4SAndy Whitcroft			$type = 'E';
21456c72ffaaSAndy Whitcroft
21466c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
2147c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
21486c72ffaaSAndy Whitcroft
2149171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
2150171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
2151171ae1a4SAndy Whitcroft			$av_pending = $type;
2152171ae1a4SAndy Whitcroft			$type = 'N';
2153171ae1a4SAndy Whitcroft
21546c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
2155c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
21566c72ffaaSAndy Whitcroft			if (defined $2) {
2157cf655043SAndy Whitcroft				$av_pending = 'V';
21586c72ffaaSAndy Whitcroft			}
21596c72ffaaSAndy Whitcroft			$type = 'N';
21606c72ffaaSAndy Whitcroft
216114b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
2162c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
216314b111c1SAndy Whitcroft			$av_pending = 'E';
21646c72ffaaSAndy Whitcroft			$type = 'N';
21656c72ffaaSAndy Whitcroft
21661f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
21671f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
21681f65f947SAndy Whitcroft			$av_pend_colon = 'C';
21691f65f947SAndy Whitcroft			$type = 'N';
21701f65f947SAndy Whitcroft
217114b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
2172c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
21736c72ffaaSAndy Whitcroft			$type = 'N';
21746c72ffaaSAndy Whitcroft
21756c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
2176c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
2177cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
2178cf655043SAndy Whitcroft			$av_pending = '_';
21796c72ffaaSAndy Whitcroft			$type = 'N';
21806c72ffaaSAndy Whitcroft
21816c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
2182cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
2183cf655043SAndy Whitcroft			if ($new_type ne '_') {
2184cf655043SAndy Whitcroft				$type = $new_type;
2185c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
2186c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
21876c72ffaaSAndy Whitcroft			} else {
2188c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
21896c72ffaaSAndy Whitcroft			}
21906c72ffaaSAndy Whitcroft
2191c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
2192c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
2193c8cb2ca3SAndy Whitcroft			$type = 'V';
2194cf655043SAndy Whitcroft			$av_pending = 'V';
21956c72ffaaSAndy Whitcroft
21968e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
21978e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
21981f65f947SAndy Whitcroft				$av_pend_colon = 'B';
21998e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
22008e761b04SAndy Whitcroft				$av_pend_colon = 'L';
22011f65f947SAndy Whitcroft			}
22021f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
22031f65f947SAndy Whitcroft			$type = 'V';
22041f65f947SAndy Whitcroft
22056c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
2206c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
22076c72ffaaSAndy Whitcroft			$type = 'V';
22086c72ffaaSAndy Whitcroft
22096c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
2210c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
22116c72ffaaSAndy Whitcroft			$type = 'N';
22126c72ffaaSAndy Whitcroft
2213cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
2214c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
221513214adfSAndy Whitcroft			$type = 'E';
22161f65f947SAndy Whitcroft			$av_pend_colon = 'O';
221713214adfSAndy Whitcroft
22188e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
22198e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
22208e761b04SAndy Whitcroft			$type = 'C';
22218e761b04SAndy Whitcroft
22221f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
22231f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
22241f65f947SAndy Whitcroft			$type = 'N';
22251f65f947SAndy Whitcroft
22261f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
22271f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
22281f65f947SAndy Whitcroft
22291f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
22301f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
22311f65f947SAndy Whitcroft				$type = 'E';
22321f65f947SAndy Whitcroft			} else {
22331f65f947SAndy Whitcroft				$type = 'N';
22341f65f947SAndy Whitcroft			}
22351f65f947SAndy Whitcroft			$av_pend_colon = 'O';
22361f65f947SAndy Whitcroft
22378e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
223813214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
22396c72ffaaSAndy Whitcroft			$type = 'N';
22406c72ffaaSAndy Whitcroft
22410d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
224274048ed8SAndy Whitcroft			my $variant;
224374048ed8SAndy Whitcroft
224474048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
224574048ed8SAndy Whitcroft			if ($type eq 'V') {
224674048ed8SAndy Whitcroft				$variant = 'B';
224774048ed8SAndy Whitcroft			} else {
224874048ed8SAndy Whitcroft				$variant = 'U';
224974048ed8SAndy Whitcroft			}
225074048ed8SAndy Whitcroft
225174048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
225274048ed8SAndy Whitcroft			$type = 'N';
225374048ed8SAndy Whitcroft
22546c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
2255c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
22566c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
22576c72ffaaSAndy Whitcroft				$type = 'N';
22586c72ffaaSAndy Whitcroft			}
22596c72ffaaSAndy Whitcroft
22606c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
2261c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
22626c72ffaaSAndy Whitcroft		}
22636c72ffaaSAndy Whitcroft		if (defined $1) {
22646c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
22656c72ffaaSAndy Whitcroft			$res .= $type x length($1);
22666c72ffaaSAndy Whitcroft		}
22676c72ffaaSAndy Whitcroft	}
22686c72ffaaSAndy Whitcroft
22691f65f947SAndy Whitcroft	return ($res, $var);
22706c72ffaaSAndy Whitcroft}
22716c72ffaaSAndy Whitcroft
22728905a67cSAndy Whitcroftsub possible {
227313214adfSAndy Whitcroft	my ($possible, $line) = @_;
22749a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
22750776e594SAndy Whitcroft		^(?:
22760776e594SAndy Whitcroft			$Modifier|
22770776e594SAndy Whitcroft			$Storage|
22780776e594SAndy Whitcroft			$Type|
22799a974fdbSAndy Whitcroft			DEFINE_\S+
22809a974fdbSAndy Whitcroft		)$|
22819a974fdbSAndy Whitcroft		^(?:
22820776e594SAndy Whitcroft			goto|
22830776e594SAndy Whitcroft			return|
22840776e594SAndy Whitcroft			case|
22850776e594SAndy Whitcroft			else|
22860776e594SAndy Whitcroft			asm|__asm__|
228789a88353SAndy Whitcroft			do|
228889a88353SAndy Whitcroft			\#|
228989a88353SAndy Whitcroft			\#\#|
22909a974fdbSAndy Whitcroft		)(?:\s|$)|
22910776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
22929a974fdbSAndy Whitcroft	    )}x;
22939a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
22949a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2295c45dcabdSAndy Whitcroft		# Check for modifiers.
2296c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2297c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2298c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2299c45dcabdSAndy Whitcroft
2300c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2301c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2302d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
23039a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2304d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2305485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2306d2506586SAndy Whitcroft				}
23079a974fdbSAndy Whitcroft			}
2308c45dcabdSAndy Whitcroft
2309c45dcabdSAndy Whitcroft		} else {
231013214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2311485ff23eSAlex Dowad			push(@typeListFile, $possible);
2312c45dcabdSAndy Whitcroft		}
23138905a67cSAndy Whitcroft		build_types();
23140776e594SAndy Whitcroft	} else {
23150776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
23168905a67cSAndy Whitcroft	}
23178905a67cSAndy Whitcroft}
23188905a67cSAndy Whitcroft
23196c72ffaaSAndy Whitcroftmy $prefix = '';
23206c72ffaaSAndy Whitcroft
2321000d1cc1SJoe Perchessub show_type {
2322cbec18afSJoe Perches	my ($type) = @_;
232391bfe484SJoe Perches
2324522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2325522b837cSAlexey Dobriyan
2326cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2327cbec18afSJoe Perches
2328cbec18afSJoe Perches	return !defined $ignore_type{$type};
2329000d1cc1SJoe Perches}
2330000d1cc1SJoe Perches
2331f0a594c1SAndy Whitcroftsub report {
2332cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2333cbec18afSJoe Perches
2334cbec18afSJoe Perches	if (!show_type($type) ||
2335cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2336773647a0SAndy Whitcroft		return 0;
2337773647a0SAndy Whitcroft	}
233857230297SJoe Perches	my $output = '';
2339737c0767SJohn Brooks	if ($color) {
234057230297SJoe Perches		if ($level eq 'ERROR') {
234157230297SJoe Perches			$output .= RED;
234257230297SJoe Perches		} elsif ($level eq 'WARNING') {
234357230297SJoe Perches			$output .= YELLOW;
2344000d1cc1SJoe Perches		} else {
234557230297SJoe Perches			$output .= GREEN;
2346000d1cc1SJoe Perches		}
234757230297SJoe Perches	}
234857230297SJoe Perches	$output .= $prefix . $level . ':';
234957230297SJoe Perches	if ($show_types) {
2350737c0767SJohn Brooks		$output .= BLUE if ($color);
235157230297SJoe Perches		$output .= "$type:";
235257230297SJoe Perches	}
2353737c0767SJohn Brooks	$output .= RESET if ($color);
235457230297SJoe Perches	$output .= ' ' . $msg . "\n";
235534d8815fSJoe Perches
235634d8815fSJoe Perches	if ($showfile) {
235734d8815fSJoe Perches		my @lines = split("\n", $output, -1);
235834d8815fSJoe Perches		splice(@lines, 1, 1);
235934d8815fSJoe Perches		$output = join("\n", @lines);
236034d8815fSJoe Perches	}
236152178ce0SDwaipayan Ray
236252178ce0SDwaipayan Ray	if ($terse) {
236352178ce0SDwaipayan Ray		$output = (split('\n', $output))[0] . "\n";
236452178ce0SDwaipayan Ray	}
236552178ce0SDwaipayan Ray
236652178ce0SDwaipayan Ray	if ($verbose && exists($verbose_messages{$type}) &&
236752178ce0SDwaipayan Ray	    !exists($verbose_emitted{$type})) {
236852178ce0SDwaipayan Ray		$output .= $verbose_messages{$type} . "\n\n";
236952178ce0SDwaipayan Ray		$verbose_emitted{$type} = 1;
237052178ce0SDwaipayan Ray	}
23718905a67cSAndy Whitcroft
237257230297SJoe Perches	push(our @report, $output);
2373773647a0SAndy Whitcroft
2374773647a0SAndy Whitcroft	return 1;
2375f0a594c1SAndy Whitcroft}
2376cbec18afSJoe Perches
2377f0a594c1SAndy Whitcroftsub report_dump {
237813214adfSAndy Whitcroft	our @report;
2379f0a594c1SAndy Whitcroft}
2380000d1cc1SJoe Perches
2381d752fcc8SJoe Perchessub fixup_current_range {
2382d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2383d752fcc8SJoe Perches
2384d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2385d752fcc8SJoe Perches		my $o = $1;
2386d752fcc8SJoe Perches		my $l = $2;
2387d752fcc8SJoe Perches		my $no = $o + $offset;
2388d752fcc8SJoe Perches		my $nl = $l + $length;
2389d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2390d752fcc8SJoe Perches	}
2391d752fcc8SJoe Perches}
2392d752fcc8SJoe Perches
2393d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2394d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2395d752fcc8SJoe Perches
2396d752fcc8SJoe Perches	my $range_last_linenr = 0;
2397d752fcc8SJoe Perches	my $delta_offset = 0;
2398d752fcc8SJoe Perches
2399d752fcc8SJoe Perches	my $old_linenr = 0;
2400d752fcc8SJoe Perches	my $new_linenr = 0;
2401d752fcc8SJoe Perches
2402d752fcc8SJoe Perches	my $next_insert = 0;
2403d752fcc8SJoe Perches	my $next_delete = 0;
2404d752fcc8SJoe Perches
2405d752fcc8SJoe Perches	my @lines = ();
2406d752fcc8SJoe Perches
2407d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2408d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2409d752fcc8SJoe Perches
2410d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2411d752fcc8SJoe Perches		my $save_line = 1;
2412d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2413323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2414d752fcc8SJoe Perches			$delta_offset = 0;
2415d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2416d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2417d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2418d752fcc8SJoe Perches		}
2419d752fcc8SJoe Perches
2420d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2421d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2422d752fcc8SJoe Perches			$save_line = 0;
2423d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2424d752fcc8SJoe Perches		}
2425d752fcc8SJoe Perches
2426d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2427d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2428d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2429d752fcc8SJoe Perches			$new_linenr++;
2430d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2431d752fcc8SJoe Perches		}
2432d752fcc8SJoe Perches
2433d752fcc8SJoe Perches		if ($save_line) {
2434d752fcc8SJoe Perches			push(@lines, $line);
2435d752fcc8SJoe Perches			$new_linenr++;
2436d752fcc8SJoe Perches		}
2437d752fcc8SJoe Perches
2438d752fcc8SJoe Perches		$old_linenr++;
2439d752fcc8SJoe Perches	}
2440d752fcc8SJoe Perches
2441d752fcc8SJoe Perches	return @lines;
2442d752fcc8SJoe Perches}
2443d752fcc8SJoe Perches
2444f2d7e4d4SJoe Perchessub fix_insert_line {
2445f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2446f2d7e4d4SJoe Perches
2447f2d7e4d4SJoe Perches	my $inserted = {
2448f2d7e4d4SJoe Perches		LINENR => $linenr,
2449f2d7e4d4SJoe Perches		LINE => $line,
2450f2d7e4d4SJoe Perches	};
2451f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2452f2d7e4d4SJoe Perches}
2453f2d7e4d4SJoe Perches
2454f2d7e4d4SJoe Perchessub fix_delete_line {
2455f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2456f2d7e4d4SJoe Perches
2457f2d7e4d4SJoe Perches	my $deleted = {
2458f2d7e4d4SJoe Perches		LINENR => $linenr,
2459f2d7e4d4SJoe Perches		LINE => $line,
2460f2d7e4d4SJoe Perches	};
2461f2d7e4d4SJoe Perches
2462f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2463f2d7e4d4SJoe Perches}
2464f2d7e4d4SJoe Perches
2465de7d4f0eSAndy Whitcroftsub ERROR {
2466cbec18afSJoe Perches	my ($type, $msg) = @_;
2467cbec18afSJoe Perches
2468cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2469de7d4f0eSAndy Whitcroft		our $clean = 0;
24706c72ffaaSAndy Whitcroft		our $cnt_error++;
24713705ce5bSJoe Perches		return 1;
2472de7d4f0eSAndy Whitcroft	}
24733705ce5bSJoe Perches	return 0;
2474773647a0SAndy Whitcroft}
2475de7d4f0eSAndy Whitcroftsub WARN {
2476cbec18afSJoe Perches	my ($type, $msg) = @_;
2477cbec18afSJoe Perches
2478cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2479de7d4f0eSAndy Whitcroft		our $clean = 0;
24806c72ffaaSAndy Whitcroft		our $cnt_warn++;
24813705ce5bSJoe Perches		return 1;
2482de7d4f0eSAndy Whitcroft	}
24833705ce5bSJoe Perches	return 0;
2484773647a0SAndy Whitcroft}
2485de7d4f0eSAndy Whitcroftsub CHK {
2486cbec18afSJoe Perches	my ($type, $msg) = @_;
2487cbec18afSJoe Perches
2488cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2489de7d4f0eSAndy Whitcroft		our $clean = 0;
24906c72ffaaSAndy Whitcroft		our $cnt_chk++;
24913705ce5bSJoe Perches		return 1;
24926c72ffaaSAndy Whitcroft	}
24933705ce5bSJoe Perches	return 0;
2494de7d4f0eSAndy Whitcroft}
2495de7d4f0eSAndy Whitcroft
24966ecd9674SAndy Whitcroftsub check_absolute_file {
24976ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
24986ecd9674SAndy Whitcroft	my $file = $absolute;
24996ecd9674SAndy Whitcroft
25006ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
25016ecd9674SAndy Whitcroft
25026ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
25036ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
25046ecd9674SAndy Whitcroft		if (-f "$root/$file") {
25056ecd9674SAndy Whitcroft			##print "file<$file>\n";
25066ecd9674SAndy Whitcroft			last;
25076ecd9674SAndy Whitcroft		}
25086ecd9674SAndy Whitcroft	}
25096ecd9674SAndy Whitcroft	if (! -f _)  {
25106ecd9674SAndy Whitcroft		return 0;
25116ecd9674SAndy Whitcroft	}
25126ecd9674SAndy Whitcroft
25136ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
25146ecd9674SAndy Whitcroft	my $prefix = $absolute;
25156ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
25166ecd9674SAndy Whitcroft
25176ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
25186ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2519000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2520000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
25216ecd9674SAndy Whitcroft	}
25226ecd9674SAndy Whitcroft}
25236ecd9674SAndy Whitcroft
25243705ce5bSJoe Perchessub trim {
25253705ce5bSJoe Perches	my ($string) = @_;
25263705ce5bSJoe Perches
2527b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2528b34c648bSJoe Perches
2529b34c648bSJoe Perches	return $string;
2530b34c648bSJoe Perches}
2531b34c648bSJoe Perches
2532b34c648bSJoe Perchessub ltrim {
2533b34c648bSJoe Perches	my ($string) = @_;
2534b34c648bSJoe Perches
2535b34c648bSJoe Perches	$string =~ s/^\s+//;
2536b34c648bSJoe Perches
2537b34c648bSJoe Perches	return $string;
2538b34c648bSJoe Perches}
2539b34c648bSJoe Perches
2540b34c648bSJoe Perchessub rtrim {
2541b34c648bSJoe Perches	my ($string) = @_;
2542b34c648bSJoe Perches
2543b34c648bSJoe Perches	$string =~ s/\s+$//;
25443705ce5bSJoe Perches
25453705ce5bSJoe Perches	return $string;
25463705ce5bSJoe Perches}
25473705ce5bSJoe Perches
254852ea8506SJoe Perchessub string_find_replace {
254952ea8506SJoe Perches	my ($string, $find, $replace) = @_;
255052ea8506SJoe Perches
255152ea8506SJoe Perches	$string =~ s/$find/$replace/g;
255252ea8506SJoe Perches
255352ea8506SJoe Perches	return $string;
255452ea8506SJoe Perches}
255552ea8506SJoe Perches
25563705ce5bSJoe Perchessub tabify {
25573705ce5bSJoe Perches	my ($leading) = @_;
25583705ce5bSJoe Perches
2559713a09deSAntonio Borneo	my $source_indent = $tabsize;
25603705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
25613705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
25623705ce5bSJoe Perches
25633705ce5bSJoe Perches	#convert leading spaces to tabs
25643705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
25653705ce5bSJoe Perches	#Remove spaces before a tab
25663705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
25673705ce5bSJoe Perches
25683705ce5bSJoe Perches	return "$leading";
25693705ce5bSJoe Perches}
25703705ce5bSJoe Perches
2571d1fe9c09SJoe Perchessub pos_last_openparen {
2572d1fe9c09SJoe Perches	my ($line) = @_;
2573d1fe9c09SJoe Perches
2574d1fe9c09SJoe Perches	my $pos = 0;
2575d1fe9c09SJoe Perches
2576d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2577d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2578d1fe9c09SJoe Perches
2579d1fe9c09SJoe Perches	my $last_openparen = 0;
2580d1fe9c09SJoe Perches
2581d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2582d1fe9c09SJoe Perches		return -1;
2583d1fe9c09SJoe Perches	}
2584d1fe9c09SJoe Perches
2585d1fe9c09SJoe Perches	my $len = length($line);
2586d1fe9c09SJoe Perches
2587d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2588d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2589d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2590d1fe9c09SJoe Perches			$pos += length($1) - 1;
2591d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2592d1fe9c09SJoe Perches			$last_openparen = $pos;
2593d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2594d1fe9c09SJoe Perches			last;
2595d1fe9c09SJoe Perches		}
2596d1fe9c09SJoe Perches	}
2597d1fe9c09SJoe Perches
259891cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2599d1fe9c09SJoe Perches}
2600d1fe9c09SJoe Perches
2601f36d3eb8SJoe Perchessub get_raw_comment {
2602f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2603f36d3eb8SJoe Perches	my $comment = '';
2604f36d3eb8SJoe Perches
2605f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2606f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2607f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2608f36d3eb8SJoe Perches		}
2609f36d3eb8SJoe Perches	}
2610f36d3eb8SJoe Perches
2611f36d3eb8SJoe Perches	return $comment;
2612f36d3eb8SJoe Perches}
2613f36d3eb8SJoe Perches
26145b8f82e1SSong Liusub exclude_global_initialisers {
26155b8f82e1SSong Liu	my ($realfile) = @_;
26165b8f82e1SSong Liu
26175b8f82e1SSong Liu	# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).
26185b8f82e1SSong Liu	return $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\.c$@ ||
26195b8f82e1SSong Liu		$realfile =~ m@^samples/bpf/.*_kern\.c$@ ||
26205b8f82e1SSong Liu		$realfile =~ m@/bpf/.*\.bpf\.c$@;
26215b8f82e1SSong Liu}
26225b8f82e1SSong Liu
26230a920b5bSAndy Whitcroftsub process {
26240a920b5bSAndy Whitcroft	my $filename = shift;
26250a920b5bSAndy Whitcroft
26260a920b5bSAndy Whitcroft	my $linenr=0;
26270a920b5bSAndy Whitcroft	my $prevline="";
2628c2fdda0dSAndy Whitcroft	my $prevrawline="";
26290a920b5bSAndy Whitcroft	my $stashline="";
2630c2fdda0dSAndy Whitcroft	my $stashrawline="";
26310a920b5bSAndy Whitcroft
26324a0df2efSAndy Whitcroft	my $length;
26330a920b5bSAndy Whitcroft	my $indent;
26340a920b5bSAndy Whitcroft	my $previndent=0;
26350a920b5bSAndy Whitcroft	my $stashindent=0;
26360a920b5bSAndy Whitcroft
2637de7d4f0eSAndy Whitcroft	our $clean = 1;
26380a920b5bSAndy Whitcroft	my $signoff = 0;
2639cd261496SGeert Uytterhoeven	my $author = '';
2640cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
264148ca2d8aSDwaipayan Ray	my $author_sob = '';
26420a920b5bSAndy Whitcroft	my $is_patch = 0;
2643133712a2SRob Herring	my $is_binding_patch = -1;
264429ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
264515662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
264644d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2647ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2648490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2649bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
26502a076f40SJoe Perches	my $commit_log_long_line = 0;
2651e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
265213f1937eSJoe Perches	my $reported_maintainer_file = 0;
2653fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2654fa64205dSPasi Savanainen
26554ce9f970SJoe Perches	my $last_git_commit_id_linenr = -1;
26564ce9f970SJoe Perches
2657365dd4eaSJoe Perches	my $last_blank_line = 0;
26585e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2659365dd4eaSJoe Perches
266013214adfSAndy Whitcroft	our @report = ();
26616c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
26626c72ffaaSAndy Whitcroft	our $cnt_error = 0;
26636c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
26646c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
26656c72ffaaSAndy Whitcroft
26660a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
26670a920b5bSAndy Whitcroft	my $realfile = '';
26680a920b5bSAndy Whitcroft	my $realline = 0;
26690a920b5bSAndy Whitcroft	my $realcnt = 0;
26700a920b5bSAndy Whitcroft	my $here = '';
267177cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
26720a920b5bSAndy Whitcroft	my $in_comment = 0;
2673c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
26740a920b5bSAndy Whitcroft	my $first_line = 0;
26751e855726SWolfram Sang	my $p1_prefix = '';
26760a920b5bSAndy Whitcroft
267713214adfSAndy Whitcroft	my $prev_values = 'E';
267813214adfSAndy Whitcroft
267913214adfSAndy Whitcroft	# suppression flags
2680773647a0SAndy Whitcroft	my %suppress_ifbraces;
2681170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
26822b474a1aSAndy Whitcroft	my %suppress_export;
26833e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2684653d4876SAndy Whitcroft
26857e51f197SJoe Perches	my %signatures = ();
2686323c1260SJoe Perches
2687c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2688de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2689c2fdda0dSAndy Whitcroft	#
2690de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2691de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2692773647a0SAndy Whitcroft
2693d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2694d8b07710SJoe Perches
26959f3a8992SRob Herring	my $checklicenseline = 1;
26969f3a8992SRob Herring
2697773647a0SAndy Whitcroft	sanitise_line_reset();
2698c2fdda0dSAndy Whitcroft	my $line;
2699c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2700773647a0SAndy Whitcroft		$linenr++;
2701773647a0SAndy Whitcroft		$line = $rawline;
2702c2fdda0dSAndy Whitcroft
27033705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
27043705ce5bSJoe Perches
2705773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2706de7d4f0eSAndy Whitcroft			$setup_docs = 0;
27072581ac7cSTim Froidcoeur			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {
2708de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2709de7d4f0eSAndy Whitcroft			}
2710773647a0SAndy Whitcroft			#next;
2711de7d4f0eSAndy Whitcroft		}
271274fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2713773647a0SAndy Whitcroft			$realline=$1-1;
2714773647a0SAndy Whitcroft			if (defined $2) {
2715773647a0SAndy Whitcroft				$realcnt=$3+1;
2716773647a0SAndy Whitcroft			} else {
2717773647a0SAndy Whitcroft				$realcnt=1+1;
2718773647a0SAndy Whitcroft			}
2719c45dcabdSAndy Whitcroft			$in_comment = 0;
2720773647a0SAndy Whitcroft
2721773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2722773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2723773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2724773647a0SAndy Whitcroft			# at context start.
2725773647a0SAndy Whitcroft			my $edge;
272601fa9147SAndy Whitcroft			my $cnt = $realcnt;
272701fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
272801fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
272901fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
273001fa9147SAndy Whitcroft				$cnt--;
273101fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2732721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2733fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2734fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2735fae17daeSAndy Whitcroft					($edge) = $1;
2736fae17daeSAndy Whitcroft					last;
2737fae17daeSAndy Whitcroft				}
2738773647a0SAndy Whitcroft			}
2739773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2740773647a0SAndy Whitcroft				$in_comment = 1;
2741773647a0SAndy Whitcroft			}
2742773647a0SAndy Whitcroft
2743773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2744773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2745773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2746773647a0SAndy Whitcroft			if (!defined $edge &&
274783242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2748773647a0SAndy Whitcroft			{
2749773647a0SAndy Whitcroft				$in_comment = 1;
2750773647a0SAndy Whitcroft			}
2751773647a0SAndy Whitcroft
2752773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2753773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2754773647a0SAndy Whitcroft
2755171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2756773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2757171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2758773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2759773647a0SAndy Whitcroft		}
2760773647a0SAndy Whitcroft		push(@lines, $line);
2761773647a0SAndy Whitcroft
2762773647a0SAndy Whitcroft		if ($realcnt > 1) {
2763773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2764773647a0SAndy Whitcroft		} else {
2765773647a0SAndy Whitcroft			$realcnt = 0;
2766773647a0SAndy Whitcroft		}
2767773647a0SAndy Whitcroft
2768773647a0SAndy Whitcroft		#print "==>$rawline\n";
2769773647a0SAndy Whitcroft		#print "-->$line\n";
2770de7d4f0eSAndy Whitcroft
2771de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2772de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2773de7d4f0eSAndy Whitcroft		}
2774de7d4f0eSAndy Whitcroft	}
2775de7d4f0eSAndy Whitcroft
27766c72ffaaSAndy Whitcroft	$prefix = '';
27776c72ffaaSAndy Whitcroft
2778773647a0SAndy Whitcroft	$realcnt = 0;
2779773647a0SAndy Whitcroft	$linenr = 0;
2780194f66fcSJoe Perches	$fixlinenr = -1;
27810a920b5bSAndy Whitcroft	foreach my $line (@lines) {
27820a920b5bSAndy Whitcroft		$linenr++;
2783194f66fcSJoe Perches		$fixlinenr++;
27841b5539b1SJoe Perches		my $sline = $line;	#copy of $line
27851b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
27860a920b5bSAndy Whitcroft
2787c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2788f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
27896c72ffaaSAndy Whitcroft
279012c253abSJoe Perches# check if it's a mode change, rename or start of a patch
279112c253abSJoe Perches		if (!$in_commit_log &&
279212c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
279312c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
279412c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
279512c253abSJoe Perches			$is_patch = 1;
279612c253abSJoe Perches		}
279712c253abSJoe Perches
27980a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2799e518e9a5SJoe Perches		if (!$in_commit_log &&
280074fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
280174fd4f34SJoe Perches			my $context = $4;
28020a920b5bSAndy Whitcroft			$is_patch = 1;
28034a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
28040a920b5bSAndy Whitcroft			$realline=$1-1;
28050a920b5bSAndy Whitcroft			if (defined $2) {
28060a920b5bSAndy Whitcroft				$realcnt=$3+1;
28070a920b5bSAndy Whitcroft			} else {
28080a920b5bSAndy Whitcroft				$realcnt=1+1;
28090a920b5bSAndy Whitcroft			}
2810c2fdda0dSAndy Whitcroft			annotate_reset();
281113214adfSAndy Whitcroft			$prev_values = 'E';
281213214adfSAndy Whitcroft
2813773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2814170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
28152b474a1aSAndy Whitcroft			%suppress_export = ();
28163e469cdcSAndy Whitcroft			$suppress_statement = 0;
281774fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
281874fd4f34SJoe Perches				$context_function = $1;
281974fd4f34SJoe Perches			} else {
282074fd4f34SJoe Perches				undef $context_function;
282174fd4f34SJoe Perches			}
28220a920b5bSAndy Whitcroft			next;
28230a920b5bSAndy Whitcroft
28244a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
28254a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
28264a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2827773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
28280a920b5bSAndy Whitcroft			$realline++;
2829d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
28300a920b5bSAndy Whitcroft
28314a0df2efSAndy Whitcroft			# Measure the line length and indent.
2832c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
28330a920b5bSAndy Whitcroft
28340a920b5bSAndy Whitcroft			# Track the previous line.
28350a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
28360a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2837c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2838c2fdda0dSAndy Whitcroft
2839773647a0SAndy Whitcroft			#warn "line<$line>\n";
28406c72ffaaSAndy Whitcroft
2841d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2842d8aaf121SAndy Whitcroft			$realcnt--;
28430a920b5bSAndy Whitcroft		}
28440a920b5bSAndy Whitcroft
2845cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2846cc77cdcaSAndy Whitcroft
28476c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
28486c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2849773647a0SAndy Whitcroft
28502ac73b4fSJoe Perches		my $found_file = 0;
2851773647a0SAndy Whitcroft		# extract the filename as it passes
28523bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
28533bf9a009SRabin Vincent			$realfile = $1;
28542b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2855270c49a0SJoe Perches			$in_commit_log = 0;
28562ac73b4fSJoe Perches			$found_file = 1;
28573bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2858773647a0SAndy Whitcroft			$realfile = $1;
28592b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2860270c49a0SJoe Perches			$in_commit_log = 0;
28611e855726SWolfram Sang
28621e855726SWolfram Sang			$p1_prefix = $1;
2863e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2864e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2865000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2866000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
28671e855726SWolfram Sang			}
2868773647a0SAndy Whitcroft
2869c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2870000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2871000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2872773647a0SAndy Whitcroft			}
28732ac73b4fSJoe Perches			$found_file = 1;
28742ac73b4fSJoe Perches		}
28752ac73b4fSJoe Perches
287634d8815fSJoe Perches#make up the handle for any error we report on this line
287734d8815fSJoe Perches		if ($showfile) {
287834d8815fSJoe Perches			$prefix = "$realfile:$realline: "
287934d8815fSJoe Perches		} elsif ($emacs) {
28807d3a9f67SJoe Perches			if ($file) {
28817d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
28827d3a9f67SJoe Perches			} else {
288334d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
288434d8815fSJoe Perches			}
28857d3a9f67SJoe Perches		}
288634d8815fSJoe Perches
28872ac73b4fSJoe Perches		if ($found_file) {
288885b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
288985b0ee18SJoe Perches				WARN("OBSOLETE",
289085b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
289185b0ee18SJoe Perches			}
28927bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
28932ac73b4fSJoe Perches				$check = 1;
28942ac73b4fSJoe Perches			} else {
28952ac73b4fSJoe Perches				$check = $check_orig;
28962ac73b4fSJoe Perches			}
28979f3a8992SRob Herring			$checklicenseline = 1;
2898133712a2SRob Herring
2899133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2900133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2901133712a2SRob Herring
2902133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2903133712a2SRob Herring
2904133712a2SRob Herring				if (($last_binding_patch != -1) &&
2905133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2906133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2907858e6845SMauro Carvalho Chehab					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n");
2908133712a2SRob Herring				}
2909133712a2SRob Herring			}
2910133712a2SRob Herring
2911773647a0SAndy Whitcroft			next;
2912773647a0SAndy Whitcroft		}
2913773647a0SAndy Whitcroft
2914389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
29150a920b5bSAndy Whitcroft
2916c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2917c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2918c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
29190a920b5bSAndy Whitcroft
29206c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
29216c72ffaaSAndy Whitcroft
2922490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2923490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2924490b292cSJoe Perches		if ($in_commit_log) {
2925490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2926490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2927490b292cSJoe Perches			}
2928490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2929490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2930490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2931490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2932490b292cSJoe Perches		}
2933490b292cSJoe Perches
2934e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2935e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
293613e45417SMrinal Pandey		    (($line =~ m@^\s+diff\b.*a/([\w/]+)@ &&
293713e45417SMrinal Pandey		      $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) ||
2938e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2939e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2940e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2941e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2942e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2943e518e9a5SJoe Perches		}
2944e518e9a5SJoe Perches
29453bf9a009SRabin Vincent# Check for incorrect file permissions
29463bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
29473bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
294804db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
294904db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2950000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2951000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
29523bf9a009SRabin Vincent			}
29533bf9a009SRabin Vincent		}
29543bf9a009SRabin Vincent
2955cd261496SGeert Uytterhoeven# Check the patch for a From:
2956cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2957cd261496SGeert Uytterhoeven			$author = $1;
2958e7f929f3SDwaipayan Ray			my $curline = $linenr;
2959e7f929f3SDwaipayan Ray			while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) {
2960e7f929f3SDwaipayan Ray				$author .= $1;
2961e7f929f3SDwaipayan Ray			}
2962cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2963cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2964dfa05c28SJoe Perches			$author = reformat_email($author);
2965cd261496SGeert Uytterhoeven		}
2966cd261496SGeert Uytterhoeven
296720112475SJoe Perches# Check the patch for a signoff:
2968dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
29694a0df2efSAndy Whitcroft			$signoff++;
297015662b3eSJoe Perches			$in_commit_log = 0;
297148ca2d8aSDwaipayan Ray			if ($author ne ''  && $authorsignoff != 1) {
2972fccaebf0SDwaipayan Ray				if (same_email_addresses($1, $author)) {
2973cd261496SGeert Uytterhoeven					$authorsignoff = 1;
297448ca2d8aSDwaipayan Ray				} else {
297548ca2d8aSDwaipayan Ray					my $ctx = $1;
297648ca2d8aSDwaipayan Ray					my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);
297748ca2d8aSDwaipayan Ray					my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);
297848ca2d8aSDwaipayan Ray
2979046fc741SMimi Zohar					if (lc $email_address eq lc $author_address && $email_name eq $author_name) {
298048ca2d8aSDwaipayan Ray						$author_sob = $ctx;
298148ca2d8aSDwaipayan Ray						$authorsignoff = 2;
2982046fc741SMimi Zohar					} elsif (lc $email_address eq lc $author_address) {
298348ca2d8aSDwaipayan Ray						$author_sob = $ctx;
298448ca2d8aSDwaipayan Ray						$authorsignoff = 3;
298548ca2d8aSDwaipayan Ray					} elsif ($email_name eq $author_name) {
298648ca2d8aSDwaipayan Ray						$author_sob = $ctx;
298748ca2d8aSDwaipayan Ray						$authorsignoff = 4;
298848ca2d8aSDwaipayan Ray
298948ca2d8aSDwaipayan Ray						my $address1 = $email_address;
299048ca2d8aSDwaipayan Ray						my $address2 = $author_address;
299148ca2d8aSDwaipayan Ray
299248ca2d8aSDwaipayan Ray						if ($address1 =~ /(\S+)\+\S+(\@.*)/) {
299348ca2d8aSDwaipayan Ray							$address1 = "$1$2";
299448ca2d8aSDwaipayan Ray						}
299548ca2d8aSDwaipayan Ray						if ($address2 =~ /(\S+)\+\S+(\@.*)/) {
299648ca2d8aSDwaipayan Ray							$address2 = "$1$2";
299748ca2d8aSDwaipayan Ray						}
299848ca2d8aSDwaipayan Ray						if ($address1 eq $address2) {
299948ca2d8aSDwaipayan Ray							$authorsignoff = 5;
300048ca2d8aSDwaipayan Ray						}
300148ca2d8aSDwaipayan Ray					}
3002cd261496SGeert Uytterhoeven				}
3003cd261496SGeert Uytterhoeven			}
30040a920b5bSAndy Whitcroft		}
300520112475SJoe Perches
300644d303ebSJoe Perches# Check for patch separator
300744d303ebSJoe Perches		if ($line =~ /^---$/) {
300844d303ebSJoe Perches			$has_patch_separator = 1;
300944d303ebSJoe Perches			$in_commit_log = 0;
301044d303ebSJoe Perches		}
301144d303ebSJoe Perches
3012e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
3013e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
3014e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
3015e0d975b1SJoe Perches			$reported_maintainer_file = 1;
3016e0d975b1SJoe Perches		}
3017e0d975b1SJoe Perches
301820112475SJoe Perches# Check signature styles
3019270c49a0SJoe Perches		if (!$in_header_lines &&
3020ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
302120112475SJoe Perches			my $space_before = $1;
302220112475SJoe Perches			my $sign_off = $2;
302320112475SJoe Perches			my $space_after = $3;
302420112475SJoe Perches			my $email = $4;
302520112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
302620112475SJoe Perches
3027ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
3028831242abSAditya Srivastava				my $suggested_signature = find_standard_signature($sign_off);
3029831242abSAditya Srivastava				if ($suggested_signature eq "") {
3030ce0338dfSJoe Perches					WARN("BAD_SIGN_OFF",
3031ce0338dfSJoe Perches					     "Non-standard signature: $sign_off\n" . $herecurr);
3032831242abSAditya Srivastava				} else {
3033831242abSAditya Srivastava					if (WARN("BAD_SIGN_OFF",
3034831242abSAditya Srivastava						 "Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\n" . $herecurr) &&
3035831242abSAditya Srivastava					    $fix) {
3036831242abSAditya Srivastava						$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;
3037831242abSAditya Srivastava					}
3038831242abSAditya Srivastava				}
3039ce0338dfSJoe Perches			}
304020112475SJoe Perches			if (defined $space_before && $space_before ne "") {
30413705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30423705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
30433705ce5bSJoe Perches				    $fix) {
3044194f66fcSJoe Perches					$fixed[$fixlinenr] =
30453705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30463705ce5bSJoe Perches				}
304720112475SJoe Perches			}
304820112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
30493705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30503705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
30513705ce5bSJoe Perches				    $fix) {
3052194f66fcSJoe Perches					$fixed[$fixlinenr] =
30533705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30543705ce5bSJoe Perches				}
30553705ce5bSJoe Perches
305620112475SJoe Perches			}
305720112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
30583705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
30593705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
30603705ce5bSJoe Perches				    $fix) {
3061194f66fcSJoe Perches					$fixed[$fixlinenr] =
30623705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
30633705ce5bSJoe Perches				}
306420112475SJoe Perches			}
306520112475SJoe Perches
3066dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
306748ca2d8aSDwaipayan Ray			my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));
306820112475SJoe Perches			if ($suggested_email eq "") {
3069000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
3070000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
307120112475SJoe Perches			} else {
307220112475SJoe Perches				my $dequoted = $suggested_email;
307320112475SJoe Perches				$dequoted =~ s/^"//;
307420112475SJoe Perches				$dequoted =~ s/" </ </;
307520112475SJoe Perches				# Don't force email to have quotes
307620112475SJoe Perches				# Allow just an angle bracketed address
3077fccaebf0SDwaipayan Ray				if (!same_email_addresses($email, $suggested_email)) {
3078fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3079fccaebf0SDwaipayan Ray						 "email address '$email' might be better as '$suggested_email'\n" . $herecurr) &&
3080fccaebf0SDwaipayan Ray					    $fix) {
3081fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$suggested_email/;
3082fccaebf0SDwaipayan Ray					}
3083fccaebf0SDwaipayan Ray				}
3084fccaebf0SDwaipayan Ray
3085fccaebf0SDwaipayan Ray				# Address part shouldn't have comments
3086fccaebf0SDwaipayan Ray				my $stripped_address = $email_address;
3087fccaebf0SDwaipayan Ray				$stripped_address =~ s/\([^\(\)]*\)//g;
3088fccaebf0SDwaipayan Ray				if ($email_address ne $stripped_address) {
3089fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3090fccaebf0SDwaipayan Ray						 "address part of email should not have comments: '$email_address'\n" . $herecurr) &&
3091fccaebf0SDwaipayan Ray					    $fix) {
3092fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email_address\E/$stripped_address/;
3093fccaebf0SDwaipayan Ray					}
3094fccaebf0SDwaipayan Ray				}
3095fccaebf0SDwaipayan Ray
3096fccaebf0SDwaipayan Ray				# Only one name comment should be allowed
3097fccaebf0SDwaipayan Ray				my $comment_count = () = $name_comment =~ /\([^\)]+\)/g;
3098fccaebf0SDwaipayan Ray				if ($comment_count > 1) {
3099000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
3100fccaebf0SDwaipayan Ray					     "Use a single name comment in email: '$email'\n" . $herecurr);
3101fccaebf0SDwaipayan Ray				}
3102fccaebf0SDwaipayan Ray
3103fccaebf0SDwaipayan Ray
3104fccaebf0SDwaipayan Ray				# [email protected] or [email protected] shouldn't
3105e73d2715SDwaipayan Ray				# have an email name. In addition comments should strictly
3106fccaebf0SDwaipayan Ray				# begin with a #
3107fccaebf0SDwaipayan Ray				if ($email =~ /^.*stable\@(?:vger\.)?kernel\.org/i) {
3108fccaebf0SDwaipayan Ray					if (($comment ne "" && $comment !~ /^#.+/) ||
3109fccaebf0SDwaipayan Ray					    ($email_name ne "")) {
3110fccaebf0SDwaipayan Ray						my $cur_name = $email_name;
3111fccaebf0SDwaipayan Ray						my $new_comment = $comment;
3112fccaebf0SDwaipayan Ray						$cur_name =~ s/[a-zA-Z\s\-\"]+//g;
3113fccaebf0SDwaipayan Ray
3114fccaebf0SDwaipayan Ray						# Remove brackets enclosing comment text
3115fccaebf0SDwaipayan Ray						# and # from start of comments to get comment text
3116fccaebf0SDwaipayan Ray						$new_comment =~ s/^\((.*)\)$/$1/;
3117fccaebf0SDwaipayan Ray						$new_comment =~ s/^\[(.*)\]$/$1/;
3118fccaebf0SDwaipayan Ray						$new_comment =~ s/^[\s\#]+|\s+$//g;
3119fccaebf0SDwaipayan Ray
3120fccaebf0SDwaipayan Ray						$new_comment = trim("$new_comment $cur_name") if ($cur_name ne $new_comment);
3121fccaebf0SDwaipayan Ray						$new_comment = " # $new_comment" if ($new_comment ne "");
3122fccaebf0SDwaipayan Ray						my $new_email = "$email_address$new_comment";
3123fccaebf0SDwaipayan Ray
3124fccaebf0SDwaipayan Ray						if (WARN("BAD_STABLE_ADDRESS_STYLE",
3125fccaebf0SDwaipayan Ray							 "Invalid email format for stable: '$email', prefer '$new_email'\n" . $herecurr) &&
3126fccaebf0SDwaipayan Ray						    $fix) {
3127fccaebf0SDwaipayan Ray							$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3128fccaebf0SDwaipayan Ray						}
3129fccaebf0SDwaipayan Ray					}
3130fccaebf0SDwaipayan Ray				} elsif ($comment ne "" && $comment !~ /^(?:#.+|\(.+\))$/) {
3131fccaebf0SDwaipayan Ray					my $new_comment = $comment;
3132fccaebf0SDwaipayan Ray
3133fccaebf0SDwaipayan Ray					# Extract comment text from within brackets or
3134fccaebf0SDwaipayan Ray					# c89 style /*...*/ comments
3135fccaebf0SDwaipayan Ray					$new_comment =~ s/^\[(.*)\]$/$1/;
3136fccaebf0SDwaipayan Ray					$new_comment =~ s/^\/\*(.*)\*\/$/$1/;
3137fccaebf0SDwaipayan Ray
3138fccaebf0SDwaipayan Ray					$new_comment = trim($new_comment);
3139fccaebf0SDwaipayan Ray					$new_comment =~ s/^[^\w]$//; # Single lettered comment with non word character is usually a typo
3140fccaebf0SDwaipayan Ray					$new_comment = "($new_comment)" if ($new_comment ne "");
3141fccaebf0SDwaipayan Ray					my $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);
3142fccaebf0SDwaipayan Ray
3143fccaebf0SDwaipayan Ray					if (WARN("BAD_SIGN_OFF",
3144fccaebf0SDwaipayan Ray						 "Unexpected content after email: '$email', should be: '$new_email'\n" . $herecurr) &&
3145fccaebf0SDwaipayan Ray					    $fix) {
3146fccaebf0SDwaipayan Ray						$fixed[$fixlinenr] =~ s/\Q$email\E/$new_email/;
3147fccaebf0SDwaipayan Ray					}
314820112475SJoe Perches				}
31490a920b5bSAndy Whitcroft			}
31507e51f197SJoe Perches
31517e51f197SJoe Perches# Check for duplicate signatures
31527e51f197SJoe Perches			my $sig_nospace = $line;
31537e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
31547e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
31557e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
31567e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
31577e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
31587e51f197SJoe Perches			} else {
31597e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
31607e51f197SJoe Perches			}
31616c5d24eeSSean Christopherson
31626c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
31636c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
31646c5d24eeSSean Christopherson				if ($email eq $author) {
31656c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31661916f777SThorsten Leemhuis					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr);
31676c5d24eeSSean Christopherson				}
31686c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
31696c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31701916f777SThorsten Leemhuis					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
31711916f777SThorsten Leemhuis				} elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
31726c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31731916f777SThorsten Leemhuis					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n");
31746c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
31756c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
31761916f777SThorsten Leemhuis					     "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n");
31776c5d24eeSSean Christopherson				}
31786c5d24eeSSean Christopherson			}
3179d7f1d71eSKai Wasserbäch
318044c31888SMatthieu Baerts# check if Reported-by: is followed by a Closes: tag
3181d7f1d71eSKai Wasserbäch			if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) {
3182d7f1d71eSKai Wasserbäch				if (!defined $lines[$linenr]) {
3183d7f1d71eSKai Wasserbäch					WARN("BAD_REPORTED_BY_LINK",
318444c31888SMatthieu Baerts					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . "\n");
3185d6ccdd67SMatthieu Baerts				} elsif ($rawlines[$linenr] !~ /^closes:\s*/i) {
3186d7f1d71eSKai Wasserbäch					WARN("BAD_REPORTED_BY_LINK",
318744c31888SMatthieu Baerts					     "Reported-by: should be immediately followed by Closes: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
31880a920b5bSAndy Whitcroft				}
3189d7f1d71eSKai Wasserbäch			}
3190d7f1d71eSKai Wasserbäch		}
3191d7f1d71eSKai Wasserbäch
31920a920b5bSAndy Whitcroft
3193bd17e036SNiklas Söderlund# Check Fixes: styles is correct
3194bd17e036SNiklas Söderlund		if (!$in_header_lines &&
3195bd17e036SNiklas Söderlund		    $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
3196bd17e036SNiklas Söderlund			my $orig_commit = "";
3197bd17e036SNiklas Söderlund			my $id = "0123456789ab";
3198bd17e036SNiklas Söderlund			my $title = "commit title";
3199bd17e036SNiklas Söderlund			my $tag_case = 1;
3200bd17e036SNiklas Söderlund			my $tag_space = 1;
3201bd17e036SNiklas Söderlund			my $id_length = 1;
3202bd17e036SNiklas Söderlund			my $id_case = 1;
3203bd17e036SNiklas Söderlund			my $title_has_quotes = 0;
3204bd17e036SNiklas Söderlund
3205bd17e036SNiklas Söderlund			if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) {
3206bd17e036SNiklas Söderlund				my $tag = $1;
3207bd17e036SNiklas Söderlund				$orig_commit = $2;
3208bd17e036SNiklas Söderlund				$title = $3;
3209bd17e036SNiklas Söderlund
3210bd17e036SNiklas Söderlund				$tag_case = 0 if $tag eq "Fixes:";
3211bd17e036SNiklas Söderlund				$tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i);
3212bd17e036SNiklas Söderlund
3213bd17e036SNiklas Söderlund				$id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i);
3214bd17e036SNiklas Söderlund				$id_case = 0 if ($orig_commit !~ /[A-F]/);
3215bd17e036SNiklas Söderlund
3216bd17e036SNiklas Söderlund				# Always strip leading/trailing parens then double quotes if existing
3217bd17e036SNiklas Söderlund				$title = substr($title, 1, -1);
3218bd17e036SNiklas Söderlund				if ($title =~ /^".*"$/) {
3219bd17e036SNiklas Söderlund					$title = substr($title, 1, -1);
3220bd17e036SNiklas Söderlund					$title_has_quotes = 1;
3221bd17e036SNiklas Söderlund				}
3222bd17e036SNiklas Söderlund			}
3223bd17e036SNiklas Söderlund
3224bd17e036SNiklas Söderlund			my ($cid, $ctitle) = git_commit_info($orig_commit, $id,
3225bd17e036SNiklas Söderlund							     $title);
3226bd17e036SNiklas Söderlund
3227bd17e036SNiklas Söderlund			if ($ctitle ne $title || $tag_case || $tag_space ||
3228bd17e036SNiklas Söderlund			    $id_length || $id_case || !$title_has_quotes) {
3229bd17e036SNiklas Söderlund				if (WARN("BAD_FIXES_TAG",
3230bd17e036SNiklas Söderlund				     "Please use correct Fixes: style 'Fixes: <12 chars of sha1> (\"<title line>\")' - ie: 'Fixes: $cid (\"$ctitle\")'\n" . $herecurr) &&
3231bd17e036SNiklas Söderlund				    $fix) {
3232bd17e036SNiklas Söderlund					$fixed[$fixlinenr] = "Fixes: $cid (\"$ctitle\")";
3233bd17e036SNiklas Söderlund				}
3234bd17e036SNiklas Söderlund			}
3235bd17e036SNiklas Söderlund		}
3236bd17e036SNiklas Söderlund
3237a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
3238a2fe16b9SJoe Perches		if ($in_header_lines &&
3239a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
3240a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
3241a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
3242a2fe16b9SJoe Perches		}
3243a2fe16b9SJoe Perches
324444d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
324544d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
32467580c5b9SAditya Srivastava			if (ERROR("GERRIT_CHANGE_ID",
32477580c5b9SAditya Srivastava			          "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr) &&
32487580c5b9SAditya Srivastava			    $fix) {
32497580c5b9SAditya Srivastava				fix_delete_line($fixlinenr, $rawline);
32507580c5b9SAditya Srivastava			}
32517ebd05efSChristopher Covington		}
32527ebd05efSChristopher Covington
3253369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
3254369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
3255369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
3256369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
3257369c8dd3SJoe Perches					# timestamp
3258634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
3259634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
3260634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
3261634cffccSJoe Perches					# stack dump address styles
3262369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
3263369c8dd3SJoe Perches		}
3264369c8dd3SJoe Perches
32652a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
32662a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
3267bf4daf12SJoe Perches		    length($line) > 75 &&
3268bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
3269bf4daf12SJoe Perches					# file delta changes
327036f8b348SJerome Forissier		      $line =~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ ||
3271bf4daf12SJoe Perches					# filename then :
3272f94e40eaSMatthieu Baerts		      $line =~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i ||
3273f94e40eaSMatthieu Baerts					# A Fixes:, link or signature tag line
3274bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
32752a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
32768e7b7ffbSJim Cromie			     "Prefer a maximum 75 chars per line (possible unwrapped commit description?)\n" . $herecurr);
32772a076f40SJoe Perches			$commit_log_long_line = 1;
32782a076f40SJoe Perches		}
32792a076f40SJoe Perches
3280bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
3281bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
3282bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
3283bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
3284bf4daf12SJoe Perches		}
3285bf4daf12SJoe Perches
328676f381bbSKai Wasserbäch# Check for odd tags before a URI/URL
328776f381bbSKai Wasserbäch		if ($in_commit_log &&
3288f94e40eaSMatthieu Baerts		    $line =~ /^\s*(\w+:)\s*http/ && $1 !~ /^$link_tags_search$/) {
328976f381bbSKai Wasserbäch			if ($1 =~ /^v(?:ersion)?\d+/i) {
329076f381bbSKai Wasserbäch				WARN("COMMIT_LOG_VERSIONING",
329176f381bbSKai Wasserbäch				     "Patch version information should be after the --- line\n" . $herecurr);
329276f381bbSKai Wasserbäch			} else {
329376f381bbSKai Wasserbäch				WARN("COMMIT_LOG_USE_LINK",
3294f94e40eaSMatthieu Baerts				     "Unknown link reference '$1', use $link_tags_print instead\n" . $herecurr);
329576f381bbSKai Wasserbäch			}
329676f381bbSKai Wasserbäch		}
329776f381bbSKai Wasserbäch
3298d6ccdd67SMatthieu Baerts# Check for misuse of the link tags
3299d6ccdd67SMatthieu Baerts		if ($in_commit_log &&
3300d6ccdd67SMatthieu Baerts		    $line =~ /^\s*(\w+:)\s*(\S+)/) {
3301d6ccdd67SMatthieu Baerts			my $tag = $1;
3302d6ccdd67SMatthieu Baerts			my $value = $2;
3303d6ccdd67SMatthieu Baerts			if ($tag =~ /^$link_tags_search$/ && $value !~ m{^https?://}) {
3304d6ccdd67SMatthieu Baerts				WARN("COMMIT_LOG_WRONG_LINK",
3305d6ccdd67SMatthieu Baerts				     "'$tag' should be followed by a public http(s) link\n" . $herecurr);
33060d7835fcSJoe Perches			}
33074ce9f970SJoe Perches		}
33084ce9f970SJoe Perches
33094ce9f970SJoe Perches# Check for lines starting with a #
33104ce9f970SJoe Perches		if ($in_commit_log && $line =~ /^#/) {
33114ce9f970SJoe Perches			if (WARN("COMMIT_COMMENT_SYMBOL",
33124ce9f970SJoe Perches				 "Commit log lines starting with '#' are dropped by git as comments\n" . $herecurr) &&
33134ce9f970SJoe Perches			    $fix) {
33144ce9f970SJoe Perches				$fixed[$fixlinenr] =~ s/^/ /;
33154ce9f970SJoe Perches			}
33164ce9f970SJoe Perches		}
3317a8972573SJohn Hubbard
3318e882dbfcSWei Wang# Check for git id commit length and improperly formed commit descriptions
33194ce9f970SJoe Perches# A correctly formed commit description is:
33204ce9f970SJoe Perches#    commit <SHA-1 hash length 12+ chars> ("Complete commit subject")
3321aab38f51SJoe Perches# with the commit subject '("' prefix and '")' suffix
3322369c8dd3SJoe Perches# This is a fairly compilicated block as it tests for what appears to be
3323bf4daf12SJoe Perches# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of
3324fe043ea1SJoe Perches# possible SHA-1 matches.
3325fe043ea1SJoe Perches# A commit match can span multiple lines so this block attempts to find a
33260d7835fcSJoe Perches# complete typical commit on a maximum of 3 lines
33270d7835fcSJoe Perches		if ($perl_version_ok &&
33280d7835fcSJoe Perches		    $in_commit_log && !$commit_log_possible_stack_dump &&
33290d7835fcSJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
33300d7835fcSJoe Perches		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
33310d7835fcSJoe Perches		    (($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
33320d7835fcSJoe Perches		      ($line =~ /\bcommit\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\s*[0-9a-f]{5,}\b/i)) ||
33334ce9f970SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
33344ce9f970SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
33354ce9f970SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
33360d7835fcSJoe Perches			my $init_char = "c";
33374ce9f970SJoe Perches			my $orig_commit = "";
33384ce9f970SJoe Perches			my $short = 1;
33394ce9f970SJoe Perches			my $long = 0;
33404ce9f970SJoe Perches			my $case = 1;
33414ce9f970SJoe Perches			my $space = 1;
33424ce9f970SJoe Perches			my $id = '0123456789ab';
33434ce9f970SJoe Perches			my $orig_desc = "commit description";
33444ce9f970SJoe Perches			my $description = "";
33454ce9f970SJoe Perches			my $herectx = $herecurr;
33464ce9f970SJoe Perches			my $has_parens = 0;
33474ce9f970SJoe Perches			my $has_quotes = 0;
33484ce9f970SJoe Perches
33494ce9f970SJoe Perches			my $input = $line;
33504ce9f970SJoe Perches			if ($line =~ /(?:\bcommit\s+[0-9a-f]{5,}|\bcommit\s*$)/i) {
33514ce9f970SJoe Perches				for (my $n = 0; $n < 2; $n++) {
33524ce9f970SJoe Perches					if ($input =~ /\bcommit\s+[0-9a-f]{5,}\s*($balanced_parens)/i) {
33534ce9f970SJoe Perches						$orig_desc = $1;
33544ce9f970SJoe Perches						$has_parens = 1;
33554ce9f970SJoe Perches						# Always strip leading/trailing parens then double quotes if existing
3356fe043ea1SJoe Perches						$orig_desc = substr($orig_desc, 1, -1);
3357fe043ea1SJoe Perches						if ($orig_desc =~ /^".*"$/) {
33584ce9f970SJoe Perches							$orig_desc = substr($orig_desc, 1, -1);
33594ce9f970SJoe Perches							$has_quotes = 1;
33604ce9f970SJoe Perches						}
33614ce9f970SJoe Perches						last;
33624ce9f970SJoe Perches					}
33634ce9f970SJoe Perches					last if ($#lines < $linenr + $n);
33644ce9f970SJoe Perches					$input .= " " . trim($rawlines[$linenr + $n]);
33654ce9f970SJoe Perches					$herectx .= "$rawlines[$linenr + $n]\n";
33664ce9f970SJoe Perches				}
33670d7835fcSJoe Perches				$herectx = $herecurr if (!$has_parens);
33680d7835fcSJoe Perches			}
33690d7835fcSJoe Perches
33700d7835fcSJoe Perches			if ($input =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
33710d7835fcSJoe Perches				$init_char = $1;
3372948b133aSHeinrich Schuchardt				$orig_commit = lc($2);
33734ce9f970SJoe Perches				$short = 0 if ($input =~ /\bcommit\s+[0-9a-f]{12,40}/i);
33744ce9f970SJoe Perches				$long = 1 if ($input =~ /\bcommit\s+[0-9a-f]{41,}/i);
3375d311cd44SJoe Perches				$space = 0 if ($input =~ /\bcommit [0-9a-f]/i);
33764ce9f970SJoe Perches				$case = 0 if ($input =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
33770d7835fcSJoe Perches			} elsif ($input =~ /\b([0-9a-f]{12,40})\b/i) {
33784ce9f970SJoe Perches				$orig_commit = lc($1);
33794ce9f970SJoe Perches			}
3380d311cd44SJoe Perches
3381d311cd44SJoe Perches			($id, $description) = git_commit_info($orig_commit,
33829b71f79fSBjorn Helgaas							      $id, $orig_desc);
33839b71f79fSBjorn Helgaas
33849b71f79fSBjorn Helgaas			if (defined($id) &&
33859b71f79fSBjorn Helgaas			    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&
33869b71f79fSBjorn Helgaas			    $last_git_commit_id_linenr != $linenr - 1) {
33879b71f79fSBjorn Helgaas				ERROR("GIT_COMMIT_ID",
338813f1937eSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herectx);
338913f1937eSJoe Perches			}
339013f1937eSJoe Perches			#don't report the next line if this line ends in commit and the sha1 hash is the next line
339113f1937eSJoe Perches			$last_git_commit_id_linenr = $linenr if ($line =~ /\bcommit\s*$/i);
339213f1937eSJoe Perches		}
339313f1937eSJoe Perches
3394a82603a8SAndrew Jeffery# Check for mailing list archives other than lore.kernel.org
339513f1937eSJoe Perches		if ($rawline =~ m{http.*\b$obsolete_archives}) {
339613f1937eSJoe Perches			WARN("PREFER_LORE_ARCHIVE",
339713f1937eSJoe Perches			     "Use lore.kernel.org archive links when possible - see https://lore.kernel.org/lists.html\n" . $herecurr);
339813f1937eSJoe Perches		}
339913f1937eSJoe Perches
3400e400edb1SRob Herring# Check for added, moved or deleted files
3401e400edb1SRob Herring		if (!$reported_maintainer_file && !$in_commit_log &&
3402e400edb1SRob Herring		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
3403e400edb1SRob Herring		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
3404e400edb1SRob Herring		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
340556ddc4cdSMauro Carvalho Chehab		      (defined($1) || defined($2))))) {
3406e400edb1SRob Herring			$is_patch = 1;
3407e400edb1SRob Herring			$reported_maintainer_file = 1;
340800df344fSAndy Whitcroft			WARN("FILE_PATH_CHANGES",
34098905a67cSAndy Whitcroft			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
3410000d1cc1SJoe Perches		}
3411000d1cc1SJoe Perches
34126c72ffaaSAndy Whitcroft# Check for adding new DT bindings not in schema format
3413de7d4f0eSAndy Whitcroft		if (!$in_commit_log &&
3414de7d4f0eSAndy Whitcroft		    ($line =~ /^new file mode\s*\d+\s*$/) &&
3415de7d4f0eSAndy Whitcroft		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
3416de7d4f0eSAndy Whitcroft			WARN("DT_SCHEMA_BINDING_PATCH",
3417171ae1a4SAndy Whitcroft			     "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
3418171ae1a4SAndy Whitcroft		}
3419171ae1a4SAndy Whitcroft
3420171ae1a4SAndy Whitcroft# Check for wrappage within a valid hunk of the file
3421171ae1a4SAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
3422171ae1a4SAndy Whitcroft			ERROR("CORRUPTED_PATCH",
3423171ae1a4SAndy Whitcroft			      "patch seems to be corrupt (line wrapped?)\n" .
342434d99219SJoe Perches				$herecurr) if (!$emitted_corrupt++);
3425000d1cc1SJoe Perches		}
342600df344fSAndy Whitcroft
34270a920b5bSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
342815662b3eSJoe Perches		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
342915662b3eSJoe Perches		    $rawline !~ m/^$UTF8*$/) {
343015662b3eSJoe Perches			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
3431eb3a58deSJoe Perches
3432eb3a58deSJoe Perches			my $blank = copy_spacing($rawline);
343315662b3eSJoe Perches			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
343415662b3eSJoe Perches			my $hereptr = "$hereline$ptr\n";
3435ed43c4e5SAllen Hubbe
343615662b3eSJoe Perches			CHK("INVALID_UTF8",
343715662b3eSJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
3438fa64205dSPasi Savanainen		}
3439fa64205dSPasi Savanainen
3440fa64205dSPasi Savanainen# Check if it's the start of a commit log
3441fa64205dSPasi Savanainen# (not a header line and we haven't seen the patch filename)
3442fa64205dSPasi Savanainen		if ($in_header_lines && $realfile =~ /^$/ &&
3443fa64205dSPasi Savanainen		    !($rawline =~ /^\s+(?:\S|$)/ ||
3444fa64205dSPasi Savanainen		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
3445fa64205dSPasi Savanainen			$in_header_lines = 0;
3446fa64205dSPasi Savanainen			$in_commit_log = 1;
344715662b3eSJoe Perches			$has_commit_log = 1;
3448fa64205dSPasi Savanainen		}
344915662b3eSJoe Perches
345015662b3eSJoe Perches# Check if there is UTF-8 in a commit log when a mail header has explicitly
345115662b3eSJoe Perches# declined it, i.e defined some charset where it is missing.
3452d6430f71SJoe Perches		if ($in_header_lines &&
3453d6430f71SJoe Perches		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
3454d6430f71SJoe Perches		    $1 !~ /utf-8/i) {
3455d6430f71SJoe Perches			$non_utf8_charset = 1;
3456d6430f71SJoe Perches		}
3457d6430f71SJoe Perches
3458d6430f71SJoe Perches		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
3459d6430f71SJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
3460d6430f71SJoe Perches			WARN("UTF8_BEFORE_PATCH",
3461d6430f71SJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
3462d6430f71SJoe Perches		}
3463d6430f71SJoe Perches
3464d6430f71SJoe Perches# Check for absolute kernel paths in commit message
3465d6430f71SJoe Perches		if ($tree && $in_commit_log) {
346666b47b4aSKees Cook			while ($line =~ m{(?:^|\s)(/\S*)}g) {
346766d7a382SJoe Perches				my $file = $1;
346866d7a382SJoe Perches
34697da07c31SDwaipayan Ray				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
347066b47b4aSKees Cook				    check_absolute_file($1, $herecurr)) {
34717da07c31SDwaipayan Ray					#
34727da07c31SDwaipayan Ray				} else {
34737da07c31SDwaipayan Ray					check_absolute_file($file, $herecurr);
347466b47b4aSKees Cook				}
347566b47b4aSKees Cook			}
347666b47b4aSKees Cook		}
34770675a8fbSJean Delvare
34780675a8fbSJean Delvare# Check for various typo / spelling mistakes
34790675a8fbSJean Delvare		if (defined($misspellings) &&
34807da07c31SDwaipayan Ray		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
348166b47b4aSKees Cook			while ($rawline =~ /(?:^|[^\w\-'`])($misspellings)(?:[^\w\-'`]|$)/gi) {
348266b47b4aSKees Cook				my $typo = $1;
348366b47b4aSKees Cook				my $blank = copy_spacing($rawline);
348466b47b4aSKees Cook				my $ptr = substr($blank, 0, $-[1]) . "^" x length($typo);
348566b47b4aSKees Cook				my $hereptr = "$hereline$ptr\n";
348666b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
3487a8dd86bfSMatteo Croce				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
3488a8dd86bfSMatteo Croce				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
3489a8dd86bfSMatteo Croce				my $msg_level = \&WARN;
3490a8dd86bfSMatteo Croce				$msg_level = \&CHK if ($file);
3491a8dd86bfSMatteo Croce				if (&{$msg_level}("TYPO_SPELLING",
3492a8dd86bfSMatteo Croce						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $hereptr) &&
3493a8dd86bfSMatteo Croce				    $fix) {
3494a8dd86bfSMatteo Croce					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
3495a8dd86bfSMatteo Croce				}
3496a8dd86bfSMatteo Croce			}
3497a8dd86bfSMatteo Croce		}
3498310cd06bSJoe Perches
34998d0325ccSAditya Srivastava# check for invalid commit id
35008d0325ccSAditya Srivastava		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
35018d0325ccSAditya Srivastava			my $id;
35021db81a68SDwaipayan Ray			my $description;
3503310cd06bSJoe Perches			($id, $description) = git_commit_info($2, undef, undef);
3504310cd06bSJoe Perches			if (!defined($id)) {
3505310cd06bSJoe Perches				WARN("UNKNOWN_COMMIT_ID",
3506310cd06bSJoe Perches				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
35071db81a68SDwaipayan Ray			}
35081db81a68SDwaipayan Ray		}
3509310cd06bSJoe Perches
3510310cd06bSJoe Perches# check for repeated words separated by a single space
3511310cd06bSJoe Perches# avoid false positive from list command eg, '-rw-r--r-- 1 root root'
3512310cd06bSJoe Perches		if (($rawline =~ /^\+/ || $in_commit_log) &&
3513310cd06bSJoe Perches		    $rawline !~ /[bcCdDlMnpPs\?-][rwxsStT-]{9}/) {
35141db81a68SDwaipayan Ray			pos($rawline) = 1 if (!$in_commit_log);
3515310cd06bSJoe Perches			while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) {
3516310cd06bSJoe Perches
35171db81a68SDwaipayan Ray				my $first = $1;
35181db81a68SDwaipayan Ray				my $second = $2;
35191db81a68SDwaipayan Ray				my $start_pos = $-[1];
35201db81a68SDwaipayan Ray				my $end_pos = $+[2];
35211db81a68SDwaipayan Ray				if ($first =~ /(?:struct|union|enum)/) {
35221db81a68SDwaipayan Ray					pos($rawline) += length($first) + length($second) + 1;
35231db81a68SDwaipayan Ray					next;
35241db81a68SDwaipayan Ray				}
35251db81a68SDwaipayan Ray
35268d0325ccSAditya Srivastava				next if (lc($first) ne lc($second));
35278d0325ccSAditya Srivastava				next if ($first eq 'long');
35288d0325ccSAditya Srivastava
35298d0325ccSAditya Srivastava				# check for character before and after the word matches
35308d0325ccSAditya Srivastava				my $start_char = '';
3531310cd06bSJoe Perches				my $end_char = '';
3532310cd06bSJoe Perches				$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));
3533310cd06bSJoe Perches				$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));
3534310cd06bSJoe Perches
3535310cd06bSJoe Perches				next if ($start_char =~ /^\S$/);
3536310cd06bSJoe Perches				next if (index(" \t.,;?!", $end_char) == -1);
3537310cd06bSJoe Perches
3538310cd06bSJoe Perches				# avoid repeating hex occurrences like 'ff ff fe 09 ...'
3539310cd06bSJoe Perches				if ($first =~ /\b[0-9a-f]{2,}\b/i) {
3540310cd06bSJoe Perches					next if (!exists($allow_repeated_words{lc($first)}));
3541310cd06bSJoe Perches				}
3542310cd06bSJoe Perches
3543310cd06bSJoe Perches				if (WARN("REPEATED_WORD",
3544310cd06bSJoe Perches					 "Possible repeated word: '$first'\n" . $herecurr) &&
3545310cd06bSJoe Perches				    $fix) {
3546310cd06bSJoe Perches					$fixed[$fixlinenr] =~ s/\b$first $second\b/$first/;
3547310cd06bSJoe Perches				}
3548310cd06bSJoe Perches			}
3549310cd06bSJoe Perches
3550310cd06bSJoe Perches			# if it's a repeated word on consecutive lines in a comment block
3551310cd06bSJoe Perches			if ($prevline =~ /$;+\s*$/ &&
355230670854SAndy Whitcroft			    $prevrawline =~ /($word_pattern)\s*$/) {
355330670854SAndy Whitcroft				my $last_word = $1;
355400df344fSAndy Whitcroft				if ($rawline =~ /^\+\s*\*\s*$last_word /) {
35550a920b5bSAndy Whitcroft					if (WARN("REPEATED_WORD",
35569c0ca6f9SAndy Whitcroft						 "Possible repeated word: '$last_word'\n" . $hereprev) &&
3557c2fdda0dSAndy Whitcroft					    $fix) {
3558d5e616fcSJoe Perches						$fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/;
3559d5e616fcSJoe Perches					}
3560d5e616fcSJoe Perches				}
3561194f66fcSJoe Perches			}
3562d5e616fcSJoe Perches		}
3563c2fdda0dSAndy Whitcroft
3564c2fdda0dSAndy Whitcroft# ignore non-hunk lines and lines being removed
35653705ce5bSJoe Perches		next if (!$hunk_line || $line =~ /^-/);
35663705ce5bSJoe Perches
35673705ce5bSJoe Perches#trailing whitespace
3568194f66fcSJoe Perches		if ($line =~ /^\+.*\015/) {
35693705ce5bSJoe Perches			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35703705ce5bSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
3571d2c0a235SAndy Whitcroft				  "DOS line endings\n" . $herevet) &&
35720a920b5bSAndy Whitcroft			    $fix) {
35735368df20SAndy Whitcroft				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
35744783f894SJosh Triplett			}
3575109d8cb2SAlexander Duyck		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
35761bde561eSMatthew Wilcox			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35773e2232f2SJoe Perches			if (ERROR("TRAILING_WHITESPACE",
35783e2232f2SJoe Perches				  "trailing whitespace\n" . $herevet) &&
35794783f894SJosh Triplett			    $fix) {
35800675a8fbSJean Delvare				$fixed[$fixlinenr] =~ s/\s+$//;
35810675a8fbSJean Delvare			}
35820675a8fbSJean Delvare
35834783f894SJosh Triplett			$rpt_cleaners = 1;
35844783f894SJosh Triplett		}
35854783f894SJosh Triplett
35863354957aSAndi Kleen# Check for FSF mailing addresses.
35879fe287d7SAndy Whitcroft		if ($rawline =~ /\bwrite to the Free/i ||
35889fe287d7SAndy Whitcroft		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
35893354957aSAndi Kleen		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
3590678ae162SUlf Magnusson		    $rawline =~ /\b51\s+Franklin\s+St/i) {
3591678ae162SUlf Magnusson			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3592678ae162SUlf Magnusson			my $msg_level = \&ERROR;
3593678ae162SUlf Magnusson			$msg_level = \&CHK if ($file);
3594b8709bceSJoe Perches			&{$msg_level}("FSF_MAILING_ADDRESS",
3595b8709bceSJoe Perches				      "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)
3596b8709bceSJoe Perches		}
3597b8709bceSJoe Perches
3598b8709bceSJoe Perches# check for Kconfig help text having a real description
3599b8709bceSJoe Perches# Only applies when adding the entry originally, after that we do not have
36009fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
36019fe287d7SAndy Whitcroft		if ($realfile =~ /Kconfig/ &&
3602b8709bceSJoe Perches		    # 'choice' is usually the last thing on the line (though
3603a1385803SAndy Whitcroft		    # Kconfig supports named choices), so use a word boundary
3604b8709bceSJoe Perches		    # (\b) rather than a whitespace character (\s)
3605b8709bceSJoe Perches		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
3606b8709bceSJoe Perches			my $ln = $linenr;
3607b8709bceSJoe Perches			my $needs_help = 0;
3608b8709bceSJoe Perches			my $has_help = 0;
3609b8709bceSJoe Perches			my $help_length = 0;
3610b8709bceSJoe Perches			while (defined $lines[$ln]) {
3611a1385803SAndy Whitcroft				my $f = $lines[$ln++];
3612a1385803SAndy Whitcroft
3613b8709bceSJoe Perches				next if ($f =~ /^-/);
3614b8709bceSJoe Perches				last if ($f !~ /^[\+ ]/);	# !patch context
3615b8709bceSJoe Perches
3616b8709bceSJoe Perches				if ($f =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3617678ae162SUlf Magnusson					$needs_help = 1;
3618b8709bceSJoe Perches					next;
3619678ae162SUlf Magnusson				}
3620678ae162SUlf Magnusson				if ($f =~ /^\+\s*help\s*$/) {
3621678ae162SUlf Magnusson					$has_help = 1;
3622678ae162SUlf Magnusson					next;
3623b8709bceSJoe Perches				}
3624678ae162SUlf Magnusson
36259fe287d7SAndy Whitcroft				$f =~ s/^.//;	# strip patch context [+ ]
36269fe287d7SAndy Whitcroft				$f =~ s/#.*//;	# strip # directives
3627b8709bceSJoe Perches				$f =~ s/^\s+//;	# strip leading blanks
36283354957aSAndi Kleen				next if ($f =~ /^$/);	# skip blank lines
3629b8709bceSJoe Perches
3630b8709bceSJoe Perches				# At the end of this Kconfig block:
3631b8709bceSJoe Perches				# This only checks context lines in the patch
3632000d1cc1SJoe Perches				# and so hopefully shouldn't trigger false
3633b8709bceSJoe Perches				# positives, even though some of these are
363456193274SVadim Bendebury				# common words in help texts
36353354957aSAndi Kleen				if ($f =~ /^(?:config|menuconfig|choice|endchoice|
36363354957aSAndi Kleen					       if|endif|menu|endmenu|source)\b/x) {
36377ccf41a8SJoe Perches					last;
36387ccf41a8SJoe Perches				}
36397ccf41a8SJoe Perches				$help_length++ if ($has_help);
36407ccf41a8SJoe Perches			}
3641628f91a2SJoe Perches			if ($needs_help &&
3642628f91a2SJoe Perches			    $help_length < $min_conf_desc_length) {
3643628f91a2SJoe Perches				my $stat_real = get_stat_real($linenr, $ln - 1);
3644628f91a2SJoe Perches				WARN("CONFIG_DESCRIPTION",
3645628f91a2SJoe Perches				     "please write a help paragraph that fully describes the config symbol\n" . "$here\n$stat_real\n");
3646628f91a2SJoe Perches			}
3647628f91a2SJoe Perches		}
36487ccf41a8SJoe Perches
36497ccf41a8SJoe Perches# check MAINTAINERS entries
36507ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
36517ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
36527ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
36537ccf41a8SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
36547ccf41a8SJoe Perches				if (WARN("MAINTAINERS_STYLE",
36557ccf41a8SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
36567ccf41a8SJoe Perches				    $fix) {
36577ccf41a8SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
36587ccf41a8SJoe Perches				}
36597ccf41a8SJoe Perches			}
36607ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
36617ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
36627ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
36637ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
36647ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
36657ccf41a8SJoe Perches				my $cur = $1;
36667ccf41a8SJoe Perches				my $curval = $2;
36677ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
36687ccf41a8SJoe Perches				my $prev = $1;
36697ccf41a8SJoe Perches				my $prevval = $2;
36707ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
36717ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
36727ccf41a8SJoe Perches				if ($curindex < 0) {
36737ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
36747ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
36757ccf41a8SJoe Perches				} else {
3676628f91a2SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
3677c68e5878SArnaud Lacombe						WARN("MAINTAINERS_STYLE",
3678c68e5878SArnaud Lacombe						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3679c68e5878SArnaud Lacombe					} elsif ((($prev eq 'F' && $cur eq 'F') ||
3680c68e5878SArnaud Lacombe						  ($prev eq 'X' && $cur eq 'X')) &&
3681c68e5878SArnaud Lacombe						 ($prevval cmp $curval) > 0) {
3682c68e5878SArnaud Lacombe						WARN("MAINTAINERS_STYLE",
3683c68e5878SArnaud Lacombe						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3684c68e5878SArnaud Lacombe					}
3685c68e5878SArnaud Lacombe				}
3686c68e5878SArnaud Lacombe			}
3687c68e5878SArnaud Lacombe		}
3688c68e5878SArnaud Lacombe
3689c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3690c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3691bff5da43SRob Herring			my $flag = $1;
36927dd05b38SFlorian Vaussard			my $replacement = {
36937dd05b38SFlorian Vaussard				'EXTRA_AFLAGS' =>   'asflags-y',
36947dd05b38SFlorian Vaussard				'EXTRA_CFLAGS' =>   'ccflags-y',
36957dd05b38SFlorian Vaussard				'EXTRA_CPPFLAGS' => 'cppflags-y',
3696bff5da43SRob Herring				'EXTRA_LDFLAGS' =>  'ldflags-y',
3697bff5da43SRob Herring			};
3698cc93319bSFlorian Vaussard
3699852d095dSRob Herring			WARN("DEPRECATED_VARIABLE",
3700cc93319bSFlorian Vaussard			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3701bff5da43SRob Herring		}
3702bff5da43SRob Herring
3703185d566bSRob Herring# check for DT compatible documentation
3704185d566bSRob Herring		if (defined $root &&
3705185d566bSRob Herring			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3706185d566bSRob Herring			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3707bff5da43SRob Herring
3708bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3709bff5da43SRob Herring
3710bff5da43SRob Herring			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3711bff5da43SRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
37124fbf32a6SFlorian Vaussard
37134fbf32a6SFlorian Vaussard			foreach my $compat (@compats) {
3714852d095dSRob Herring				my $compat2 = $compat;
3715bff5da43SRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3716bff5da43SRob Herring				my $compat3 = $compat;
3717cc93319bSFlorian Vaussard				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3718bff5da43SRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3719bff5da43SRob Herring				if ( $? >> 8 ) {
3720bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3721bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
37229f3a8992SRob Herring				}
37239f3a8992SRob Herring
37249f3a8992SRob Herring				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
37259f3a8992SRob Herring				my $vendor = $1;
37269f3a8992SRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
37279f3a8992SRob Herring				if ( $? >> 8 ) {
37289f3a8992SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
37299f3a8992SRob Herring					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3730d1d84b5fSMiguel Ojeda				}
37319f3a8992SRob Herring			}
3732c8df0ab6SLubomir Rintel		}
37339f3a8992SRob Herring
37349f3a8992SRob Herring# check for using SPDX license tag at beginning of files
37359f3a8992SRob Herring		if ($realline == $checklicenseline) {
37369f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
37379f3a8992SRob Herring				$checklicenseline = 2;
3738fdf13693SJoe Perches			} elsif ($rawline =~ /^\+/) {
3739fdf13693SJoe Perches				my $comment = "";
3740fdf13693SJoe Perches				if ($realfile =~ /\.(h|s|S)$/) {
3741ffbce897SJoe Perches					$comment = '/*';
3742fdf13693SJoe Perches				} elsif ($realfile =~ /\.(c|rs|dts|dtsi)$/) {
3743fdf13693SJoe Perches					$comment = '//';
3744fdf13693SJoe Perches				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
3745fdf13693SJoe Perches					$comment = '#';
37469f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
3747ffbce897SJoe Perches					$comment = '..';
37489f3a8992SRob Herring				}
37499f3a8992SRob Herring
37503b6e8ac9SJoe Perches# check SPDX comment style for .[chsS] files
37513b6e8ac9SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
37523b6e8ac9SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
37533b6e8ac9SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
37543b6e8ac9SJoe Perches					WARN("SPDX_LICENSE_TAG",
37553b6e8ac9SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
375650c92900SLubomir Rintel				}
375750c92900SLubomir Rintel
375850c92900SLubomir Rintel				if ($comment !~ /^$/ &&
375950c92900SLubomir Rintel				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
376050c92900SLubomir Rintel					WARN("SPDX_LICENSE_TAG",
376150c92900SLubomir Rintel					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
376250c92900SLubomir Rintel				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
376350c92900SLubomir Rintel					my $spdx_license = $1;
376450c92900SLubomir Rintel					if (!is_SPDX_License_valid($spdx_license)) {
376550c92900SLubomir Rintel						WARN("SPDX_LICENSE_TAG",
376650c92900SLubomir Rintel						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
37679f3a8992SRob Herring					}
37689f3a8992SRob Herring					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
3769a04bb4c2SDmitry Rokosov					    $spdx_license !~ /GPL-2\.0(?:-only)? OR BSD-2-Clause/) {
37709f3a8992SRob Herring						my $msg_level = \&WARN;
37719f3a8992SRob Herring						$msg_level = \&CHK if ($file);
37725368df20SAndy Whitcroft						if (&{$msg_level}("SPDX_LICENSE_TAG",
3773d6430f71SJoe Perches
37745368df20SAndy Whitcroft								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
3775a8da38a9SJoe Perches						    $fix) {
3776a8da38a9SJoe Perches							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
3777a8da38a9SJoe Perches						}
3778a8da38a9SJoe Perches					}
3779a04bb4c2SDmitry Rokosov					if ($realfile =~ m@^include/dt-bindings/@ &&
3780a04bb4c2SDmitry Rokosov					    $spdx_license !~ /GPL-2\.0(?:-only)? OR \S+/) {
3781a04bb4c2SDmitry Rokosov						WARN("SPDX_LICENSE_TAG",
3782a04bb4c2SDmitry Rokosov						     "DT binding headers should be licensed (GPL-2.0-only OR .*)\n" . $herecurr);
3783a04bb4c2SDmitry Rokosov					}
378447e0c88bSJoe Perches				}
378547e0c88bSJoe Perches			}
378647e0c88bSJoe Perches		}
378747e0c88bSJoe Perches
3788a0154cdbSJoe Perches# check for embedded filenames
378936217357SJoe Perches		if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
3790a0154cdbSJoe Perches			WARN("EMBEDDED_FILENAME",
3791a0154cdbSJoe Perches			     "It's generally not useful to have the filename in the file\n" . $herecurr);
3792a0154cdbSJoe Perches		}
3793a0154cdbSJoe Perches
37945e79d96eSJoe Perches# check we are in a valid source file if not then ignore this hunk
3795d1d84b5fSMiguel Ojeda		next if ($realfile !~ /\.(h|c|rs|s|S|sh|dtsi|dts)$/);
37960a920b5bSAndy Whitcroft
3797a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3798a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3799a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3800a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3801a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3802a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3803a8da38a9SJoe Perches		}
3804a8da38a9SJoe Perches
3805c45dcabdSAndy Whitcroft# line length limit (with some exclusions)
380647e0c88bSJoe Perches#
380747e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
380847e0c88bSJoe Perches#	logging functions like pr_info that end in a string
380947e0c88bSJoe Perches#	lines with a single string
381047e0c88bSJoe Perches#	#defines that are a single string
381147e0c88bSJoe Perches#	lines with an RFC3986 like URL
381247e0c88bSJoe Perches#
381347e0c88bSJoe Perches# There are 3 different line length message types:
381447e0c88bSJoe Perches# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
381547e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
381647e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
381747e0c88bSJoe Perches#
381847e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
381947e0c88bSJoe Perches#
382047e0c88bSJoe Perches
382147e0c88bSJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
382247e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
382347e0c88bSJoe Perches
382447e0c88bSJoe Perches			# Check the allowed long line types first
382547e0c88bSJoe Perches
382647e0c88bSJoe Perches			# logging functions that end in a string that starts
382747e0c88bSJoe Perches			# before $max_line_length
382847e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
382947e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
383047e0c88bSJoe Perches				$msg_type = "";
383147e0c88bSJoe Perches
383247e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
383347e0c88bSJoe Perches			# #defines with only strings
383447e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
383547e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
383647e0c88bSJoe Perches				$msg_type = "";
383747e0c88bSJoe Perches
3838cc147506SJoe Perches			# More special cases
3839cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3840cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3841d560a5f8SJoe Perches				$msg_type = "";
3842d560a5f8SJoe Perches
38432e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
38442e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
38452e4bbbc5SAndreas Brauchli				$msg_type = "";
38462e4bbbc5SAndreas Brauchli
384747e0c88bSJoe Perches			# Otherwise set the alternate message types
384847e0c88bSJoe Perches
384947e0c88bSJoe Perches			# a comment starts before $max_line_length
385047e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
385147e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
385247e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
385347e0c88bSJoe Perches
385447e0c88bSJoe Perches			# a quoted string starts before $max_line_length
385547e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
385647e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
385747e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
385847e0c88bSJoe Perches			}
385947e0c88bSJoe Perches
386047e0c88bSJoe Perches			if ($msg_type ne "" &&
386147e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3862bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3863bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3864bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3865bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
38660a920b5bSAndy Whitcroft			}
386747e0c88bSJoe Perches		}
38680a920b5bSAndy Whitcroft
38698905a67cSAndy Whitcroft# check for adding lines without a newline.
38708905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
387147ca69b8STom Rix			if (WARN("MISSING_EOF_NEWLINE",
387247ca69b8STom Rix			         "adding a line without newline at end of file\n" . $herecurr) &&
387347ca69b8STom Rix			    $fix) {
387447ca69b8STom Rix				fix_delete_line($fixlinenr+1, "No newline at end of file");
387547ca69b8STom Rix			}
38768905a67cSAndy Whitcroft		}
38778905a67cSAndy Whitcroft
3878de93245cSAditya Srivastava# check for .L prefix local symbols in .S files
3879de93245cSAditya Srivastava		if ($realfile =~ /\.S$/ &&
3880de93245cSAditya Srivastava		    $line =~ /^\+\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\s*\(\s*\.L/) {
3881de93245cSAditya Srivastava			WARN("AVOID_L_PREFIX",
3882f4bf1cd4SJonathan Corbet			     "Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/core-api/asm-annotations.rst\n" . $herecurr);
3883de93245cSAditya Srivastava		}
3884de93245cSAditya Srivastava
3885b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3886de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
38870a920b5bSAndy Whitcroft
38880a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3889713a09deSAntonio Borneo# more than $tabsize must use tabs.
3890c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3891c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3892c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3893d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
38943705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
38953705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
38963705ce5bSJoe Perches			    $fix) {
3897194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
38983705ce5bSJoe Perches			}
38990a920b5bSAndy Whitcroft		}
39000a920b5bSAndy Whitcroft
390108e44365SAlberto Panizzo# check for space before tabs.
390208e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
390308e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
39043705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
39053705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
39063705ce5bSJoe Perches			    $fix) {
3907194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3908713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3909194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3910c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
39113705ce5bSJoe Perches			}
391208e44365SAlberto Panizzo		}
391308e44365SAlberto Panizzo
39146a487211SJoe Perches# check for assignments on the start of a line
39156a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3916da7355abSAditya Srivastava			my $operator = $1;
3917da7355abSAditya Srivastava			if (CHK("ASSIGNMENT_CONTINUATIONS",
3918da7355abSAditya Srivastava				"Assignment operator '$1' should be on the previous line\n" . $hereprev) &&
3919da7355abSAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
3920da7355abSAditya Srivastava				# add assignment operator to the previous line, remove from current line
3921da7355abSAditya Srivastava				$fixed[$fixlinenr - 1] .= " $operator";
3922da7355abSAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
3923da7355abSAditya Srivastava			}
39246a487211SJoe Perches		}
39256a487211SJoe Perches
3926d1fe9c09SJoe Perches# check for && or || at the start of a line
3927d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
39288e08f076SAditya Srivastava			my $operator = $1;
39298e08f076SAditya Srivastava			if (CHK("LOGICAL_CONTINUATIONS",
39308e08f076SAditya Srivastava				"Logical continuations should be on the previous line\n" . $hereprev) &&
39318e08f076SAditya Srivastava			    $fix && $prevrawline =~ /^\+/) {
39328e08f076SAditya Srivastava				# insert logical operator at last non-comment, non-whitepsace char on previous line
39338e08f076SAditya Srivastava				$prevline =~ /[\s$;]*$/;
39348e08f076SAditya Srivastava				my $line_end = substr($prevrawline, $-[0]);
39358e08f076SAditya Srivastava				$fixed[$fixlinenr - 1] =~ s/\Q$line_end\E$/ $operator$line_end/;
39368e08f076SAditya Srivastava				$fixed[$fixlinenr] =~ s/\Q$operator\E\s*//;
39378e08f076SAditya Srivastava			}
3938d1fe9c09SJoe Perches		}
3939d1fe9c09SJoe Perches
3940a91e8994SJoe Perches# check indentation starts on a tab stop
39415b57980dSJoe Perches		if ($perl_version_ok &&
3942bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3943a91e8994SJoe Perches			my $indent = length($1);
3944713a09deSAntonio Borneo			if ($indent % $tabsize) {
3945a91e8994SJoe Perches				if (WARN("TABSTOP",
3946a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3947a91e8994SJoe Perches				    $fix) {
3948713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3949a91e8994SJoe Perches				}
3950a91e8994SJoe Perches			}
3951a91e8994SJoe Perches		}
3952a91e8994SJoe Perches
3953d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
39545b57980dSJoe Perches		if ($perl_version_ok &&
3955fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3956d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3957d1fe9c09SJoe Perches			my $oldindent = $1;
3958d1fe9c09SJoe Perches			my $rest = $2;
3959d1fe9c09SJoe Perches
3960d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3961d1fe9c09SJoe Perches			if ($pos >= 0) {
3962b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3963b34a26f3SJoe Perches				my $newindent = $2;
3964d1fe9c09SJoe Perches
3965d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3966713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3967713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3968d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3969d1fe9c09SJoe Perches
3970d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3971d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
39723705ce5bSJoe Perches
39733705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
39743705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
39753705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3976194f66fcSJoe Perches						$fixed[$fixlinenr] =~
39773705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
39783705ce5bSJoe Perches					}
3979d1fe9c09SJoe Perches				}
3980d1fe9c09SJoe Perches			}
3981d1fe9c09SJoe Perches		}
3982d1fe9c09SJoe Perches
39836ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
39846ab3a970SJoe Perches# avoid checking a few false positives:
39856ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
39866ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
39876ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
39886ab3a970SJoe Perches#   multiline macros that define functions
39896ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
39906ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
39916ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
39923705ce5bSJoe Perches			if (CHK("SPACING",
3993f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
39943705ce5bSJoe Perches			    $fix) {
3995194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3996f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
39973705ce5bSJoe Perches			}
3998aad4f614SJoe Perches		}
3999aad4f614SJoe Perches
400086406b1cSJoe Perches# Block comment styles
400186406b1cSJoe Perches# Networking with an initial /*
400205880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
4003fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
400485ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
4005c70735c2SŁukasz Stelmach		    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier
400605880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
400705880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
400805880600SJoe Perches		}
400905880600SJoe Perches
401086406b1cSJoe Perches# Block comments use * on subsequent lines
401186406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
401286406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
4013a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
401461135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
4015a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
401686406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
401786406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
4018a605e32eSJoe Perches		}
4019a605e32eSJoe Perches
402086406b1cSJoe Perches# Block comments use */ on trailing lines
402186406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
4022c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
4023c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
4024c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
402586406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
402686406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
402705880600SJoe Perches		}
402805880600SJoe Perches
402908eb9b80SJoe Perches# Block comment * alignment
403008eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
4031af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
4032af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
4033af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
403408eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
4035af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
4036af207524SJoe Perches			my $oldindent;
403708eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
4038af207524SJoe Perches			if (defined($1)) {
4039af207524SJoe Perches				$oldindent = expand_tabs($1);
4040af207524SJoe Perches			} else {
4041af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
4042af207524SJoe Perches				$oldindent = expand_tabs($1);
4043af207524SJoe Perches			}
404408eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
404508eb9b80SJoe Perches			my $newindent = $1;
404608eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
4047af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
404808eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
404908eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
405008eb9b80SJoe Perches			}
405108eb9b80SJoe Perches		}
405208eb9b80SJoe Perches
40537f619191SJoe Perches# check for missing blank lines after struct/union declarations
40547f619191SJoe Perches# with exceptions for various attributes and macros
40557f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
40567f619191SJoe Perches		    $line =~ /^\+/ &&
40577f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
405805dc40e6SJoe Perches		      $line =~ /^\+\s*(?:EXPORT_SYMBOL|early_param)/ ||
40597f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
40607f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
40617f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
40627f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
40637f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
40640bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
40657f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
4066d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
4067d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
4068d752fcc8SJoe Perches			    $fix) {
4069f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
4070d752fcc8SJoe Perches			}
40717f619191SJoe Perches		}
40727f619191SJoe Perches
4073365dd4eaSJoe Perches# check for multiple consecutive blank lines
4074365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
4075365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
4076365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
4077d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
4078d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
4079d752fcc8SJoe Perches			    $fix) {
4080f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4081d752fcc8SJoe Perches			}
4082d752fcc8SJoe Perches
4083365dd4eaSJoe Perches			$last_blank_line = $linenr;
4084365dd4eaSJoe Perches		}
4085365dd4eaSJoe Perches
40863b617e3bSJoe Perches# check for missing blank lines after declarations
4087b5e8736aSJoe Perches# (declarations must have the same indentation and not be at the start of line)
4088b5e8736aSJoe Perches		if (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/) {
4089b5e8736aSJoe Perches			# use temporaries
4090b5e8736aSJoe Perches			my $sl = $sline;
4091b5e8736aSJoe Perches			my $pl = $prevline;
4092b5e8736aSJoe Perches			# remove $Attribute/$Sparse uses to simplify comparisons
4093b5e8736aSJoe Perches			$sl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4094b5e8736aSJoe Perches			$pl =~ s/\b(?:$Attribute|$Sparse)\b//g;
4095b5e8736aSJoe Perches			if (($pl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
40965a4e1fd3SJoe Perches			# function pointer declarations
4097b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
40983f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
4099b5e8736aSJoe Perches			     $pl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
41003f7bac03SJoe Perches			# known declaration macros
4101b5e8736aSJoe Perches			     $pl =~ /^\+\s+$declaration_macros/) &&
41023f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
4103b5e8736aSJoe Perches			    !($pl =~ /^\+\s+$c90_Keywords\b/ ||
41043f7bac03SJoe Perches			# other possible extensions of declaration lines
4105b5e8736aSJoe Perches			      $pl =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
41063f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
4107b5e8736aSJoe Perches			      $pl =~ /(?:\{\s*|\\)$/) &&
41083f7bac03SJoe Perches			# looks like a declaration
4109b5e8736aSJoe Perches			    !($sl =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
41105a4e1fd3SJoe Perches			# function pointer declarations
4111b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
41123f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
4113b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
41143f7bac03SJoe Perches			# known declaration macros
4115b5e8736aSJoe Perches			      $sl =~ /^\+\s+$declaration_macros/ ||
41163f7bac03SJoe Perches			# start of struct or union or enum
4117b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
41183f7bac03SJoe Perches			# start or end of block or continuation of declaration
4119b5e8736aSJoe Perches			      $sl =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
41203f7bac03SJoe Perches			# bitfield continuation
4121b5e8736aSJoe Perches			      $sl =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
41223f7bac03SJoe Perches			# other possible extensions of declaration lines
4123b5e8736aSJoe Perches			      $sl =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/)) {
4124d752fcc8SJoe Perches				if (WARN("LINE_SPACING",
4125d752fcc8SJoe Perches					 "Missing a blank line after declarations\n" . $hereprev) &&
4126d752fcc8SJoe Perches				    $fix) {
4127f2d7e4d4SJoe Perches					fix_insert_line($fixlinenr, "\+");
4128d752fcc8SJoe Perches				}
41293b617e3bSJoe Perches			}
4130b5e8736aSJoe Perches		}
41313b617e3bSJoe Perches
41325f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
41336b4c5bebSAndy Whitcroft# Exceptions:
41346b4c5bebSAndy Whitcroft#  1) within comments
41356b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
41366b4c5bebSAndy Whitcroft#  3) hanging labels
41373705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
41385f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
41393705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
41403705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
41413705ce5bSJoe Perches			    $fix) {
4142194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
41433705ce5bSJoe Perches			}
41445f7ddae6SRaffaele Recalcati		}
41455f7ddae6SRaffaele Recalcati
4146b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
4147b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
4148b9ea10d6SAndy Whitcroft
41495751a24eSJoe Perches# check for unusual line ending [ or (
41505751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
41515751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
41525751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
41535751a24eSJoe Perches		}
41545751a24eSJoe Perches
41554dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
41564dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
41574dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
41584dbed76fSJoe Perches			$context_function = $1;
41594dbed76fSJoe Perches		}
41604dbed76fSJoe Perches
41614dbed76fSJoe Perches# check if this appears to be the end of function declaration
41624dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
41634dbed76fSJoe Perches			undef $context_function;
41644dbed76fSJoe Perches		}
41654dbed76fSJoe Perches
4166032a4c0fSJoe Perches# check indentation of any line with a bare else
4167840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
4168032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
4169032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
4170032a4c0fSJoe Perches			my $tabs = length($1) + 1;
4171840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
4172840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
4173840080a0SJoe Perches			     defined $lines[$linenr] &&
4174840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
4175032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
4176032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
4177032a4c0fSJoe Perches			}
4178032a4c0fSJoe Perches		}
4179032a4c0fSJoe Perches
4180c00df19aSJoe Perches# check indentation of a line with a break;
4181dc58bc55SJoe Perches# if the previous line is a goto, return or break
4182dc58bc55SJoe Perches# and is indented the same # of tabs
4183c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
4184c00df19aSJoe Perches			my $tabs = $1;
4185dc58bc55SJoe Perches			if ($prevline =~ /^\+$tabs(goto|return|break)\b/) {
4186dc58bc55SJoe Perches				if (WARN("UNNECESSARY_BREAK",
4187dc58bc55SJoe Perches					 "break is not useful after a $1\n" . $hereprev) &&
4188dc58bc55SJoe Perches				    $fix) {
4189dc58bc55SJoe Perches					fix_delete_line($fixlinenr, $rawline);
4190dc58bc55SJoe Perches				}
4191c00df19aSJoe Perches			}
4192c00df19aSJoe Perches		}
4193c00df19aSJoe Perches
4194c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
4195cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
4196000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
4197000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
4198c2fdda0dSAndy Whitcroft		}
419922f2a2efSAndy Whitcroft
420056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
420156e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
420256e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
420356e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
420456e77d70SJoe Perches		}
420556e77d70SJoe Perches
42069c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
42072b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
42082b474a1aSAndy Whitcroft		    $realline_next);
42093e469cdcSAndy Whitcroft#print "LINE<$line>\n";
4210ca819864SJoe Perches		if ($linenr > $suppress_statement &&
42111b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
4212170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
4213f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4214171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
4215171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
4216171ae1a4SAndy Whitcroft
42173e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
42183e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
42193e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
42203e469cdcSAndy Whitcroft			# until we hit end of it.
42213e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
42223e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
42233e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
42243e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
42253e469cdcSAndy Whitcroft			}
4226f74bd194SAndy Whitcroft
42272b474a1aSAndy Whitcroft			# Find the real next line.
42282b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
42292b474a1aSAndy Whitcroft			if (defined $realline_next &&
42302b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
42312b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
42322b474a1aSAndy Whitcroft				$realline_next++;
42332b474a1aSAndy Whitcroft			}
42342b474a1aSAndy Whitcroft
4235171ae1a4SAndy Whitcroft			my $s = $stat;
4236171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
4237cf655043SAndy Whitcroft
4238c2fdda0dSAndy Whitcroft			# Ignore goto labels.
4239171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
4240c2fdda0dSAndy Whitcroft
4241c2fdda0dSAndy Whitcroft			# Ignore functions being called
4242171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
4243c2fdda0dSAndy Whitcroft
4244463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
4245463f2864SAndy Whitcroft
4246c45dcabdSAndy Whitcroft			# declarations always start with types
4247d2506586SAndy 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) {
4248c45dcabdSAndy Whitcroft				my $type = $1;
4249c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
4250c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
4251c45dcabdSAndy Whitcroft
42526c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
4253a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
4254c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
4255c2fdda0dSAndy Whitcroft			}
42568905a67cSAndy Whitcroft
42576c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
425865863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
4259c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
42609c0ca6f9SAndy Whitcroft			}
42618905a67cSAndy Whitcroft
42628905a67cSAndy Whitcroft			# Check for any sort of function declaration.
42638905a67cSAndy Whitcroft			# int foo(something bar, other baz);
42648905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
4265171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
42668905a67cSAndy Whitcroft				my ($name_len) = length($1);
42678905a67cSAndy Whitcroft
4268cf655043SAndy Whitcroft				my $ctx = $s;
4269773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
42708905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
4271cf655043SAndy Whitcroft
42728905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
4273c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
42748905a67cSAndy Whitcroft
4275c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
42768905a67cSAndy Whitcroft					}
42778905a67cSAndy Whitcroft				}
42788905a67cSAndy Whitcroft			}
42798905a67cSAndy Whitcroft
42809c0ca6f9SAndy Whitcroft		}
42819c0ca6f9SAndy Whitcroft
428200df344fSAndy Whitcroft#
428300df344fSAndy Whitcroft# Checks which may be anchored in the context.
428400df344fSAndy Whitcroft#
428500df344fSAndy Whitcroft
428600df344fSAndy Whitcroft# Check for switch () and associated case and default
428700df344fSAndy Whitcroft# statements should be at the same indent.
428800df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
428900df344fSAndy Whitcroft			my $err = '';
429000df344fSAndy Whitcroft			my $sep = '';
429100df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
429200df344fSAndy Whitcroft			shift(@ctx);
429300df344fSAndy Whitcroft			for my $ctx (@ctx) {
429400df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
429500df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
429600df344fSAndy Whitcroft							$indent != $cindent) {
429700df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
429800df344fSAndy Whitcroft					$sep = '';
429900df344fSAndy Whitcroft				} else {
430000df344fSAndy Whitcroft					$sep = "[...]\n";
430100df344fSAndy Whitcroft				}
430200df344fSAndy Whitcroft			}
430300df344fSAndy Whitcroft			if ($err ne '') {
4304000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
4305000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
4306de7d4f0eSAndy Whitcroft			}
4307de7d4f0eSAndy Whitcroft		}
4308de7d4f0eSAndy Whitcroft
4309de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
4310de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
43110fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
4312773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
4313773647a0SAndy Whitcroft
43149c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
43158eef05ddSJoe Perches
43168eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
43178eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
43188eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
43198eef05ddSJoe Perches			}
43208eef05ddSJoe Perches
4321de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
4322de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
4323de7d4f0eSAndy Whitcroft
4324548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
4325548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
4326de7d4f0eSAndy Whitcroft
4327548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
4328548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
4329548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
4330548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
4331548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
4332773647a0SAndy Whitcroft				$ctx_ln++;
4333773647a0SAndy Whitcroft			}
4334548596d5SAndy Whitcroft
433553210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
433653210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
4337773647a0SAndy Whitcroft
4338773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
4339000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
4340000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
434101464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
434200df344fSAndy Whitcroft			}
4343773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
4344773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
4345773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
4346773647a0SAndy Whitcroft			{
43479c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
43489c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
4349000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
4350000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
435101464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
43529c0ca6f9SAndy Whitcroft				}
43539c0ca6f9SAndy Whitcroft			}
435400df344fSAndy Whitcroft		}
435500df344fSAndy Whitcroft
43564d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
4357f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
43583e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
43593e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
43603e469cdcSAndy Whitcroft					if (!defined $stat);
43614d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
43624d001e4dSAndy Whitcroft
43634d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
43644d001e4dSAndy Whitcroft
43659f5af480SJoe Perches			# remove inline comments
43669f5af480SJoe Perches			$s =~ s/$;/ /g;
43679f5af480SJoe Perches			$c =~ s/$;/ /g;
43684d001e4dSAndy Whitcroft
43694d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
43706f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
43716f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
43724d001e4dSAndy Whitcroft
43739f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
43749f5af480SJoe Perches			# none on the first line, and are going to readd them
43759f5af480SJoe Perches			# where necessary.
43769f5af480SJoe Perches			$s =~ s/\n./\n/gs;
43779f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
43789f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
43799f5af480SJoe Perches			}
43809f5af480SJoe Perches
43814d001e4dSAndy Whitcroft			# We want to check the first line inside the block
43824d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
43834d001e4dSAndy Whitcroft			#  1) any blank line termination
43844d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
43854d001e4dSAndy Whitcroft			#  3) any do (...) {
43864d001e4dSAndy Whitcroft			my $continuation = 0;
43874d001e4dSAndy Whitcroft			my $check = 0;
43884d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
43894d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
43904d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
43914d001e4dSAndy Whitcroft				$continuation = 1;
43924d001e4dSAndy Whitcroft			}
43939bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
43944d001e4dSAndy Whitcroft				$check = 1;
43954d001e4dSAndy Whitcroft				$cond_lines++;
43964d001e4dSAndy Whitcroft			}
43974d001e4dSAndy Whitcroft
43984d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
43994d001e4dSAndy Whitcroft			# preprocessor statement.
44004d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
44014d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
44024d001e4dSAndy Whitcroft				$check = 0;
44034d001e4dSAndy Whitcroft			}
44044d001e4dSAndy Whitcroft
44059bd49efeSAndy Whitcroft			my $cond_ptr = -1;
4406740504c6SAndy Whitcroft			$continuation = 0;
44079bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
44089bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
44094d001e4dSAndy Whitcroft
4410f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
4411f16fa28fSAndy Whitcroft				# is not linear.
4412f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
4413f16fa28fSAndy Whitcroft					$check = 0;
4414f16fa28fSAndy Whitcroft				}
4415f16fa28fSAndy Whitcroft
44169bd49efeSAndy Whitcroft				# Ignore:
44179bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
44189bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
44199bd49efeSAndy Whitcroft				#  3) labels.
4420740504c6SAndy Whitcroft				if ($continuation ||
4421740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
44229bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
44239bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
4424740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
442530dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
44269bd49efeSAndy Whitcroft						$cond_lines++;
44279bd49efeSAndy Whitcroft					}
44284d001e4dSAndy Whitcroft				}
442930dad6ebSAndy Whitcroft			}
44304d001e4dSAndy Whitcroft
44314d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
44324d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
44334d001e4dSAndy Whitcroft
44344d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
44354d001e4dSAndy Whitcroft			# this is not this patch's fault.
44364d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
44374d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
44384d001e4dSAndy Whitcroft				$check = 0;
44394d001e4dSAndy Whitcroft			}
44404d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
44414d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
44424d001e4dSAndy Whitcroft			}
44434d001e4dSAndy Whitcroft
44449bd49efeSAndy 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";
44454d001e4dSAndy Whitcroft
44469f5af480SJoe Perches			if ($check && $s ne '' &&
4447713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
44489f5af480SJoe Perches			     ($sindent < $indent) ||
4449f6950a73SJoe Perches			     ($sindent == $indent &&
4450f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
4451713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
4452000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
4453000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
44544d001e4dSAndy Whitcroft			}
44554d001e4dSAndy Whitcroft		}
44564d001e4dSAndy Whitcroft
44576c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
44586c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
44591f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
44601f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
44616c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
4462c2fdda0dSAndy Whitcroft		if ($dbg_values) {
4463c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
4464cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
4465cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
44661f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
4467c2fdda0dSAndy Whitcroft		}
44686c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
44696c72ffaaSAndy Whitcroft
447000df344fSAndy Whitcroft#ignore lines not being added
44713705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
447200df344fSAndy Whitcroft
447399ca38c2SJoe Perches# check for self assignments used to avoid compiler warnings
447499ca38c2SJoe Perches# e.g.:	int foo = foo, *bar = NULL;
447599ca38c2SJoe Perches#	struct foo bar = *(&(bar));
447699ca38c2SJoe Perches		if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) {
447799ca38c2SJoe Perches			my $var = $1;
447899ca38c2SJoe Perches			if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) {
447999ca38c2SJoe Perches				WARN("SELF_ASSIGNMENT",
448099ca38c2SJoe Perches				     "Do not use self-assignments to avoid compiler warnings\n" . $herecurr);
448199ca38c2SJoe Perches			}
448299ca38c2SJoe Perches		}
448399ca38c2SJoe Perches
448411ca40a0SJoe Perches# check for dereferences that span multiple lines
448511ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
448611ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
448711ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
448811ca40a0SJoe Perches			my $ref = $1;
448911ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
449011ca40a0SJoe Perches			$ref .= $1;
449111ca40a0SJoe Perches			$ref =~ s/\s//g;
449211ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
449311ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
449411ca40a0SJoe Perches		}
449511ca40a0SJoe Perches
4496a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
4497c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
4498a1ce18e4SJoe Perches			my $type = $1;
4499a1ce18e4SJoe Perches			my $var = $2;
4500207a8e84SJoe Perches			$var = "" if (!defined $var);
4501207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
4502a1ce18e4SJoe Perches				my $sign = $1;
4503a1ce18e4SJoe Perches				my $pointer = $2;
4504a1ce18e4SJoe Perches
4505a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
4506a1ce18e4SJoe Perches
4507a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
4508a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
4509a1ce18e4SJoe Perches				    $fix) {
4510a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
4511207a8e84SJoe Perches					my $comp_pointer = $pointer;
4512207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
4513207a8e84SJoe Perches					$decl .= $comp_pointer;
4514207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
4515207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
4516a1ce18e4SJoe Perches				}
4517a1ce18e4SJoe Perches			}
4518a1ce18e4SJoe Perches		}
4519a1ce18e4SJoe Perches
4520653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
45217429c690SAndy Whitcroft		if ($dbg_type) {
45227429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
4523000d1cc1SJoe Perches				ERROR("TEST_TYPE",
4524000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
45257429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
4526000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
4527000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
45287429c690SAndy Whitcroft			}
4529653d4876SAndy Whitcroft			next;
4530653d4876SAndy Whitcroft		}
4531a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
4532a1ef277eSAndy Whitcroft		if ($dbg_attr) {
45339360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
4534000d1cc1SJoe Perches				ERROR("TEST_ATTR",
4535000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
45369360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
4537000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
4538000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
4539a1ef277eSAndy Whitcroft			}
4540a1ef277eSAndy Whitcroft			next;
4541a1ef277eSAndy Whitcroft		}
4542653d4876SAndy Whitcroft
4543f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
454499423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
454599423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
4546d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
4547d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
4548f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
4549f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
4550f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
4551d752fcc8SJoe Perches				my $fixedline = $prevrawline;
4552d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
4553f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4554d752fcc8SJoe Perches				$fixedline = $line;
45558d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
4556f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
4557d752fcc8SJoe Perches			}
4558f0a594c1SAndy Whitcroft		}
4559f0a594c1SAndy Whitcroft
456000df344fSAndy Whitcroft#
456100df344fSAndy Whitcroft# Checks which are anchored on the added line.
456200df344fSAndy Whitcroft#
456300df344fSAndy Whitcroft
4564653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
4565c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
4566653d4876SAndy Whitcroft			my $path = $1;
4567653d4876SAndy Whitcroft			if ($path =~ m{//}) {
4568000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
4569495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
4570495e9d84SJoe Perches			}
4571495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
4572495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
4573495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
4574653d4876SAndy Whitcroft			}
4575653d4876SAndy Whitcroft		}
4576653d4876SAndy Whitcroft
457700df344fSAndy Whitcroft# no C99 // comments
457800df344fSAndy Whitcroft		if ($line =~ m{//}) {
45793705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
45803705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
45813705ce5bSJoe Perches			    $fix) {
4582194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
45833705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
45843705ce5bSJoe Perches					my $comment = trim($1);
4585194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
45863705ce5bSJoe Perches				}
45873705ce5bSJoe Perches			}
458800df344fSAndy Whitcroft		}
458900df344fSAndy Whitcroft		# Remove C99 comments.
45900a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
45916c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
45920a920b5bSAndy Whitcroft
45932b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
45942b474a1aSAndy Whitcroft# the whole statement.
45952b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
45962b474a1aSAndy Whitcroft		if (defined $realline_next &&
45972b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
45982b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
459936794822SChristoph Hellwig		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
46003cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
46013cbf62dfSAndy Whitcroft			# a prefix:
46023cbf62dfSAndy Whitcroft			#   XXX(foo);
46033cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
4604653d4876SAndy Whitcroft			my $name = $1;
460570a11659SJoe Perches			$name =~ s/^\s*($Ident).*/$1/;
460687a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
46073cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
46083cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
46093cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
46103cbf62dfSAndy Whitcroft
46113cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
46122b474a1aSAndy Whitcroft				\n.}\s*$|
461348012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
461448012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
461548012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
46162b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
46172b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
461848012058SAndy Whitcroft			    )/x) {
46192b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
46202b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
46212b474a1aSAndy Whitcroft			} else {
46222b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
46230a920b5bSAndy Whitcroft			}
46240a920b5bSAndy Whitcroft		}
46252b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
46262b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
462736794822SChristoph Hellwig		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/)) {
46282b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
46292b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
46302b474a1aSAndy Whitcroft		}
46312b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
46322b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4633000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4634000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
46352b474a1aSAndy Whitcroft		}
46360a920b5bSAndy Whitcroft
46375150bda4SJoe Eloff# check for global initialisers.
46385b8f82e1SSong Liu		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/ &&
46395b8f82e1SSong Liu		    !exclude_global_initialisers($realfile)) {
4640d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
46416d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4642d5e616fcSJoe Perches			    $fix) {
46436d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4644d5e616fcSJoe Perches			}
4645f0a594c1SAndy Whitcroft		}
46460a920b5bSAndy Whitcroft# check for static initialisers.
46476d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4648d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
46496d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4650d5e616fcSJoe Perches				      $herecurr) &&
4651d5e616fcSJoe Perches			    $fix) {
46526d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4653d5e616fcSJoe Perches			}
46540a920b5bSAndy Whitcroft		}
46550a920b5bSAndy Whitcroft
46561813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
46571813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
46581813087dSJoe Perches			my $tmp = trim($1);
46591813087dSJoe Perches			WARN("MISORDERED_TYPE",
46601813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
46611813087dSJoe Perches		}
46621813087dSJoe Perches
4663809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4664809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4665809e082eSJoe Perches			my $type = trim($1);
4666809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4667809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4668809e082eSJoe Perches			my $new_type = $type;
4669809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4670809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4671809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4672809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4673809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4674809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4675809e082eSJoe Perches			$new_type = trim($new_type);
4676809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4677809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4678809e082eSJoe Perches			    $fix) {
4679809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4680809e082eSJoe Perches			}
4681809e082eSJoe Perches		}
4682809e082eSJoe Perches
4683cb710ecaSJoe Perches# check for static const char * arrays.
4684cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4685000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4686000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4687cb710ecaSJoe Perches				$herecurr);
4688cb710ecaSJoe Perches		}
4689cb710ecaSJoe Perches
469077b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
469177b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
469277b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
469377b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
469477b8c0a8SJoe Perches			    $fix) {
469577b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
469677b8c0a8SJoe Perches			}
469777b8c0a8SJoe Perches		}
469877b8c0a8SJoe Perches
4699cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4700cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4701000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4702000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4703cb710ecaSJoe Perches				$herecurr);
4704cb710ecaSJoe Perches		}
4705cb710ecaSJoe Perches
4706ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4707ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4708ab7e23f3SJoe Perches			my $found = $1;
4709ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4710ab7e23f3SJoe Perches				WARN("CONST_CONST",
4711ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4712ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4713ab7e23f3SJoe Perches				WARN("CONST_CONST",
4714ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4715ab7e23f3SJoe Perches			}
4716ab7e23f3SJoe Perches		}
4717ab7e23f3SJoe Perches
471873169765SJoe Perches# check for const static or static <non ptr type> const declarations
471973169765SJoe Perches# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'
472073169765SJoe Perches		if ($sline =~ /^\+\s*const\s+static\s+($Type)\b/ ||
472173169765SJoe Perches		    $sline =~ /^\+\s*static\s+($BasicType)\s+const\b/) {
472273169765SJoe Perches			if (WARN("STATIC_CONST",
472373169765SJoe Perches				 "Move const after static - use 'static const $1'\n" . $herecurr) &&
472473169765SJoe Perches			    $fix) {
472573169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bconst\s+static\b/static const/;
472673169765SJoe Perches				$fixed[$fixlinenr] =~ s/\bstatic\s+($BasicType)\s+const\b/static const $1/;
472773169765SJoe Perches			}
472873169765SJoe Perches		}
472973169765SJoe Perches
47309b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
47319b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
47329b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
47339b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
47349b0fa60dSJoe Perches				$herecurr);
47359b0fa60dSJoe Perches		}
47369b0fa60dSJoe Perches
4737b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4738b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4739b598b670SJoe Perches			my $array = $1;
4740b598b670SJoe 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*\))@) {
4741b598b670SJoe Perches				my $array_div = $1;
4742b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4743b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4744b598b670SJoe Perches				    $fix) {
4745b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4746b598b670SJoe Perches				}
4747b598b670SJoe Perches			}
4748b598b670SJoe Perches		}
4749b598b670SJoe Perches
4750b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
475116b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4752b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4753b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4754b36190c5SJoe Perches			    $fix) {
4755194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4756b36190c5SJoe Perches			}
4757b36190c5SJoe Perches		}
4758b36190c5SJoe Perches
4759653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4760653d4876SAndy Whitcroft# make sense.
4761653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
47628054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4763c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
47648ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
476546d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4766000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4767000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
47680a920b5bSAndy Whitcroft		}
47690a920b5bSAndy Whitcroft
47700a920b5bSAndy Whitcroft# * goes on variable not on type
477165863862SAndy Whitcroft		# (char*[ const])
4772bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4773bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
47743705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4775d8aaf121SAndy Whitcroft
477665863862SAndy Whitcroft			# Should start with a space.
477765863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
477865863862SAndy Whitcroft			# Should not end with a space.
477965863862SAndy Whitcroft			$to =~ s/\s+$//;
478065863862SAndy Whitcroft			# '*'s should not have spaces between.
4781f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
478265863862SAndy Whitcroft			}
4783d8aaf121SAndy Whitcroft
47843705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
478565863862SAndy Whitcroft			if ($from ne $to) {
47863705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
47873705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
47883705ce5bSJoe Perches				    $fix) {
47893705ce5bSJoe Perches					my $sub_from = $ident;
47903705ce5bSJoe Perches					my $sub_to = $ident;
47913705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4792194f66fcSJoe Perches					$fixed[$fixlinenr] =~
47933705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
47943705ce5bSJoe Perches				}
479565863862SAndy Whitcroft			}
4796bfcb2cc7SAndy Whitcroft		}
4797bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4798bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
47993705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4800d8aaf121SAndy Whitcroft
480165863862SAndy Whitcroft			# Should start with a space.
480265863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
480365863862SAndy Whitcroft			# Should not end with a space.
480465863862SAndy Whitcroft			$to =~ s/\s+$//;
480565863862SAndy Whitcroft			# '*'s should not have spaces between.
4806f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
480765863862SAndy Whitcroft			}
480865863862SAndy Whitcroft			# Modifiers should have spaces.
480965863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
481065863862SAndy Whitcroft
48113705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4812667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
48133705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
48143705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
48153705ce5bSJoe Perches				    $fix) {
48163705ce5bSJoe Perches
48173705ce5bSJoe Perches					my $sub_from = $match;
48183705ce5bSJoe Perches					my $sub_to = $match;
48193705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4820194f66fcSJoe Perches					$fixed[$fixlinenr] =~
48213705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
48223705ce5bSJoe Perches				}
482365863862SAndy Whitcroft			}
48240a920b5bSAndy Whitcroft		}
48250a920b5bSAndy Whitcroft
482669d517e6SDavid Hildenbrand# do not use BUG() or variants
482769d517e6SDavid Hildenbrand		if ($line =~ /\b(?!AA_|BUILD_|DCCP_|IDA_|KVM_|RWLOCK_|snd_|SPIN_)(?:[a-zA-Z_]*_)?BUG(?:_ON)?(?:_[A-Z_]+)?\s*\(/) {
48280675a8fbSJean Delvare			my $msg_level = \&WARN;
48290675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
48300675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
483169d517e6SDavid Hildenbrand				      "Do not crash the kernel unless it is absolutely unavoidable--use WARN_ON_ONCE() plus recovery code (if feasible) instead of BUG() or variants\n" . $herecurr);
48329d3e3c70SJoe Perches		}
48330a920b5bSAndy Whitcroft
48349d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
48358905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4836000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4837000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
48388905a67cSAndy Whitcroft		}
48398905a67cSAndy Whitcroft
484017441227SJoe Perches# check for uses of printk_ratelimit
484117441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4842000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4843000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
484417441227SJoe Perches		}
484517441227SJoe Perches
4846eeef5733SJoe Perches# printk should use KERN_* levels
4847eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4848000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4849eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
485000df344fSAndy Whitcroft		}
48510a920b5bSAndy Whitcroft
4852f5eea3b0SJoe Perches# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>
4853f5eea3b0SJoe Perches		if ($line =~ /\b(printk(_once|_ratelimited)?)\s*\(\s*KERN_([A-Z]+)/) {
4854f5eea3b0SJoe Perches			my $printk = $1;
4855f5eea3b0SJoe Perches			my $modifier = $2;
4856f5eea3b0SJoe Perches			my $orig = $3;
4857f5eea3b0SJoe Perches			$modifier = "" if (!defined($modifier));
4858243f3803SJoe Perches			my $level = lc($orig);
4859243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
48608f26b837SJoe Perches			my $level2 = $level;
48618f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4862f5eea3b0SJoe Perches			$level .= $modifier;
4863f5eea3b0SJoe Perches			$level2 .= $modifier;
4864243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4865f5eea3b0SJoe Perches			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\n" . $herecurr);
4866243f3803SJoe Perches		}
4867243f3803SJoe Perches
4868f5eea3b0SJoe Perches# prefer dev_<level> to dev_printk(KERN_<LEVEL>
4869dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4870dc139313SJoe Perches			my $orig = $1;
4871dc139313SJoe Perches			my $level = lc($orig);
4872dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4873dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4874dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4875dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4876dc139313SJoe Perches		}
4877dc139313SJoe Perches
48788020b253SNicolas Boichat# trace_printk should not be used in production code.
48798020b253SNicolas Boichat		if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) {
48808020b253SNicolas Boichat			WARN("TRACE_PRINTK",
48818020b253SNicolas Boichat			     "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr);
48828020b253SNicolas Boichat		}
48838020b253SNicolas Boichat
488491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
488591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
488691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
488791c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
488891c9afafSAndy Lutomirski			WARN("ENOSYS",
488991c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
489091c9afafSAndy Lutomirski		}
489191c9afafSAndy Lutomirski
48926b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
48936b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
48946b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
48956b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
48966b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
48976b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
48986b9ea5ffSJakub Kicinski			    $fix) {
48996b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
49006b9ea5ffSJakub Kicinski			}
49016b9ea5ffSJakub Kicinski		}
49026b9ea5ffSJakub Kicinski
4903653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4904653d4876SAndy Whitcroft# or if closed on same line
49055b57980dSJoe Perches		if ($perl_version_ok &&
49062d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
49072d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
49082d453e3bSJoe Perches		    $sline !~ /}/) {
49098d182478SJoe Perches			if (ERROR("OPEN_BRACE",
49102d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
49118d182478SJoe Perches			    $fix) {
49128d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
49138d182478SJoe Perches				my $fixed_line = $rawline;
491403f49351SDwaipayan Ray				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/;
49158d182478SJoe Perches				my $line1 = $1;
49168d182478SJoe Perches				my $line2 = $2;
49178d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
49188d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
49198d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
49208d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
49218d182478SJoe Perches				}
49228d182478SJoe Perches			}
49230a920b5bSAndy Whitcroft		}
4924653d4876SAndy Whitcroft
49258905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
49268905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
49278905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
49288d182478SJoe Perches			if (ERROR("OPEN_BRACE",
49298d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
49308d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
49318d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
49328d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
49338d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
49348d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
49358d182478SJoe Perches				$fixedline = $rawline;
49368d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
49378d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
49388d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
49398d182478SJoe Perches				}
49408d182478SJoe Perches			}
49418905a67cSAndy Whitcroft		}
49428905a67cSAndy Whitcroft
49430c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
49443705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
49453705ce5bSJoe Perches			if (WARN("SPACING",
49463705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
49473705ce5bSJoe Perches			    $fix) {
4948194f66fcSJoe Perches				$fixed[$fixlinenr] =~
49493705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
49503705ce5bSJoe Perches			}
49510c73b4ebSAndy Whitcroft		}
49520c73b4ebSAndy Whitcroft
495331070b5dSJoe Perches# Function pointer declarations
495431070b5dSJoe Perches# check spacing between type, funcptr, and args
495531070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
495691f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
495731070b5dSJoe Perches			my $declare = $1;
495831070b5dSJoe Perches			my $pre_pointer_space = $2;
495931070b5dSJoe Perches			my $post_pointer_space = $3;
496031070b5dSJoe Perches			my $funcname = $4;
496131070b5dSJoe Perches			my $post_funcname_space = $5;
496231070b5dSJoe Perches			my $pre_args_space = $6;
496331070b5dSJoe Perches
496491f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
496591f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
496691f72e9cSJoe Perches# don't need a space so don't warn for those.
496791f72e9cSJoe Perches			my $post_declare_space = "";
496891f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
496991f72e9cSJoe Perches				$post_declare_space = $1;
497091f72e9cSJoe Perches				$declare = rtrim($declare);
497191f72e9cSJoe Perches			}
497291f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
497331070b5dSJoe Perches				WARN("SPACING",
497431070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
497591f72e9cSJoe Perches				$post_declare_space = " ";
497631070b5dSJoe Perches			}
497731070b5dSJoe Perches
497831070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
497991f72e9cSJoe Perches# This test is not currently implemented because these declarations are
498091f72e9cSJoe Perches# equivalent to
498191f72e9cSJoe Perches#	int  foo(int bar, ...)
498291f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
498391f72e9cSJoe Perches#
498491f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
498591f72e9cSJoe Perches#				WARN("SPACING",
498691f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
498791f72e9cSJoe Perches#			}
498831070b5dSJoe Perches
498931070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
499031070b5dSJoe Perches			if (defined $pre_pointer_space &&
499131070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
499231070b5dSJoe Perches				WARN("SPACING",
499331070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
499431070b5dSJoe Perches			}
499531070b5dSJoe Perches
499631070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
499731070b5dSJoe Perches			if (defined $post_pointer_space &&
499831070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
499931070b5dSJoe Perches				WARN("SPACING",
500031070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
500131070b5dSJoe Perches			}
500231070b5dSJoe Perches
500331070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
500431070b5dSJoe Perches			if (defined $post_funcname_space &&
500531070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
500631070b5dSJoe Perches				WARN("SPACING",
500731070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
500831070b5dSJoe Perches			}
500931070b5dSJoe Perches
501031070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
501131070b5dSJoe Perches			if (defined $pre_args_space &&
501231070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
501331070b5dSJoe Perches				WARN("SPACING",
501431070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
501531070b5dSJoe Perches			}
501631070b5dSJoe Perches
501731070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
5018194f66fcSJoe Perches				$fixed[$fixlinenr] =~
501991f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
502031070b5dSJoe Perches			}
502131070b5dSJoe Perches		}
502231070b5dSJoe Perches
50238d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
50248d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
5025fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
5026fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
50278d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
50288d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
50298d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
5030fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
503138dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
50323705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
50333705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
50343705ce5bSJoe Perches				    $fix) {
5035194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
50363705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
50373705ce5bSJoe Perches				}
50388d31cfceSAndy Whitcroft			}
50398d31cfceSAndy Whitcroft		}
50408d31cfceSAndy Whitcroft
5041f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
50426c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
5043c2fdda0dSAndy Whitcroft			my $name = $1;
5044773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
5045773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
5046c2fdda0dSAndy Whitcroft
5047c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
5048773647a0SAndy Whitcroft			if ($name =~ /^(?:
5049773647a0SAndy Whitcroft				if|for|while|switch|return|case|
5050773647a0SAndy Whitcroft				volatile|__volatile__|
5051773647a0SAndy Whitcroft				__attribute__|format|__extension__|
505254da6a09SPeter Zijlstra				asm|__asm__|scoped_guard)$/x)
5053773647a0SAndy Whitcroft			{
5054c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
5055c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
5056c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
5057c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
5058773647a0SAndy Whitcroft
5059773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
5060c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
5061c2fdda0dSAndy Whitcroft
5062c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
5063c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
5064773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
5065c2fdda0dSAndy Whitcroft
5066c2fdda0dSAndy Whitcroft			} else {
50673705ce5bSJoe Perches				if (WARN("SPACING",
50683705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
50693705ce5bSJoe Perches					     $fix) {
5070194f66fcSJoe Perches					$fixed[$fixlinenr] =~
50713705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
50723705ce5bSJoe Perches				}
5073f0a594c1SAndy Whitcroft			}
50746c72ffaaSAndy Whitcroft		}
50759a4cad4eSEric Nelson
5076653d4876SAndy Whitcroft# Check operator spacing.
50770a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
50783705ce5bSJoe Perches			my $fixed_line = "";
50793705ce5bSJoe Perches			my $line_fixed = 0;
50803705ce5bSJoe Perches
50819c0ca6f9SAndy Whitcroft			my $ops = qr{
50829c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
50839c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
50849c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
50851f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
508684731623SJoe Perches				\?:|\?|:
50879c0ca6f9SAndy Whitcroft			}x;
5088cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
50893705ce5bSJoe Perches
50903705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
50913705ce5bSJoe Perches##			foreach my $el (@elements) {
50923705ce5bSJoe Perches##				print("el: <$el>\n");
50933705ce5bSJoe Perches##			}
50943705ce5bSJoe Perches
50953705ce5bSJoe Perches			my @fix_elements = ();
509600df344fSAndy Whitcroft			my $off = 0;
50976c72ffaaSAndy Whitcroft
50983705ce5bSJoe Perches			foreach my $el (@elements) {
50993705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
51003705ce5bSJoe Perches				$off += length($el);
51013705ce5bSJoe Perches			}
51023705ce5bSJoe Perches
51033705ce5bSJoe Perches			$off = 0;
51043705ce5bSJoe Perches
51056c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
5106b34c648bSJoe Perches			my $last_after = -1;
51076c72ffaaSAndy Whitcroft
51080a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
51093705ce5bSJoe Perches
51103705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
51113705ce5bSJoe Perches
51123705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
51133705ce5bSJoe Perches
51144a0df2efSAndy Whitcroft				$off += length($elements[$n]);
51154a0df2efSAndy Whitcroft
511625985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
5117773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
5118773647a0SAndy Whitcroft				my $cc = '';
5119773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
5120773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
5121773647a0SAndy Whitcroft				}
5122773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
5123773647a0SAndy Whitcroft
51244a0df2efSAndy Whitcroft				my $a = '';
51254a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
51264a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
5127cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
51284a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
51294a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
5130773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
51314a0df2efSAndy Whitcroft
51320a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
51334a0df2efSAndy Whitcroft
51344a0df2efSAndy Whitcroft				my $c = '';
51350a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
51364a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
51374a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
5138cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
51394a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
51404a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
51418b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
51424a0df2efSAndy Whitcroft				} else {
51434a0df2efSAndy Whitcroft					$c = 'E';
51440a920b5bSAndy Whitcroft				}
51450a920b5bSAndy Whitcroft
51464a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
51474a0df2efSAndy Whitcroft
51484a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
51494a0df2efSAndy Whitcroft
51506c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
5151de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
51520a920b5bSAndy Whitcroft
515374048ed8SAndy Whitcroft				# Pull out the value of this operator.
51546c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
51550a920b5bSAndy Whitcroft
51561f65f947SAndy Whitcroft				# Get the full operator variant.
51571f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
51581f65f947SAndy Whitcroft
515913214adfSAndy Whitcroft				# Ignore operators passed as parameters.
516013214adfSAndy Whitcroft				if ($op_type ne 'V' &&
5161d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
516213214adfSAndy Whitcroft
5163cf655043SAndy Whitcroft#				# Ignore comments
5164cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
516513214adfSAndy Whitcroft
5166d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
516713214adfSAndy Whitcroft				} elsif ($op eq ';') {
5168cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
5169cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
51703705ce5bSJoe Perches						if (ERROR("SPACING",
51713705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
5172b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
51733705ce5bSJoe Perches							$line_fixed = 1;
51743705ce5bSJoe Perches						}
5175d8aaf121SAndy Whitcroft					}
5176d8aaf121SAndy Whitcroft
5177d8aaf121SAndy Whitcroft				# // is a comment
5178d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
51790a920b5bSAndy Whitcroft
5180b00e4814SJoe Perches				#   :   when part of a bitfield
5181b00e4814SJoe Perches				} elsif ($opv eq ':B') {
5182b00e4814SJoe Perches					# skip the bitfield test for now
5183b00e4814SJoe Perches
51841f65f947SAndy Whitcroft				# No spaces for:
51851f65f947SAndy Whitcroft				#   ->
5186b00e4814SJoe Perches				} elsif ($op eq '->') {
51874a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
51883705ce5bSJoe Perches						if (ERROR("SPACING",
51893705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
5190b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
51913705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
51923705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
51933705ce5bSJoe Perches							}
5194b34c648bSJoe Perches							$line_fixed = 1;
51953705ce5bSJoe Perches						}
51960a920b5bSAndy Whitcroft					}
51970a920b5bSAndy Whitcroft
51982381097bSJoe Perches				# , must not have a space before and must have a space on the right.
51990a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
52002381097bSJoe Perches					my $rtrim_before = 0;
52012381097bSJoe Perches					my $space_after = 0;
52022381097bSJoe Perches					if ($ctx =~ /Wx./) {
52032381097bSJoe Perches						if (ERROR("SPACING",
52042381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
52052381097bSJoe Perches							$line_fixed = 1;
52062381097bSJoe Perches							$rtrim_before = 1;
52072381097bSJoe Perches						}
52082381097bSJoe Perches					}
5209cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
52103705ce5bSJoe Perches						if (ERROR("SPACING",
52113705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
52123705ce5bSJoe Perches							$line_fixed = 1;
5213b34c648bSJoe Perches							$last_after = $n;
52142381097bSJoe Perches							$space_after = 1;
52152381097bSJoe Perches						}
52162381097bSJoe Perches					}
52172381097bSJoe Perches					if ($rtrim_before || $space_after) {
52182381097bSJoe Perches						if ($rtrim_before) {
52192381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
52202381097bSJoe Perches						} else {
52212381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
52222381097bSJoe Perches						}
52232381097bSJoe Perches						if ($space_after) {
52242381097bSJoe Perches							$good .= " ";
52253705ce5bSJoe Perches						}
52260a920b5bSAndy Whitcroft					}
52270a920b5bSAndy Whitcroft
52289c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
522974048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
52309c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
52319c0ca6f9SAndy Whitcroft
52329c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
52339c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
52349c0ca6f9SAndy Whitcroft				# unary operator, or a cast
52359c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
523674048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
52370d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
5238cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
52393705ce5bSJoe Perches						if (ERROR("SPACING",
52403705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
5241b34c648bSJoe Perches							if ($n != $last_after + 2) {
5242b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
52433705ce5bSJoe Perches								$line_fixed = 1;
52443705ce5bSJoe Perches							}
52450a920b5bSAndy Whitcroft						}
5246b34c648bSJoe Perches					}
5247a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
5248171ae1a4SAndy Whitcroft						# A unary '*' may be const
5249171ae1a4SAndy Whitcroft
5250171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
52513705ce5bSJoe Perches						if (ERROR("SPACING",
52523705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5253b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
52543705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
52553705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
52563705ce5bSJoe Perches							}
5257b34c648bSJoe Perches							$line_fixed = 1;
52583705ce5bSJoe Perches						}
52590a920b5bSAndy Whitcroft					}
52600a920b5bSAndy Whitcroft
52610a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
52620a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
5263773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
52643705ce5bSJoe Perches						if (ERROR("SPACING",
52653705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
5266b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
52673705ce5bSJoe Perches							$line_fixed = 1;
52683705ce5bSJoe Perches						}
52690a920b5bSAndy Whitcroft					}
5270773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
5271773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
52723705ce5bSJoe Perches						if (ERROR("SPACING",
52733705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5274b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
52753705ce5bSJoe Perches							$line_fixed = 1;
52763705ce5bSJoe Perches						}
5277653d4876SAndy Whitcroft					}
5278773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
52793705ce5bSJoe Perches						if (ERROR("SPACING",
52803705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
5281b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
52823705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
52833705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5284773647a0SAndy Whitcroft							}
5285b34c648bSJoe Perches							$line_fixed = 1;
52863705ce5bSJoe Perches						}
52873705ce5bSJoe Perches					}
52880a920b5bSAndy Whitcroft
52890a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
52909c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
52919c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
52929c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
5293c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
5294c2fdda0dSAndy Whitcroft					 $op eq '%')
52950a920b5bSAndy Whitcroft				{
5296d2e025f3SJoe Perches					if ($check) {
5297d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
5298d2e025f3SJoe Perches							if (CHK("SPACING",
5299d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
5300d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5301d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5302d2e025f3SJoe Perches								$line_fixed = 1;
5303d2e025f3SJoe Perches							}
5304d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
5305d2e025f3SJoe Perches							if (CHK("SPACING",
5306d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
5307d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
5308d2e025f3SJoe Perches								$line_fixed = 1;
5309d2e025f3SJoe Perches							}
5310d2e025f3SJoe Perches						}
5311d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
53123705ce5bSJoe Perches						if (ERROR("SPACING",
53133705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
5314b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5315b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5316b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5317b34c648bSJoe Perches							}
53183705ce5bSJoe Perches							$line_fixed = 1;
53193705ce5bSJoe Perches						}
53200a920b5bSAndy Whitcroft					}
53210a920b5bSAndy Whitcroft
53221f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
53231f65f947SAndy Whitcroft				# terminating a case value or a label.
53241f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
5325263afd39SChris Down					if ($ctx =~ /Wx./ and $realfile !~ m@.*\.lds\.h$@) {
53263705ce5bSJoe Perches						if (ERROR("SPACING",
53273705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
5328b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
53293705ce5bSJoe Perches							$line_fixed = 1;
53303705ce5bSJoe Perches						}
53311f65f947SAndy Whitcroft					}
53321f65f947SAndy Whitcroft
53330a920b5bSAndy Whitcroft				# All the others need spaces both sides.
5334cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
53351f65f947SAndy Whitcroft					my $ok = 0;
53361f65f947SAndy Whitcroft
533722f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
53381f65f947SAndy Whitcroft					if (($op eq '<' &&
53391f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
53401f65f947SAndy Whitcroft					    ($op eq '>' &&
53411f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
53421f65f947SAndy Whitcroft					{
53431f65f947SAndy Whitcroft						$ok = 1;
53441f65f947SAndy Whitcroft					}
53451f65f947SAndy Whitcroft
5346e0df7e1fSJoe Perches					# for asm volatile statements
5347e0df7e1fSJoe Perches					# ignore a colon with another
5348e0df7e1fSJoe Perches					# colon immediately before or after
5349e0df7e1fSJoe Perches					if (($op eq ':') &&
5350e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
5351e0df7e1fSJoe Perches						$ok = 1;
5352e0df7e1fSJoe Perches					}
5353e0df7e1fSJoe Perches
535484731623SJoe Perches					# messages are ERROR, but ?: are CHK
53551f65f947SAndy Whitcroft					if ($ok == 0) {
53560675a8fbSJean Delvare						my $msg_level = \&ERROR;
53570675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
535884731623SJoe Perches
53590675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
53603705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
5361b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
5362b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
5363b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
5364b34c648bSJoe Perches							}
53653705ce5bSJoe Perches							$line_fixed = 1;
53663705ce5bSJoe Perches						}
53670a920b5bSAndy Whitcroft					}
536822f2a2efSAndy Whitcroft				}
53694a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
53703705ce5bSJoe Perches
53713705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
53723705ce5bSJoe Perches
53733705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
53740a920b5bSAndy Whitcroft			}
53753705ce5bSJoe Perches
53763705ce5bSJoe Perches			if (($#elements % 2) == 0) {
53773705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
53783705ce5bSJoe Perches			}
53793705ce5bSJoe Perches
5380194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
5381194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
53823705ce5bSJoe Perches			}
53833705ce5bSJoe Perches
53843705ce5bSJoe Perches
53850a920b5bSAndy Whitcroft		}
53860a920b5bSAndy Whitcroft
5387786b6326SJoe Perches# check for whitespace before a non-naked semicolon
5388d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
5389786b6326SJoe Perches			if (WARN("SPACING",
5390786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
5391786b6326SJoe Perches			    $fix) {
5392194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
5393786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
5394786b6326SJoe Perches			}
5395786b6326SJoe Perches		}
5396786b6326SJoe Perches
5397f0a594c1SAndy Whitcroft# check for multiple assignments
5398f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
5399000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
5400000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
5401f0a594c1SAndy Whitcroft		}
5402f0a594c1SAndy Whitcroft
540322f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
540422f2a2efSAndy Whitcroft## # continuation.
540522f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
540622f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
540722f2a2efSAndy Whitcroft##
540822f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
5409e73d2715SDwaipayan Ray## 			# falsely report the parameters of functions.
541022f2a2efSAndy Whitcroft## 			my $ln = $line;
541122f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
541222f2a2efSAndy Whitcroft## 			}
541322f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
5414000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
5415000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
541622f2a2efSAndy Whitcroft## 			}
541722f2a2efSAndy Whitcroft## 		}
5418f0a594c1SAndy Whitcroft
54190a920b5bSAndy Whitcroft#need space before brace following if, while, etc
54206b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
54216ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
54223705ce5bSJoe Perches			if (ERROR("SPACING",
54233705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
54243705ce5bSJoe Perches			    $fix) {
54256ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
54263705ce5bSJoe Perches			}
5427de7d4f0eSAndy Whitcroft		}
5428de7d4f0eSAndy Whitcroft
5429c4a62ef9SJoe Perches## # check for blank lines before declarations
5430c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
5431c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
5432c4a62ef9SJoe Perches##			WARN("SPACING",
5433c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
5434c4a62ef9SJoe Perches##		}
5435c4a62ef9SJoe Perches##
5436c4a62ef9SJoe Perches
5437de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
5438de7d4f0eSAndy Whitcroft# on the line
543994fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
5440d5e616fcSJoe Perches			if (ERROR("SPACING",
5441d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
5442d5e616fcSJoe Perches			    $fix) {
5443194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5444d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
5445d5e616fcSJoe Perches			}
54460a920b5bSAndy Whitcroft		}
54470a920b5bSAndy Whitcroft
544822f2a2efSAndy Whitcroft# check spacing on square brackets
544922f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
54503705ce5bSJoe Perches			if (ERROR("SPACING",
54513705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
54523705ce5bSJoe Perches			    $fix) {
5453194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54543705ce5bSJoe Perches				    s/\[\s+/\[/;
54553705ce5bSJoe Perches			}
545622f2a2efSAndy Whitcroft		}
545722f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
54583705ce5bSJoe Perches			if (ERROR("SPACING",
54593705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
54603705ce5bSJoe Perches			    $fix) {
5461194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54623705ce5bSJoe Perches				    s/\s+\]/\]/;
54633705ce5bSJoe Perches			}
546422f2a2efSAndy Whitcroft		}
546522f2a2efSAndy Whitcroft
5466c45dcabdSAndy Whitcroft# check spacing on parentheses
54679c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
54689c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
54693705ce5bSJoe Perches			if (ERROR("SPACING",
54703705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
54713705ce5bSJoe Perches			    $fix) {
5472194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54733705ce5bSJoe Perches				    s/\(\s+/\(/;
54743705ce5bSJoe Perches			}
547522f2a2efSAndy Whitcroft		}
547613214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
5477c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
5478c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
54793705ce5bSJoe Perches			if (ERROR("SPACING",
54803705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
54813705ce5bSJoe Perches			    $fix) {
5482194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54833705ce5bSJoe Perches				    s/\s+\)/\)/;
54843705ce5bSJoe Perches			}
548522f2a2efSAndy Whitcroft		}
548622f2a2efSAndy Whitcroft
5487e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
5488e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
5489e2826fd0SJoe Perches
5490e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
5491ea4acbb1SJoe Perches			my $var = $1;
5492ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5493ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
5494ea4acbb1SJoe Perches			    $fix) {
5495ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
5496ea4acbb1SJoe Perches			}
5497ea4acbb1SJoe Perches		}
5498ea4acbb1SJoe Perches
5499ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
5500ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
5501ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
5502ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
5503ea4acbb1SJoe Perches			my $var = $2;
5504ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
5505ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
5506ea4acbb1SJoe Perches			    $fix) {
5507ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
5508ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
5509ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
5510ea4acbb1SJoe Perches			}
5511e2826fd0SJoe Perches		}
5512e2826fd0SJoe Perches
551363b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
5514a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
5515a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
55165b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
551763b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
551863b7c73eSJoe Perches			my $if_stat = $1;
551963b7c73eSJoe Perches			my $test = substr($2, 1, -1);
552063b7c73eSJoe Perches			my $herectx;
552163b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
552263b7c73eSJoe Perches				my $match = $1;
552363b7c73eSJoe Perches				# avoid parentheses around potential macro args
552463b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
552563b7c73eSJoe Perches				if (!defined($herectx)) {
552663b7c73eSJoe Perches					$herectx = $here . "\n";
552763b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
552863b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
552963b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
553063b7c73eSJoe Perches						$herectx .=  $rl . "\n";
553163b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
553263b7c73eSJoe Perches					}
553363b7c73eSJoe Perches				}
553463b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
553563b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
553663b7c73eSJoe Perches			}
553763b7c73eSJoe Perches		}
553863b7c73eSJoe Perches
553969078651SJoe Perches# check that goto labels aren't indented (allow a single space indentation)
554069078651SJoe Perches# and ignore bitfield definitions like foo:1
554169078651SJoe Perches# Strictly, labels can have whitespace after the identifier and before the :
554269078651SJoe Perches# but this is not allowed here as many ?: uses would appear to be labels
554369078651SJoe Perches		if ($sline =~ /^.\s+[A-Za-z_][A-Za-z\d_]*:(?!\s*\d+)/ &&
554469078651SJoe Perches		    $sline !~ /^. [A-Za-z\d_][A-Za-z\d_]*:/ &&
554569078651SJoe Perches		    $sline !~ /^.\s+default:/) {
55463705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
55473705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
55483705ce5bSJoe Perches			    $fix) {
5549194f66fcSJoe Perches				$fixed[$fixlinenr] =~
55503705ce5bSJoe Perches				    s/^(.)\s+/$1/;
55513705ce5bSJoe Perches			}
55520a920b5bSAndy Whitcroft		}
55530a920b5bSAndy Whitcroft
555440873abaSJoe Perches# check if a statement with a comma should be two statements like:
555540873abaSJoe Perches#	foo = bar(),	/* comma should be semicolon */
555640873abaSJoe Perches#	bar = baz();
555740873abaSJoe Perches		if (defined($stat) &&
555840873abaSJoe Perches		    $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) {
555940873abaSJoe Perches			my $cnt = statement_rawlines($stat);
556040873abaSJoe Perches			my $herectx = get_stat_here($linenr, $cnt, $here);
556140873abaSJoe Perches			WARN("SUSPECT_COMMA_SEMICOLON",
556240873abaSJoe Perches			     "Possible comma where semicolon could be used\n" . $herectx);
556340873abaSJoe Perches		}
556440873abaSJoe Perches
55655b9553abSJoe Perches# return is not a function
5566507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
5567c45dcabdSAndy Whitcroft			my $spacing = $1;
55685b57980dSJoe Perches			if ($perl_version_ok &&
55695b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
55705b9553abSJoe Perches				my $value = $1;
55715b9553abSJoe Perches				$value = deparenthesize($value);
55725b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
5573000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
5574000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
55755b9553abSJoe Perches				}
5576c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
5577000d1cc1SJoe Perches				ERROR("SPACING",
5578000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
5579c45dcabdSAndy Whitcroft			}
5580c45dcabdSAndy Whitcroft		}
5581507e5141SJoe Perches
5582b43ae21bSJoe Perches# unnecessary return in a void function
5583b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
5584b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
5585b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
5586b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
5587b43ae21bSJoe Perches		    $linenr >= 3 &&
5588b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
5589b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
55909819cf25SJoe Perches			WARN("RETURN_VOID",
5591b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
55929819cf25SJoe Perches		}
55939819cf25SJoe Perches
5594189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
55955b57980dSJoe Perches		if ($perl_version_ok &&
5596189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
5597189248d8SJoe Perches			my $openparens = $1;
5598189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
5599189248d8SJoe Perches			my $msg = "";
5600189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
5601189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
5602189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
5603189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
5604189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
5605189248d8SJoe Perches			}
5606189248d8SJoe Perches		}
5607189248d8SJoe Perches
5608c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
5609c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
5610c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
5611c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
56125b57980dSJoe Perches		if ($perl_version_ok &&
5613c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
5614c5595fa2SJoe Perches			my $lead = $1;
5615c5595fa2SJoe Perches			my $const = $2;
5616c5595fa2SJoe Perches			my $comp = $3;
5617c5595fa2SJoe Perches			my $to = $4;
5618c5595fa2SJoe Perches			my $newcomp = $comp;
5619f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
5620c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
5621c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
5622c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
5623c5595fa2SJoe Perches			    $fix) {
5624c5595fa2SJoe Perches				if ($comp eq "<") {
5625c5595fa2SJoe Perches					$newcomp = ">";
5626c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
5627c5595fa2SJoe Perches					$newcomp = ">=";
5628c5595fa2SJoe Perches				} elsif ($comp eq ">") {
5629c5595fa2SJoe Perches					$newcomp = "<";
5630c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
5631c5595fa2SJoe Perches					$newcomp = "<=";
5632c5595fa2SJoe Perches				}
5633c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
5634c5595fa2SJoe Perches			}
5635c5595fa2SJoe Perches		}
5636c5595fa2SJoe Perches
5637f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
5638f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
563953a3c448SAndy Whitcroft			my $name = $1;
564046b85bf9SGuenter Roeck			if ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {
5641000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
5642f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
564353a3c448SAndy Whitcroft			}
564453a3c448SAndy Whitcroft		}
5645c45dcabdSAndy Whitcroft
56460a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
56474a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
56483705ce5bSJoe Perches			if (ERROR("SPACING",
56493705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
56503705ce5bSJoe Perches			    $fix) {
5651194f66fcSJoe Perches				$fixed[$fixlinenr] =~
56523705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
56533705ce5bSJoe Perches			}
56540a920b5bSAndy Whitcroft		}
56550a920b5bSAndy Whitcroft
5656f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
5657f5fe35ddSAndy Whitcroft# statements after the conditional.
5658170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
56593e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
56603e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
56613e469cdcSAndy Whitcroft					if (!defined $stat);
5662170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
5663170d3a22SAndy Whitcroft						$remain_next, $off_next);
5664170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
5665170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
5666170d3a22SAndy Whitcroft
5667170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
5668170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
5669170d3a22SAndy Whitcroft				# then count those as offsets.
5670170d3a22SAndy Whitcroft				my ($whitespace) =
5671170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5672170d3a22SAndy Whitcroft				my $offset =
5673170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5674170d3a22SAndy Whitcroft
5675170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5676170d3a22SAndy Whitcroft								$offset} = 1;
5677170d3a22SAndy Whitcroft			}
5678170d3a22SAndy Whitcroft		}
5679170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5680c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5681170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5682171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
5683481efd7bSJoe Perches			my $fixed_assign_in_if = 0;
56848905a67cSAndy Whitcroft
5685b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
568665b64b3bSJoe Perches				if (ERROR("ASSIGN_IN_IF",
568765b64b3bSJoe Perches					  "do not use assignment in if condition\n" . $herecurr) &&
568865b64b3bSJoe Perches				    $fix && $perl_version_ok) {
568965b64b3bSJoe Perches					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {
569065b64b3bSJoe Perches						my $space = $1;
569165b64b3bSJoe Perches						my $not = $2;
569265b64b3bSJoe Perches						my $statement = $3;
569365b64b3bSJoe Perches						my $assigned = $4;
569465b64b3bSJoe Perches						my $test = $8;
569565b64b3bSJoe Perches						my $against = $9;
569665b64b3bSJoe Perches						my $brace = $15;
569765b64b3bSJoe Perches						fix_delete_line($fixlinenr, $rawline);
569865b64b3bSJoe Perches						fix_insert_line($fixlinenr, "$space$statement;");
569965b64b3bSJoe Perches						my $newline = "${space}if (";
570065b64b3bSJoe Perches						$newline .= '!' if defined($not);
570165b64b3bSJoe Perches						$newline .= '(' if (defined $not && defined($test) && defined($against));
570265b64b3bSJoe Perches						$newline .= "$assigned";
570365b64b3bSJoe Perches						$newline .= " $test $against" if (defined($test) && defined($against));
570465b64b3bSJoe Perches						$newline .= ')' if (defined $not && defined($test) && defined($against));
570565b64b3bSJoe Perches						$newline .= ')';
570665b64b3bSJoe Perches						$newline .= " {" if (defined($brace));
570765b64b3bSJoe Perches						fix_insert_line($fixlinenr + 1, $newline);
5708481efd7bSJoe Perches						$fixed_assign_in_if = 1;
570965b64b3bSJoe Perches					}
571065b64b3bSJoe Perches				}
57118905a67cSAndy Whitcroft			}
57128905a67cSAndy Whitcroft
57138905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
57148905a67cSAndy Whitcroft			# conditional.
5715773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
57168905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
571713214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
571853210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
571953210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5720773647a0SAndy Whitcroft			{
5721bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5722bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5723bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
572442bdf74cSHidetoshi Seto				my $stat_real = '';
5725bb44ad39SAndy Whitcroft
572642bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
572742bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5728bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5729bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5730bb44ad39SAndy Whitcroft				}
5731bb44ad39SAndy Whitcroft
5732481efd7bSJoe Perches				if (ERROR("TRAILING_STATEMENTS",
5733481efd7bSJoe Perches					  "trailing statements should be on next line\n" . $herecurr . $stat_real) &&
5734481efd7bSJoe Perches				    !$fixed_assign_in_if &&
5735481efd7bSJoe Perches				    $cond_lines == 0 &&
5736481efd7bSJoe Perches				    $fix && $perl_version_ok &&
5737481efd7bSJoe Perches				    $fixed[$fixlinenr] =~ /^\+(\s*)((?:if|while|for)\s*$balanced_parens)\s*(.*)$/) {
5738481efd7bSJoe Perches					my $indent = $1;
5739481efd7bSJoe Perches					my $test = $2;
5740481efd7bSJoe Perches					my $rest = rtrim($4);
5741481efd7bSJoe Perches					if ($rest =~ /;$/) {
5742481efd7bSJoe Perches						$fixed[$fixlinenr] = "\+$indent$test";
5743481efd7bSJoe Perches						fix_insert_line($fixlinenr + 1, "$indent\t$rest");
5744481efd7bSJoe Perches					}
5745481efd7bSJoe Perches				}
57468905a67cSAndy Whitcroft			}
57478905a67cSAndy Whitcroft		}
57488905a67cSAndy Whitcroft
574913214adfSAndy Whitcroft# Check for bitwise tests written as boolean
575013214adfSAndy Whitcroft		if ($line =~ /
575113214adfSAndy Whitcroft			(?:
575213214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
575313214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
575413214adfSAndy Whitcroft				(?:\&\&|\|\|)
575513214adfSAndy Whitcroft			|
575613214adfSAndy Whitcroft				(?:\&\&|\|\|)
575713214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
575813214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
575913214adfSAndy Whitcroft			)/x)
576013214adfSAndy Whitcroft		{
5761000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5762000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
576313214adfSAndy Whitcroft		}
576413214adfSAndy Whitcroft
57658905a67cSAndy Whitcroft# if and else should not have general statements after it
576613214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
576713214adfSAndy Whitcroft			my $s = $1;
576813214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
576913214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5770000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5771000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
57720a920b5bSAndy Whitcroft			}
577313214adfSAndy Whitcroft		}
577439667782SAndy Whitcroft# if should not continue a brace
577539667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5776000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5777048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
577839667782SAndy Whitcroft				$herecurr);
577939667782SAndy Whitcroft		}
5780a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5781a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5782a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
57833fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5784a1080bf8SAndy Whitcroft			\s*return\s+
5785a1080bf8SAndy Whitcroft		    )/xg)
5786a1080bf8SAndy Whitcroft		{
5787000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5788000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5789a1080bf8SAndy Whitcroft		}
57900a920b5bSAndy Whitcroft
57910a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
57920a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
57938b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
57940a920b5bSAndy Whitcroft		    $previndent == $indent) {
57958b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
57968b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
57978b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
57988b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
57998b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
58008b8856f4SJoe Perches				my $fixedline = $prevrawline;
58018b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
58028b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
58038b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
58048b8856f4SJoe Perches				}
58058b8856f4SJoe Perches				$fixedline = $rawline;
58068b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
58078b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
58088b8856f4SJoe Perches			}
58090a920b5bSAndy Whitcroft		}
58100a920b5bSAndy Whitcroft
58118b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5812c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5813c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5814c2fdda0dSAndy Whitcroft
5815c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5816c2fdda0dSAndy Whitcroft			# conditional.
5817773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5818c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5819c2fdda0dSAndy Whitcroft
5820c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
58218b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
58228b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
58238b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
58248b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
58258b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
58268b8856f4SJoe Perches					my $fixedline = $prevrawline;
58278b8856f4SJoe Perches					my $trailing = $rawline;
58288b8856f4SJoe Perches					$trailing =~ s/^\+//;
58298b8856f4SJoe Perches					$trailing = trim($trailing);
58308b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
58318b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
58328b8856f4SJoe Perches				}
5833c2fdda0dSAndy Whitcroft			}
5834c2fdda0dSAndy Whitcroft		}
5835c2fdda0dSAndy Whitcroft
583695e2c602SJoe Perches#Specific variable tests
5837323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5838323c1260SJoe Perches			my $var = $1;
583995e2c602SJoe Perches
584095e2c602SJoe Perches#CamelCase
5841807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5842be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
58434104a206SŁukasz Stelmach#Ignore some autogenerated defines and enum values
58444104a206SŁukasz Stelmach			    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&
584522735ce8SJoe Perches#Ignore Page<foo> variants
5846807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5847d99a4158SGerhard Engleder#Ignore ETHTOOL_LINK_MODE_<foo> variants
5848d99a4158SGerhard Engleder			    $var !~ /^ETHTOOL_LINK_MODE_/ &&
5849d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5850d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5851d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5852f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5853f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
5854f858e23aSAntonio Borneo				while ($var =~ m{\b($Ident)}g) {
58557e781f67SJoe Perches					my $word = $1;
58567e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5857d8b07710SJoe Perches					if ($check) {
5858d8b07710SJoe Perches						seed_camelcase_includes();
5859d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5860d8b07710SJoe Perches							seed_camelcase_file($realfile);
5861d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5862d8b07710SJoe Perches						}
5863d8b07710SJoe Perches					}
58647e781f67SJoe Perches					if (!defined $camelcase{$word}) {
58657e781f67SJoe Perches						$camelcase{$word} = 1;
5866be79794bSJoe Perches						CHK("CAMELCASE",
58677e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
58687e781f67SJoe Perches					}
5869323c1260SJoe Perches				}
5870323c1260SJoe Perches			}
58713445686aSJoe Perches		}
58720a920b5bSAndy Whitcroft
58730a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5874d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5875d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5876d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5877d5e616fcSJoe Perches			    $fix) {
5878194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5879d5e616fcSJoe Perches			}
58800a920b5bSAndy Whitcroft		}
58810a920b5bSAndy Whitcroft
58820e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
58830e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5884c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5885e09dec48SAndy Whitcroft			my $file = "$1.h";
5886e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5887e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5888e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
58897840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5890c45dcabdSAndy Whitcroft			{
58910e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
58920e212e0aSFabian Frederick				if ($asminclude > 0) {
5893e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5894000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5895000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5896e09dec48SAndy Whitcroft					} else {
5897000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5898000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5899e09dec48SAndy Whitcroft					}
59000a920b5bSAndy Whitcroft				}
59010a920b5bSAndy Whitcroft			}
59020e212e0aSFabian Frederick		}
59030a920b5bSAndy Whitcroft
5904653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5905653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5906cf655043SAndy Whitcroft# in a known good container
5907b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5908b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5909d8aaf121SAndy Whitcroft			my $ln = $linenr;
5910d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5911c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5912c45dcabdSAndy Whitcroft			my $ctx = '';
591308a2843eSJoe Perches			my $has_flow_statement = 0;
591408a2843eSJoe Perches			my $has_arg_concat = 0;
5915c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5916f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5917f74bd194SAndy Whitcroft			$ctx = $dstat;
5918c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5919a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5920c45dcabdSAndy Whitcroft
592108a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
592262e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
592308a2843eSJoe Perches
5924f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5925f59b64bfSJoe Perches			my $define_args = $1;
5926f59b64bfSJoe Perches			my $define_stmt = $dstat;
5927f59b64bfSJoe Perches			my @def_args = ();
5928f59b64bfSJoe Perches
5929f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5930f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5931f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
59328c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5933f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5934f59b64bfSJoe Perches			}
5935f59b64bfSJoe Perches
5936292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5937c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5938c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5939c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5940c45dcabdSAndy Whitcroft
5941c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
59422e44e803SDwaipayan Ray			while ($dstat =~ s/\([^\(\)]*\)/1u/ ||
59432e44e803SDwaipayan Ray			       $dstat =~ s/\{[^\{\}]*\}/1u/ ||
59442e44e803SDwaipayan Ray			       $dstat =~ s/.\[[^\[\]]*\]/1u/)
5945bf30d6edSAndy Whitcroft			{
5946c45dcabdSAndy Whitcroft			}
5947c45dcabdSAndy Whitcroft
5948342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
594933acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
595033acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5951e45bab8eSAndy Whitcroft			{
5952e45bab8eSAndy Whitcroft			}
5953e45bab8eSAndy Whitcroft
595442e15293SJoe Perches			# Make asm volatile uses seem like a generic function
595542e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
595642e15293SJoe Perches
5957c45dcabdSAndy Whitcroft			my $exceptions = qr{
5958c45dcabdSAndy Whitcroft				$Declare|
5959c45dcabdSAndy Whitcroft				module_param_named|
5960a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5961c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5962c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5963383099fdSAndy Whitcroft				__typeof__\(|
596422fd2d3eSStefani Seibold				union|
596522fd2d3eSStefani Seibold				struct|
5966ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
59676b10df42SVladimir Zapolskiy				^\"|\"$|
59686b10df42SVladimir Zapolskiy				^\[
5969c45dcabdSAndy Whitcroft			}x;
59705eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5971f59b64bfSJoe Perches
5972f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5973f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5974e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5975f59b64bfSJoe Perches
5976f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5977f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5978f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
59793cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5980356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5981f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5982f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5983e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
5984dc3f4deeSStanislaw Gruszka			    $dstat !~ /^case\b/ &&					# case ...
598572f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
59862e44e803SDwaipayan Ray			    $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ &&		# while (...) {...}
5987f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5988f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5989f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
59904e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5991f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5992c45dcabdSAndy Whitcroft			{
5993e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5994e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5995e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5996e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5997f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5998f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5999f74bd194SAndy Whitcroft				} else {
6000000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
6001388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
6002d8aaf121SAndy Whitcroft				}
6003f59b64bfSJoe Perches
6004f59b64bfSJoe Perches			}
60055207649bSJoe Perches
60065207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
60075207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
60085207649bSJoe Perches			my $first = 1;
60095207649bSJoe Perches			$define_stmt = "";
60105207649bSJoe Perches			foreach my $l (@stmt_array) {
60115207649bSJoe Perches				$l =~ s/\\$//;
60125207649bSJoe Perches				if ($first) {
60135207649bSJoe Perches					$define_stmt = $l;
60145207649bSJoe Perches					$first = 0;
60155207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
60165207649bSJoe Perches					$define_stmt .= substr($l, 1);
60175207649bSJoe Perches				}
60185207649bSJoe Perches			}
60195207649bSJoe Perches			$define_stmt =~ s/$;//g;
60205207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
60215207649bSJoe Perches			$define_stmt = trim($define_stmt);
60225207649bSJoe Perches
6023f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
6024f59b64bfSJoe Perches			foreach my $arg (@def_args) {
6025f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
60269192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
60277fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
60287b844345SVincent 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;
60297fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
60307fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
6031d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
6032f59b64bfSJoe Perches				if ($use_cnt > 1) {
6033f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
6034f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
6035f59b64bfSJoe Perches				    }
60369192d41aSJoe Perches# check if any macro arguments may have other precedence issues
60377fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
60389192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
60399192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
60409192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
60419192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
60429192d41aSJoe Perches				}
60430a920b5bSAndy Whitcroft			}
60445023d347SJoe Perches
604508a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
604608a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
604708a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
604808a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
6049e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
605008a2843eSJoe Perches
605108a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
605208a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
605308a2843eSJoe Perches			}
605408a2843eSJoe Perches
6055481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
60565023d347SJoe Perches
60575b2c7334SJim Cromie		} elsif ($realfile =~ m@/vmlinux.lds.h$@) {
60585b2c7334SJim Cromie		    $line =~ s/(\w+)/$maybe_linker_symbol{$1}++/ge;
60595b2c7334SJim Cromie		    #print "REAL: $realfile\nln: $line\nkeys:", sort keys %maybe_linker_symbol;
60605023d347SJoe Perches		} else {
60615023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
6062481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
6063481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
60645023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
60655023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
60665023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
60675023d347SJoe Perches			}
6068653d4876SAndy Whitcroft		}
60690a920b5bSAndy Whitcroft
6070b13edf7fSJoe Perches# do {} while (0) macro tests:
6071b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
6072b13edf7fSJoe Perches# macro should not end with a semicolon
60735b57980dSJoe Perches		if ($perl_version_ok &&
6074b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
6075b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
6076b13edf7fSJoe Perches			my $ln = $linenr;
6077b13edf7fSJoe Perches			my $cnt = $realcnt;
6078b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
6079b13edf7fSJoe Perches			my $ctx = '';
6080b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
6081b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
6082b13edf7fSJoe Perches			$ctx = $dstat;
6083b13edf7fSJoe Perches
6084b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
60851b36b201SJoe Perches			$dstat =~ s/$;/ /g;
6086b13edf7fSJoe Perches
6087b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
6088b13edf7fSJoe Perches				my $stmts = $2;
6089b13edf7fSJoe Perches				my $semis = $3;
6090b13edf7fSJoe Perches
6091b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
6092b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
6093e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6094b13edf7fSJoe Perches
6095ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
6096ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
6097b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
6098b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
6099b13edf7fSJoe Perches				}
6100b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
6101b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
6102b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
6103b13edf7fSJoe Perches				}
6104f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
6105f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
6106f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
6107e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6108f5ef95b1SJoe Perches
6109f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
6110f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
6111b13edf7fSJoe Perches			}
6112b13edf7fSJoe Perches		}
6113b13edf7fSJoe Perches
6114f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
611513214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
611613214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
6117cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
611813214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
6119cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
6120cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
6121aad4f614SJoe Perches				my @allowed = ();
6122aad4f614SJoe Perches				my $allow = 0;
612313214adfSAndy Whitcroft				my $seen = 0;
6124773647a0SAndy Whitcroft				my $herectx = $here . "\n";
6125cf655043SAndy Whitcroft				my $ln = $linenr - 1;
612613214adfSAndy Whitcroft				for my $chunk (@chunks) {
612713214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
612813214adfSAndy Whitcroft
6129773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
6130773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
6131773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
6132773647a0SAndy Whitcroft
6133aad4f614SJoe Perches					$allowed[$allow] = 0;
6134773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
6135773647a0SAndy Whitcroft
6136773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
6137773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
6138773647a0SAndy Whitcroft
6139773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
6140cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
6141cf655043SAndy Whitcroft
6142773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
614313214adfSAndy Whitcroft
614413214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
614513214adfSAndy Whitcroft
6146aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
6147cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
6148cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
6149aad4f614SJoe Perches						$allowed[$allow] = 1;
615013214adfSAndy Whitcroft					}
615113214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
6152cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
6153aad4f614SJoe Perches						$allowed[$allow] = 1;
615413214adfSAndy Whitcroft					}
6155cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
6156cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
6157aad4f614SJoe Perches						$allowed[$allow] = 1;
615813214adfSAndy Whitcroft					}
6159aad4f614SJoe Perches					$allow++;
616013214adfSAndy Whitcroft				}
6161aad4f614SJoe Perches				if ($seen) {
6162aad4f614SJoe Perches					my $sum_allowed = 0;
6163aad4f614SJoe Perches					foreach (@allowed) {
6164aad4f614SJoe Perches						$sum_allowed += $_;
6165aad4f614SJoe Perches					}
6166aad4f614SJoe Perches					if ($sum_allowed == 0) {
6167000d1cc1SJoe Perches						WARN("BRACES",
6168000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
6169aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
6170aad4f614SJoe Perches						 $seen != $allow) {
6171aad4f614SJoe Perches						CHK("BRACES",
6172aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
6173aad4f614SJoe Perches					}
617413214adfSAndy Whitcroft				}
617513214adfSAndy Whitcroft			}
617613214adfSAndy Whitcroft		}
6177773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
617813214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
6179cf655043SAndy Whitcroft			my $allowed = 0;
6180f0a594c1SAndy Whitcroft
6181cf655043SAndy Whitcroft			# Check the pre-context.
6182cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
6183cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
6184cf655043SAndy Whitcroft				$allowed = 1;
6185f0a594c1SAndy Whitcroft			}
6186773647a0SAndy Whitcroft
6187773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
6188773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
6189773647a0SAndy Whitcroft
6190cf655043SAndy Whitcroft			# Check the condition.
6191cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
6192773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
6193cf655043SAndy Whitcroft			if (defined $cond) {
6194773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
6195cf655043SAndy Whitcroft			}
6196cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
6197cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
6198cf655043SAndy Whitcroft				$allowed = 1;
6199cf655043SAndy Whitcroft			}
6200cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
6201cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
6202cf655043SAndy Whitcroft				$allowed = 1;
6203cf655043SAndy Whitcroft			}
6204cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
6205cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
6206cf655043SAndy Whitcroft				$allowed = 1;
6207cf655043SAndy Whitcroft			}
6208cf655043SAndy Whitcroft			# Check the post-context.
6209cf655043SAndy Whitcroft			if (defined $chunks[1]) {
6210cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
6211cf655043SAndy Whitcroft				if (defined $cond) {
6212773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
6213cf655043SAndy Whitcroft				}
6214cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
6215cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
6216cf655043SAndy Whitcroft					$allowed = 1;
6217cf655043SAndy Whitcroft				}
6218cf655043SAndy Whitcroft			}
6219cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
6220f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
6221e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6222cf655043SAndy Whitcroft
6223000d1cc1SJoe Perches				WARN("BRACES",
6224000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
6225f0a594c1SAndy Whitcroft			}
6226f0a594c1SAndy Whitcroft		}
6227f0a594c1SAndy Whitcroft
6228e4c5babdSJoe Perches# check for single line unbalanced braces
622995330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
623095330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
6231e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
6232e4c5babdSJoe Perches		}
6233e4c5babdSJoe Perches
62340979ae66SJoe Perches# check for unnecessary blank lines around braces
623577b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
6236f8e58219SJoe Perches			if (CHK("BRACES",
6237f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
6238f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
6239f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
6240f8e58219SJoe Perches			}
62410979ae66SJoe Perches		}
624277b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
6243f8e58219SJoe Perches			if (CHK("BRACES",
6244f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
6245f8e58219SJoe Perches			    $fix) {
6246f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
6247f8e58219SJoe Perches			}
62480979ae66SJoe Perches		}
62490979ae66SJoe Perches
62504a0df2efSAndy Whitcroft# no volatiles please
62516c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
62526c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
6253000d1cc1SJoe Perches			WARN("VOLATILE",
62548c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
62554a0df2efSAndy Whitcroft		}
62564a0df2efSAndy Whitcroft
62575e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
62585e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
62595e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
62605e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
626133acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
62625e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
62635e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
62645e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
62655e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
62665e4f6ba5SJoe Perches				     $fix &&
62675e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
62685e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
62695e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
62705e4f6ba5SJoe Perches				my $comma_close = "";
62715e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
62725e4f6ba5SJoe Perches					$comma_close = $1;
62735e4f6ba5SJoe Perches				}
62745e4f6ba5SJoe Perches
62755e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
62765e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
62775e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
62785e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
62795e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
62805e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
62815e4f6ba5SJoe Perches				$fixedline = $rawline;
62825e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
62835e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
62845e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
62855e4f6ba5SJoe Perches				}
62865e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
62875e4f6ba5SJoe Perches			}
62885e4f6ba5SJoe Perches		}
62895e4f6ba5SJoe Perches
62905e4f6ba5SJoe Perches# check for missing a space in a string concatenation
62915e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
62925e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
62935e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
62945e4f6ba5SJoe Perches		}
62955e4f6ba5SJoe Perches
629677cb8546SJoe Perches# check for an embedded function name in a string when the function is known
6297e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
6298e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
6299e4b7d309SJoe Perches# function declarations
630077cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
630177cb8546SJoe Perches		    defined($context_function) &&
6302e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
6303e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
630477cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
6305e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
630677cb8546SJoe Perches		}
630777cb8546SJoe Perches
6308adb2da82SJoe Perches# check for unnecessary function tracing like uses
6309adb2da82SJoe Perches# This does not use $logFunctions because there are many instances like
6310adb2da82SJoe Perches# 'dprintk(FOO, "%s()\n", __func__);' which do not match $logFunctions
6311adb2da82SJoe Perches		if ($rawline =~ /^\+.*\([^"]*"$tracing_logging_tags{0,3}%s(?:\s*\(\s*\)\s*)?$tracing_logging_tags{0,3}(?:\\n)?"\s*,\s*__func__\s*\)\s*;/) {
6312adb2da82SJoe Perches			if (WARN("TRACING_LOGGING",
6313adb2da82SJoe Perches				 "Unnecessary ftrace-like logging - prefer using ftrace\n" . $herecurr) &&
6314adb2da82SJoe Perches			    $fix) {
6315adb2da82SJoe Perches                                fix_delete_line($fixlinenr, $rawline);
6316adb2da82SJoe Perches			}
6317adb2da82SJoe Perches		}
6318adb2da82SJoe Perches
63195e4f6ba5SJoe Perches# check for spaces before a quoted newline
63205e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
63215e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
63225e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
63235e4f6ba5SJoe Perches			    $fix) {
63245e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
63255e4f6ba5SJoe Perches			}
63265e4f6ba5SJoe Perches
63275e4f6ba5SJoe Perches		}
63285e4f6ba5SJoe Perches
6329f17dba4fSJoe Perches# concatenated string without spaces between elements
6330d2af5aa6SJoe Perches		if ($line =~ /$String[A-Z_]/ ||
6331d2af5aa6SJoe Perches		    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {
633279682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
633379682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
633479682c0cSJoe Perches			    $fix) {
633579682c0cSJoe Perches				while ($line =~ /($String)/g) {
633679682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
633779682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
633879682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
633979682c0cSJoe Perches				}
634079682c0cSJoe Perches			}
6341f17dba4fSJoe Perches		}
6342f17dba4fSJoe Perches
634390ad30e5SJoe Perches# uncoalesced string fragments
6344d2af5aa6SJoe Perches		if ($line =~ /$String\s*[Lu]?"/) {
634579682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
634679682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
634779682c0cSJoe Perches			    $fix) {
634879682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
634979682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
635079682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
635179682c0cSJoe Perches				}
635279682c0cSJoe Perches			}
635390ad30e5SJoe Perches		}
635490ad30e5SJoe Perches
6355522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
6356522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
6357522b837cSAlexey Dobriyan		my $show_Z = 1;
63585e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
6359522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
63605e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
6361522b837cSAlexey Dobriyan			# check for %L
6362522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
63635e4f6ba5SJoe Perches				WARN("PRINTF_L",
6364522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
6365522b837cSAlexey Dobriyan				$show_L = 0;
63665e4f6ba5SJoe Perches			}
6367522b837cSAlexey Dobriyan			# check for %Z
6368522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
6369522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
6370522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
6371522b837cSAlexey Dobriyan				$show_Z = 0;
6372522b837cSAlexey Dobriyan			}
6373522b837cSAlexey Dobriyan			# check for 0x<decimal>
6374522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
6375522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
63766e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
63776e300757SJoe Perches			}
63785e4f6ba5SJoe Perches		}
63795e4f6ba5SJoe Perches
63805e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
63813f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
63825e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
63835e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
63845e4f6ba5SJoe Perches		}
63855e4f6ba5SJoe Perches
638600df344fSAndy Whitcroft# warn about #if 0
6387c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
638860f89010SPrakruthi Deepak Heragu			WARN("IF_0",
638960f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
639060f89010SPrakruthi Deepak Heragu		}
639160f89010SPrakruthi Deepak Heragu
639260f89010SPrakruthi Deepak Heragu# warn about #if 1
639360f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
639460f89010SPrakruthi Deepak Heragu			WARN("IF_1",
639560f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
63964a0df2efSAndy Whitcroft		}
63974a0df2efSAndy Whitcroft
639803df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
639903df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
6400100425deSJoe Perches			my $tested = quotemeta($1);
6401100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
6402100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
6403100425deSJoe Perches				my $func = $1;
6404100425deSJoe Perches				if (WARN('NEEDLESS_IF',
6405100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
6406100425deSJoe Perches				    $fix) {
6407100425deSJoe Perches					my $do_fix = 1;
6408100425deSJoe Perches					my $leading_tabs = "";
6409100425deSJoe Perches					my $new_leading_tabs = "";
6410100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
6411100425deSJoe Perches						$leading_tabs = $1;
6412100425deSJoe Perches					} else {
6413100425deSJoe Perches						$do_fix = 0;
6414100425deSJoe Perches					}
6415100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
6416100425deSJoe Perches						$new_leading_tabs = $1;
6417100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
6418100425deSJoe Perches							$do_fix = 0;
6419100425deSJoe Perches						}
6420100425deSJoe Perches					} else {
6421100425deSJoe Perches						$do_fix = 0;
6422100425deSJoe Perches					}
6423100425deSJoe Perches					if ($do_fix) {
6424100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
6425100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
6426100425deSJoe Perches					}
6427100425deSJoe Perches				}
64284c432a8fSGreg Kroah-Hartman			}
64294c432a8fSGreg Kroah-Hartman		}
6430f0a594c1SAndy Whitcroft
6431ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
6432ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
6433ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
6434ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
6435ebfdc409SJoe Perches		    $linenr > 3) {
6436ebfdc409SJoe Perches			my $testval = $2;
6437ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
6438ebfdc409SJoe Perches
6439ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
6440ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
6441ebfdc409SJoe Perches
6442e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
6443e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
6444ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
6445ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
6446ebfdc409SJoe Perches			}
6447ebfdc409SJoe Perches		}
6448ebfdc409SJoe Perches
6449f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
6450dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
6451f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
6452f78d98f6SJoe Perches			my $level = $1;
6453f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
6454f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
6455f78d98f6SJoe Perches			    $fix) {
6456f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
6457f78d98f6SJoe Perches			}
6458f78d98f6SJoe Perches		}
6459f78d98f6SJoe Perches
646045c55e92SJoe Perches# check for logging continuations
646145c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
646245c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
646345c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
646445c55e92SJoe Perches		}
646545c55e92SJoe Perches
646670eb2275SDwaipayan Ray# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions
646770eb2275SDwaipayan Ray		if (defined $stat &&
646870eb2275SDwaipayan Ray		    $line =~ /\b$logFunctions\s*\(/ &&
646970eb2275SDwaipayan Ray		    index($stat, '"') >= 0) {
647070eb2275SDwaipayan Ray			my $lc = $stat =~ tr@\n@@;
647170eb2275SDwaipayan Ray			$lc = $lc + $linenr;
647270eb2275SDwaipayan Ray			my $stat_real = get_stat_real($linenr, $lc);
647370eb2275SDwaipayan Ray			pos($stat_real) = index($stat_real, '"');
647470eb2275SDwaipayan Ray			while ($stat_real =~ /[^\"%]*(%[\#\d\.\*\-]*(h+)[idux])/g) {
647570eb2275SDwaipayan Ray				my $pspec = $1;
647670eb2275SDwaipayan Ray				my $h = $2;
647770eb2275SDwaipayan Ray				my $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\n@@;
647870eb2275SDwaipayan Ray				if (WARN("UNNECESSARY_MODIFIER",
647970eb2275SDwaipayan Ray					 "Integer promotion: Using '$h' in '$pspec' is unnecessary\n" . "$here\n$stat_real\n") &&
648070eb2275SDwaipayan Ray				    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\+/) {
648170eb2275SDwaipayan Ray					my $nspec = $pspec;
648270eb2275SDwaipayan Ray					$nspec =~ s/h//g;
648370eb2275SDwaipayan Ray					$fixed[$fixlinenr + $lineoff] =~ s/\Q$pspec\E/$nspec/;
648470eb2275SDwaipayan Ray				}
648570eb2275SDwaipayan Ray			}
648670eb2275SDwaipayan Ray		}
648770eb2275SDwaipayan Ray
6488abb08a53SJoe Perches# check for mask then right shift without a parentheses
64895b57980dSJoe Perches		if ($perl_version_ok &&
6490abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
6491abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
6492abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
6493abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
6494abb08a53SJoe Perches		}
6495abb08a53SJoe Perches
6496b75ac618SJoe Perches# check for pointer comparisons to NULL
64975b57980dSJoe Perches		if ($perl_version_ok) {
6498b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
6499b75ac618SJoe Perches				my $val = $1;
6500b75ac618SJoe Perches				my $equal = "!";
6501b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
6502b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
6503b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
6504b75ac618SJoe Perches					    $fix) {
6505b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
6506b75ac618SJoe Perches				}
6507b75ac618SJoe Perches			}
6508b75ac618SJoe Perches		}
6509b75ac618SJoe Perches
65108716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
65118716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
65128716de38SJoe Perches			my $attr = $1;
65138716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
65148716de38SJoe Perches				my $ptr = $1;
65158716de38SJoe Perches				my $var = $2;
65168716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
65178716de38SJoe Perches				      ERROR("MISPLACED_INIT",
65188716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
65198716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
65208716de38SJoe Perches				      WARN("MISPLACED_INIT",
65218716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
65228716de38SJoe Perches				    $fix) {
6523194f66fcSJoe 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;
65248716de38SJoe Perches				}
65258716de38SJoe Perches			}
65268716de38SJoe Perches		}
65278716de38SJoe Perches
6528e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
6529e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
6530e970b884SJoe Perches			my $attr = $1;
6531e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
6532e970b884SJoe Perches			my $attr_prefix = $1;
6533e970b884SJoe Perches			my $attr_type = $2;
6534e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6535e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
6536e970b884SJoe Perches			    $fix) {
6537194f66fcSJoe Perches				$fixed[$fixlinenr] =~
6538e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
6539e970b884SJoe Perches			}
6540e970b884SJoe Perches		}
6541e970b884SJoe Perches
6542e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
6543e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
6544e970b884SJoe Perches			my $attr = $1;
6545e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
6546e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
6547e970b884SJoe Perches			    $fix) {
6548194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
6549e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
6550e970b884SJoe Perches				$lead = rtrim($1);
6551e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
6552e970b884SJoe Perches				$lead = "${lead}const ";
6553194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
6554e970b884SJoe Perches			}
6555e970b884SJoe Perches		}
6556e970b884SJoe Perches
6557c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
6558c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
6559c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
6560c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
6561c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
6562c17893c7SJoe Perches			    $fix) {
6563c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
6564c17893c7SJoe Perches			}
6565c17893c7SJoe Perches		}
6566c17893c7SJoe Perches
6567fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
6568fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
6569fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
6570fbdb8138SJoe Perches			my $constant_func = $1;
6571fbdb8138SJoe Perches			my $func = $constant_func;
6572fbdb8138SJoe Perches			$func =~ s/^__constant_//;
6573fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
6574fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
6575fbdb8138SJoe Perches			    $fix) {
6576194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
6577fbdb8138SJoe Perches			}
6578fbdb8138SJoe Perches		}
6579fbdb8138SJoe Perches
65801a15a250SPatrick Pannuto# prefer usleep_range over udelay
658137581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
658243c1d77cSJoe Perches			my $delay = $1;
65831a15a250SPatrick Pannuto			# ignore udelay's < 10, however
658443c1d77cSJoe Perches			if (! ($delay < 10) ) {
6585000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
6586458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
658743c1d77cSJoe Perches			}
658843c1d77cSJoe Perches			if ($delay > 2000) {
658943c1d77cSJoe Perches				WARN("LONG_UDELAY",
659043c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
65911a15a250SPatrick Pannuto			}
65921a15a250SPatrick Pannuto		}
65931a15a250SPatrick Pannuto
659409ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
659509ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
659609ef8725SPatrick Pannuto			if ($1 < 20) {
6597000d1cc1SJoe Perches				WARN("MSLEEP",
6598458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
659909ef8725SPatrick Pannuto			}
660009ef8725SPatrick Pannuto		}
660109ef8725SPatrick Pannuto
660236ec1939SJoe Perches# check for comparisons of jiffies
660336ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
660436ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
660536ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
660636ec1939SJoe Perches		}
660736ec1939SJoe Perches
66089d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
66099d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
66109d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
66119d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
66129d7a34a5SJoe Perches		}
66139d7a34a5SJoe Perches
661400df344fSAndy Whitcroft# warn about #ifdefs in C files
6615c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
661600df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
661700df344fSAndy Whitcroft#			print "$herecurr";
661800df344fSAndy Whitcroft#			$clean = 0;
661900df344fSAndy Whitcroft#		}
662000df344fSAndy Whitcroft
662122f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
6622c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
66233705ce5bSJoe Perches			if (ERROR("SPACING",
66243705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
66253705ce5bSJoe Perches			    $fix) {
6626194f66fcSJoe Perches				$fixed[$fixlinenr] =~
66273705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
66283705ce5bSJoe Perches			}
66293705ce5bSJoe Perches
663022f2a2efSAndy Whitcroft		}
663122f2a2efSAndy Whitcroft
66324a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
6633171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
6634171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
66354a0df2efSAndy Whitcroft			my $which = $1;
66364a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6637000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
6638000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
66394a0df2efSAndy Whitcroft			}
66404a0df2efSAndy Whitcroft		}
66414a0df2efSAndy Whitcroft# check for memory barriers without a comment.
6642402c2553SMichael S. Tsirkin
6643402c2553SMichael S. Tsirkin		my $barriers = qr{
6644402c2553SMichael S. Tsirkin			mb|
6645402c2553SMichael S. Tsirkin			rmb|
6646ad83ec6cSWill Deacon			wmb
6647402c2553SMichael S. Tsirkin		}x;
6648402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
6649402c2553SMichael S. Tsirkin			mb__before_atomic|
6650402c2553SMichael S. Tsirkin			mb__after_atomic|
6651402c2553SMichael S. Tsirkin			store_release|
6652402c2553SMichael S. Tsirkin			load_acquire|
6653402c2553SMichael S. Tsirkin			store_mb|
6654402c2553SMichael S. Tsirkin			(?:$barriers)
6655402c2553SMichael S. Tsirkin		}x;
6656402c2553SMichael S. Tsirkin		my $all_barriers = qr{
6657402c2553SMichael S. Tsirkin			(?:$barriers)|
665843e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
665943e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
6660402c2553SMichael S. Tsirkin		}x;
6661402c2553SMichael S. Tsirkin
6662402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
66634a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
6664c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
6665000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
66664a0df2efSAndy Whitcroft			}
66674a0df2efSAndy Whitcroft		}
66683ad81779SPaul E. McKenney
6669f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
6670f4073b0fSMichael S. Tsirkin
6671f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
6672f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
6673f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
6674f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
6675f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
6676f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
6677f4073b0fSMichael S. Tsirkin		}
6678f4073b0fSMichael S. Tsirkin
6679cb426e99SJoe Perches# check for waitqueue_active without a comment.
6680cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
6681cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
6682cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
6683cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
6684cb426e99SJoe Perches			}
6685cb426e99SJoe Perches		}
66863ad81779SPaul E. McKenney
66875099a722SMarco Elver# check for data_race without a comment.
66885099a722SMarco Elver		if ($line =~ /\bdata_race\s*\(/) {
66895099a722SMarco Elver			if (!ctx_has_comment($first_line, $linenr)) {
66905099a722SMarco Elver				WARN("DATA_RACE",
66915099a722SMarco Elver				     "data_race without comment\n" . $herecurr);
66925099a722SMarco Elver			}
66935099a722SMarco Elver		}
66945099a722SMarco Elver
66954a0df2efSAndy Whitcroft# check of hardware specific defines
6696c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
6697000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
6698000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
66990a920b5bSAndy Whitcroft		}
6700653d4876SAndy Whitcroft
6701596ed45bSJoe Perches# check that the storage class is not after a type
6702596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
6703000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
6704596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
6705596ed45bSJoe Perches		}
6706596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
6707596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
6708596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
6709596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
6710596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
6711596ed45bSJoe Perches			WARN("STORAGE_CLASS",
6712596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
6713d4977c78STobias Klauser		}
6714d4977c78STobias Klauser
6715de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
6716de7d4f0eSAndy Whitcroft# storage class and type.
67179c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
67189c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
6719000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
6720000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
6721de7d4f0eSAndy Whitcroft		}
6722de7d4f0eSAndy Whitcroft
67238905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
67242b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
67252b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
6726d5e616fcSJoe Perches			if (WARN("INLINE",
6727d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
6728d5e616fcSJoe Perches			    $fix) {
6729194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
6730d5e616fcSJoe Perches
6731d5e616fcSJoe Perches			}
67328905a67cSAndy Whitcroft		}
67338905a67cSAndy Whitcroft
67347ebe1d17SDwaipayan Ray# Check for compiler attributes
67352b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
67367ebe1d17SDwaipayan Ray		    $rawline =~ /\b__attribute__\s*\(\s*($balanced_parens)\s*\)/) {
67377ebe1d17SDwaipayan Ray			my $attr = $1;
67387ebe1d17SDwaipayan Ray			$attr =~ s/\s*\(\s*(.*)\)\s*/$1/;
67397ebe1d17SDwaipayan Ray
67407ebe1d17SDwaipayan Ray			my %attr_list = (
67410830aab0SJoe Perches				"alias"				=> "__alias",
67427ebe1d17SDwaipayan Ray				"aligned"			=> "__aligned",
67437ebe1d17SDwaipayan Ray				"always_inline"			=> "__always_inline",
67447ebe1d17SDwaipayan Ray				"assume_aligned"		=> "__assume_aligned",
67457ebe1d17SDwaipayan Ray				"cold"				=> "__cold",
67467ebe1d17SDwaipayan Ray				"const"				=> "__attribute_const__",
67477ebe1d17SDwaipayan Ray				"copy"				=> "__copy",
67487ebe1d17SDwaipayan Ray				"designated_init"		=> "__designated_init",
67497ebe1d17SDwaipayan Ray				"externally_visible"		=> "__visible",
67507ebe1d17SDwaipayan Ray				"format"			=> "printf|scanf",
67517ebe1d17SDwaipayan Ray				"gnu_inline"			=> "__gnu_inline",
67527ebe1d17SDwaipayan Ray				"malloc"			=> "__malloc",
67537ebe1d17SDwaipayan Ray				"mode"				=> "__mode",
67547ebe1d17SDwaipayan Ray				"no_caller_saved_registers"	=> "__no_caller_saved_registers",
67557ebe1d17SDwaipayan Ray				"noclone"			=> "__noclone",
67567ebe1d17SDwaipayan Ray				"noinline"			=> "noinline",
67577ebe1d17SDwaipayan Ray				"nonstring"			=> "__nonstring",
67587ebe1d17SDwaipayan Ray				"noreturn"			=> "__noreturn",
67597ebe1d17SDwaipayan Ray				"packed"			=> "__packed",
67607ebe1d17SDwaipayan Ray				"pure"				=> "__pure",
6761339f29d9SJoe Perches				"section"			=> "__section",
67620830aab0SJoe Perches				"used"				=> "__used",
67630830aab0SJoe Perches				"weak"				=> "__weak"
67647ebe1d17SDwaipayan Ray			);
67657ebe1d17SDwaipayan Ray
67667ebe1d17SDwaipayan Ray			while ($attr =~ /\s*(\w+)\s*(${balanced_parens})?/g) {
6767339f29d9SJoe Perches				my $orig_attr = $1;
67687ebe1d17SDwaipayan Ray				my $params = '';
67697ebe1d17SDwaipayan Ray				$params = $2 if defined($2);
6770339f29d9SJoe Perches				my $curr_attr = $orig_attr;
67717ebe1d17SDwaipayan Ray				$curr_attr =~ s/^[\s_]+|[\s_]+$//g;
67727ebe1d17SDwaipayan Ray				if (exists($attr_list{$curr_attr})) {
6773339f29d9SJoe Perches					my $new = $attr_list{$curr_attr};
67747ebe1d17SDwaipayan Ray					if ($curr_attr eq "format" && $params) {
67757ebe1d17SDwaipayan Ray						$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
6776339f29d9SJoe Perches						$new = "__$1\($2";
67777ebe1d17SDwaipayan Ray					} else {
6778339f29d9SJoe Perches						$new = "$new$params";
67797ebe1d17SDwaipayan Ray					}
67807ebe1d17SDwaipayan Ray					if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
6781339f29d9SJoe Perches						 "Prefer $new over __attribute__(($orig_attr$params))\n" . $herecurr) &&
67827ebe1d17SDwaipayan Ray					    $fix) {
6783339f29d9SJoe Perches						my $remove = "\Q$orig_attr\E" . '\s*' . "\Q$params\E" . '(?:\s*,\s*)?';
6784339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/$remove//;
6785339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\b__attribute__/$new __attribute__/;
6786339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/\}\Q$new\E/} $new/;
6787339f29d9SJoe Perches						$fixed[$fixlinenr] =~ s/ __attribute__\s*\(\s*\(\s*\)\s*\)//;
67887ebe1d17SDwaipayan Ray					}
678939b7e287SJoe Perches				}
6790462811d9SJoe Perches			}
6791462811d9SJoe Perches
67927ebe1d17SDwaipayan Ray			# Check for __attribute__ unused, prefer __always_unused or __maybe_unused
67937ebe1d17SDwaipayan Ray			if ($attr =~ /^_*unused/) {
67947ebe1d17SDwaipayan Ray				WARN("PREFER_DEFINED_ATTRIBUTE_MACRO",
67957ebe1d17SDwaipayan Ray				     "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr);
6796d5e616fcSJoe Perches			}
67976061d949SJoe Perches		}
67986061d949SJoe Perches
6799619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
68005b57980dSJoe Perches		if ($perl_version_ok &&
6801619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6802619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6803619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6804619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6805619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6806619a908aSJoe Perches		}
6807619a908aSJoe Perches
6808fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6809e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6810fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6811e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6812e6176fa4SJoe Perches			my $type = $1;
6813e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6814e6176fa4SJoe Perches				$type = $1;
6815e6176fa4SJoe Perches				my $kernel_type = 'u';
6816e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6817e6176fa4SJoe Perches				$type =~ /(\d+)/;
6818e6176fa4SJoe Perches				$kernel_type .= $1;
6819e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6820e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6821e6176fa4SJoe Perches				    $fix) {
6822e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6823e6176fa4SJoe Perches				}
6824e6176fa4SJoe Perches			}
6825e6176fa4SJoe Perches		}
6826e6176fa4SJoe Perches
6827938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6828938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6829938224b5SJoe Perches			my $cast = $1;
6830938224b5SJoe Perches			my $const = $2;
6831938224b5SJoe Perches			my $suffix = "";
6832938224b5SJoe Perches			my $newconst = $const;
6833938224b5SJoe Perches			$newconst =~ s/${Int_type}$//;
6834938224b5SJoe Perches			$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6835938224b5SJoe Perches			if ($cast =~ /\blong\s+long\b/) {
6836938224b5SJoe Perches			    $suffix .= 'LL';
6837938224b5SJoe Perches			} elsif ($cast =~ /\blong\b/) {
6838938224b5SJoe Perches			    $suffix .= 'L';
6839938224b5SJoe Perches			}
68400972b8bfSJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
68410972b8bfSJoe Perches				 "Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\n" . $herecurr) &&
68420972b8bfSJoe Perches			    $fix) {
6843938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6844938224b5SJoe Perches			}
6845938224b5SJoe Perches		}
6846938224b5SJoe Perches
68478f53a9b8SJoe Perches# check for sizeof(&)
68488f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6849000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6850000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
68518f53a9b8SJoe Perches		}
68528f53a9b8SJoe Perches
685366c80b60SJoe Perches# check for sizeof without parenthesis
685466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6855d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6856d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6857d5e616fcSJoe Perches			    $fix) {
6858194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6859d5e616fcSJoe Perches			}
686066c80b60SJoe Perches		}
686166c80b60SJoe Perches
686288982feaSJoe Perches# check for struct spinlock declarations
686388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
686488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
686588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
686688982feaSJoe Perches		}
686788982feaSJoe Perches
6868a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
686906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6870a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6871caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6872caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6873d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6874d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6875d5e616fcSJoe Perches				    $fix) {
6876194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6877d5e616fcSJoe Perches				}
6878a6962d72SJoe Perches			}
6879a6962d72SJoe Perches		}
6880a6962d72SJoe Perches
68810b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
68825b57980dSJoe Perches		if ($perl_version_ok &&
68830b523769SJoe Perches		    defined $stat &&
68840b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
68850b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6886e3c6bc95STobin C. Harding			my $stat_real;
6887e3c6bc95STobin C. Harding
68880b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
68890b523769SJoe Perches			$lc = $lc + $linenr;
68900b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6891ffe07513SJoe Perches				my $specifier;
6892ffe07513SJoe Perches				my $extension;
68933bd32d6aSSakari Ailus				my $qualifier;
6894ffe07513SJoe Perches				my $bad_specifier = "";
68950b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
68960b523769SJoe Perches				$fmt =~ s/%%//g;
6897e3c6bc95STobin C. Harding
68983bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6899e3c6bc95STobin C. Harding					$specifier = $1;
6900e3c6bc95STobin C. Harding					$extension = $2;
69013bd32d6aSSakari Ailus					$qualifier = $3;
6902af612e43SSakari Ailus					if ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
69033bd32d6aSSakari Ailus					    ($extension eq "f" &&
6904af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^w/) ||
6905af612e43SSakari Ailus					    ($extension eq "4" &&
6906af612e43SSakari Ailus					     defined $qualifier && $qualifier !~ /^cc/)) {
6907e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
69080b523769SJoe Perches						last;
69090b523769SJoe Perches					}
6910e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6911e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6912e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
69130b523769SJoe Perches						}
6914e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6915e3c6bc95STobin 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");
6916e3c6bc95STobin C. Harding					}
6917e3c6bc95STobin C. Harding				}
6918e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
69192a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
6920de48fa1aSMiguel Ojeda					my $msg_level = \&WARN;
69211df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
69221df7338aSSergey Senozhatsky					my $use = "";
6923e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
69241df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6925e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
6926de48fa1aSMiguel Ojeda					} elsif ($bad_specifier =~ /pA/) {
6927de48fa1aSMiguel Ojeda						$use =  " - '%pA' is only intended to be used from Rust code";
6928de48fa1aSMiguel Ojeda						$msg_level = \&ERROR;
69291df7338aSSergey Senozhatsky					}
69302a9f9d85STobin C. Harding
6931de48fa1aSMiguel Ojeda					&{$msg_level}("VSPRINTF_POINTER_EXTENSION",
6932e3c6bc95STobin C. Harding						      "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6933e3c6bc95STobin C. Harding				}
69340b523769SJoe Perches			}
69350b523769SJoe Perches		}
69360b523769SJoe Perches
6937554e165cSAndy Whitcroft# Check for misused memsets
69385b57980dSJoe Perches		if ($perl_version_ok &&
6939d1fe9c09SJoe Perches		    defined $stat &&
69409e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6941554e165cSAndy Whitcroft
6942d7c76ba7SJoe Perches			my $ms_addr = $2;
6943d1fe9c09SJoe Perches			my $ms_val = $7;
6944d1fe9c09SJoe Perches			my $ms_size = $12;
6945d7c76ba7SJoe Perches
6946554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6947554e165cSAndy Whitcroft				ERROR("MEMSET",
6948d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6949554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6950554e165cSAndy Whitcroft				WARN("MEMSET",
6951d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6952d7c76ba7SJoe Perches			}
6953d7c76ba7SJoe Perches		}
6954d7c76ba7SJoe Perches
695598a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
69565b57980dSJoe Perches#		if ($perl_version_ok &&
6957f333195dSJoe Perches#		    defined $stat &&
6958f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6959f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6960f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6961f333195dSJoe Perches#			    $fix) {
6962f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6963f333195dSJoe Perches#			}
6964f333195dSJoe Perches#		}
696598a9bba5SJoe Perches
6966b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
69675b57980dSJoe Perches#		if ($perl_version_ok &&
6968f333195dSJoe Perches#		    defined $stat &&
6969f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6970f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6971f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6972f333195dSJoe Perches#		}
6973b6117d17SMateusz Kulikowski
69748617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
69758617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
69765b57980dSJoe Perches#		if ($perl_version_ok &&
6977f333195dSJoe Perches#		    defined $stat &&
6978f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6979f333195dSJoe Perches#
6980f333195dSJoe Perches#			my $ms_val = $7;
6981f333195dSJoe Perches#
6982f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6983f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6984f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6985f333195dSJoe Perches#				    $fix) {
6986f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6987f333195dSJoe Perches#				}
6988f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6989f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6990f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6991f333195dSJoe Perches#				    $fix) {
6992f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6993f333195dSJoe Perches#				}
6994f333195dSJoe Perches#			}
6995f333195dSJoe Perches#		}
69968617cd09SMateusz Kulikowski
6997d0f90841SKees Cook# strcpy uses that should likely be strscpy
6998d0f90841SKees Cook		if ($line =~ /\bstrcpy\s*\(/) {
6999d0f90841SKees Cook			WARN("STRCPY",
7000d0f90841SKees Cook			     "Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88\n" . $herecurr);
7001d0f90841SKees Cook		}
7002d0f90841SKees Cook
70035dbdb2d8SJoe Perches# strlcpy uses that should likely be strscpy
70045dbdb2d8SJoe Perches		if ($line =~ /\bstrlcpy\s*\(/) {
70055dbdb2d8SJoe Perches			WARN("STRLCPY",
7006d0f90841SKees Cook			     "Prefer strscpy over strlcpy - see: https://github.com/KSPP/linux/issues/89\n" . $herecurr);
7007d0f90841SKees Cook		}
7008d0f90841SKees Cook
7009d0f90841SKees Cook# strncpy uses that should likely be strscpy or strscpy_pad
7010d0f90841SKees Cook		if ($line =~ /\bstrncpy\s*\(/) {
7011d0f90841SKees Cook			WARN("STRNCPY",
7012d0f90841SKees Cook			     "Prefer strscpy, strscpy_pad, or __nonstring over strncpy - see: https://github.com/KSPP/linux/issues/90\n" . $herecurr);
70135dbdb2d8SJoe Perches		}
70145dbdb2d8SJoe Perches
7015d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
70165b57980dSJoe Perches		if ($perl_version_ok &&
7017d1fe9c09SJoe Perches		    defined $stat &&
7018d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
7019d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
7020d7c76ba7SJoe Perches				my $call = $1;
7021d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
7022d7c76ba7SJoe Perches				my $arg1 = $3;
7023d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
7024d1fe9c09SJoe Perches				my $arg2 = $8;
7025d7c76ba7SJoe Perches				my $cast;
7026d7c76ba7SJoe Perches
7027d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
7028d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
7029d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
7030d7c76ba7SJoe Perches					$cast = $cast1;
7031d7c76ba7SJoe Perches				} else {
7032d7c76ba7SJoe Perches					$cast = $cast2;
7033d7c76ba7SJoe Perches				}
7034d7c76ba7SJoe Perches				WARN("MINMAX",
7035d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
7036554e165cSAndy Whitcroft			}
7037554e165cSAndy Whitcroft		}
7038554e165cSAndy Whitcroft
70394a273195SJoe Perches# check usleep_range arguments
70405b57980dSJoe Perches		if ($perl_version_ok &&
70414a273195SJoe Perches		    defined $stat &&
70424a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
70434a273195SJoe Perches			my $min = $1;
70444a273195SJoe Perches			my $max = $7;
70454a273195SJoe Perches			if ($min eq $max) {
70464a273195SJoe Perches				WARN("USLEEP_RANGE",
7047458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
70484a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
70494a273195SJoe Perches				 $min > $max) {
70504a273195SJoe Perches				WARN("USLEEP_RANGE",
7051458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
70524a273195SJoe Perches			}
70534a273195SJoe Perches		}
70544a273195SJoe Perches
7055823b794cSJoe Perches# check for naked sscanf
70565b57980dSJoe Perches		if ($perl_version_ok &&
7057823b794cSJoe Perches		    defined $stat &&
70586c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
7059823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
7060823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
7061823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
7062823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
7063823b794cSJoe Perches			$lc = $lc + $linenr;
70642a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
7065823b794cSJoe Perches			WARN("NAKED_SSCANF",
7066823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
7067823b794cSJoe Perches		}
7068823b794cSJoe Perches
7069afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
70705b57980dSJoe Perches		if ($perl_version_ok &&
7071afc819abSJoe Perches		    defined $stat &&
7072afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
7073afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
7074afc819abSJoe Perches			$lc = $lc + $linenr;
70752a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
7076afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
7077afc819abSJoe Perches				my $format = $6;
7078afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
7079afc819abSJoe Perches				if ($count == 1 &&
7080afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
7081afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
7082afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
7083afc819abSJoe Perches				}
7084afc819abSJoe Perches			}
7085afc819abSJoe Perches		}
7086afc819abSJoe Perches
708770dc8a48SJoe Perches# check for new externs in .h files.
708870dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
708970dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
7090d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
709170dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
709270dc8a48SJoe Perches			    $fix) {
7093194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
709470dc8a48SJoe Perches			}
709570dc8a48SJoe Perches		}
709670dc8a48SJoe Perches
7097de7d4f0eSAndy Whitcroft# check for new externs in .c files.
7098171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
7099c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
7100171ae1a4SAndy Whitcroft		{
7101c45dcabdSAndy Whitcroft			my $function_name = $1;
7102c45dcabdSAndy Whitcroft			my $paren_space = $2;
7103171ae1a4SAndy Whitcroft
7104171ae1a4SAndy Whitcroft			my $s = $stat;
7105171ae1a4SAndy Whitcroft			if (defined $cond) {
7106171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
7107171ae1a4SAndy Whitcroft			}
7108d8b44b58SKees Cook			if ($s =~ /^\s*;/)
7109c45dcabdSAndy Whitcroft			{
7110000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
7111000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
7112de7d4f0eSAndy Whitcroft			}
7113de7d4f0eSAndy Whitcroft
7114171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
7115000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
7116000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
7117171ae1a4SAndy Whitcroft			}
71189c9ba34eSAndy Whitcroft
71199c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
71205b2c7334SJim Cromie		    $stat =~ /^\+extern struct\s+(\w+)\s+(\w+)\[\];/)
71215b2c7334SJim Cromie		{
71225b2c7334SJim Cromie			my ($st_type, $st_name) = ($1, $2);
71235b2c7334SJim Cromie
71245b2c7334SJim Cromie			for my $s (keys %maybe_linker_symbol) {
71255b2c7334SJim Cromie			    #print "Linker symbol? $st_name : $s\n";
71265b2c7334SJim Cromie			    goto LIKELY_LINKER_SYMBOL
71275b2c7334SJim Cromie				if $st_name =~ /$s/;
71285b2c7334SJim Cromie			}
71295b2c7334SJim Cromie			WARN("AVOID_EXTERNS",
71305b2c7334SJim Cromie			     "found a file-scoped extern type:$st_type name:$st_name in .c file\n"
71315b2c7334SJim Cromie			     . "is this a linker symbol ?\n" . $herecurr);
71325b2c7334SJim Cromie		  LIKELY_LINKER_SYMBOL:
71335b2c7334SJim Cromie
71345b2c7334SJim Cromie		} elsif ($realfile =~ /\.c$/ && defined $stat &&
71359c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
71369c9ba34eSAndy Whitcroft		{
7137000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
7138000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
7139171ae1a4SAndy Whitcroft		}
7140171ae1a4SAndy Whitcroft
7141a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
7142a0ad7596SJoe Perches		if (defined $stat &&
7143d8b44b58SKees Cook		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
7144d8b44b58SKees Cook		    $1 ne "void") {
7145d8b44b58SKees Cook			my $args = trim($1);
7146ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
7147ca0d8929SJoe Perches				my $arg = trim($1);
7148d8b44b58SKees Cook				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
7149ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
7150ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
7151ca0d8929SJoe Perches				}
7152ca0d8929SJoe Perches			}
7153ca0d8929SJoe Perches		}
7154ca0d8929SJoe Perches
7155a0ad7596SJoe Perches# check for function definitions
71565b57980dSJoe Perches		if ($perl_version_ok &&
7157a0ad7596SJoe Perches		    defined $stat &&
7158a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
7159a0ad7596SJoe Perches			$context_function = $1;
7160a0ad7596SJoe Perches
7161a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
7162a0ad7596SJoe Perches			my $ok = 0;
7163a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
7164a0ad7596SJoe Perches			my $herectx = $here . "\n";
7165a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
7166a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
7167a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
7168a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
7169a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
7170a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
7171a0ad7596SJoe Perches			}
7172a0ad7596SJoe Perches			if (!$ok) {
7173a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
7174a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
7175a0ad7596SJoe Perches			}
7176a0ad7596SJoe Perches		}
7177a0ad7596SJoe Perches
7178de7d4f0eSAndy Whitcroft# checks for new __setup's
7179de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
7180de7d4f0eSAndy Whitcroft			my $name = $1;
7181de7d4f0eSAndy Whitcroft
7182de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
7183000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
71842581ac7cSTim Froidcoeur				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);
7185de7d4f0eSAndy Whitcroft			}
7186653d4876SAndy Whitcroft		}
71879c0ca6f9SAndy Whitcroft
7188e29a70f1SJoe Perches# check for pointless casting of alloc functions
7189e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
7190000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
7191000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
71929c0ca6f9SAndy Whitcroft		}
719313214adfSAndy Whitcroft
7194a640d25cSJoe Perches# alloc style
7195a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
71965b57980dSJoe Perches		if ($perl_version_ok &&
7197e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
7198a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
7199a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
7200a640d25cSJoe Perches		}
7201a640d25cSJoe Perches
720273f1d07eSGustavo A. R. Silva# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc
72035b57980dSJoe Perches		if ($perl_version_ok &&
72041b4a2ed4SJoe Perches		    defined $stat &&
720573f1d07eSGustavo A. R. Silva		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
720660a55369SJoe Perches			my $oldfunc = $3;
720760a55369SJoe Perches			my $a1 = $4;
720860a55369SJoe Perches			my $a2 = $10;
720960a55369SJoe Perches			my $newfunc = "kmalloc_array";
721073f1d07eSGustavo A. R. Silva			$newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");
721173f1d07eSGustavo A. R. Silva			$newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");
721260a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
721360a55369SJoe Perches			my $r1 = $a1;
721460a55369SJoe Perches			my $r2 = $a2;
721560a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
721660a55369SJoe Perches				$r1 = $a2;
721760a55369SJoe Perches				$r2 = $a1;
721860a55369SJoe Perches			}
7219e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
7220e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
72211b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
7222e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
7223e3d95a2aSTobin C. Harding
7224e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
72251b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
72261b4a2ed4SJoe Perches				    $cnt == 1 &&
7227e367455aSJoe Perches				    $fix) {
722873f1d07eSGustavo 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;
722960a55369SJoe Perches				}
723060a55369SJoe Perches			}
723160a55369SJoe Perches		}
723260a55369SJoe Perches
7233972fdea2SJoe Perches# check for krealloc arg reuse
72345b57980dSJoe Perches		if ($perl_version_ok &&
72354cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
72364cab63ceSJoe Perches		    $1 eq $3) {
7237972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
7238972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
7239972fdea2SJoe Perches		}
7240972fdea2SJoe Perches
72415ce59ae0SJoe Perches# check for alloc argument mismatch
72423965292aSLiao Chang		if ($line =~ /\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/) {
72435ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
72445ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
72455ce59ae0SJoe Perches		}
72465ce59ae0SJoe Perches
7247caf2a54fSJoe Perches# check for multiple semicolons
7248caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
7249d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
7250d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
7251d5e616fcSJoe Perches			    $fix) {
7252194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
7253d5e616fcSJoe Perches			}
7254d1e2ad07SJoe Perches		}
7255d1e2ad07SJoe Perches
7256cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
7257cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
7258cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
72590ab90191SJoe Perches			my $ull = "";
72600ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
72610ab90191SJoe Perches			if (CHK("BIT_MACRO",
72620ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
72630ab90191SJoe Perches			    $fix) {
72640ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
72650ab90191SJoe Perches			}
72660ab90191SJoe Perches		}
72670ab90191SJoe Perches
726850161266SJoe Perches# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)
72693e89ad85SJerome Forissier		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {
727050161266SJoe Perches			WARN("IS_ENABLED_CONFIG",
72713e89ad85SJerome Forissier			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);
727250161266SJoe Perches		}
727350161266SJoe Perches
72742d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
72753e89ad85SJerome 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*$/) {
72762d632745SJoe Perches			my $config = $1;
72772d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
72783e89ad85SJerome Forissier				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&
72792d632745SJoe Perches			    $fix) {
72802d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
72812d632745SJoe Perches			}
72822d632745SJoe Perches		}
72832d632745SJoe Perches
7284f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
7285f36d3eb8SJoe Perches		my @fallthroughs = (
7286f36d3eb8SJoe Perches			'fallthrough',
7287f36d3eb8SJoe Perches			'@fallthrough@',
7288f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
7289f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
7290f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
7291f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7292f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
7293f36d3eb8SJoe Perches		    );
7294f36d3eb8SJoe Perches		if ($raw_comment ne '') {
7295f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
7296f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
7297f36d3eb8SJoe Perches					my $msg_level = \&WARN;
7298f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
7299f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
7300f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
7301f36d3eb8SJoe Perches					last;
7302f36d3eb8SJoe Perches				}
7303f36d3eb8SJoe Perches			}
7304f36d3eb8SJoe Perches		}
7305f36d3eb8SJoe Perches
7306d1e2ad07SJoe Perches# check for switch/default statements without a break;
73075b57980dSJoe Perches		if ($perl_version_ok &&
7308d1e2ad07SJoe Perches		    defined $stat &&
7309d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
7310d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
7311e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
7312e3d95a2aSTobin C. Harding
7313d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
7314d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
7315caf2a54fSJoe Perches		}
7316caf2a54fSJoe Perches
731713214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
7318d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
7319d5e616fcSJoe Perches			if (WARN("USE_FUNC",
7320d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
7321d5e616fcSJoe Perches			    $fix) {
7322194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
7323d5e616fcSJoe Perches			}
732413214adfSAndy Whitcroft		}
7325773647a0SAndy Whitcroft
732662ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
732762ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
732862ec818fSJoe Perches			ERROR("DATE_TIME",
732962ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
733062ec818fSJoe Perches		}
733162ec818fSJoe Perches
73322c92488aSJoe Perches# check for use of yield()
73332c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
73342c92488aSJoe Perches			WARN("YIELD",
73352c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
73362c92488aSJoe Perches		}
73372c92488aSJoe Perches
7338179f8f40SJoe Perches# check for comparisons against true and false
7339179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
7340179f8f40SJoe Perches			my $lead = $1;
7341179f8f40SJoe Perches			my $arg = $2;
7342179f8f40SJoe Perches			my $test = $3;
7343179f8f40SJoe Perches			my $otype = $4;
7344179f8f40SJoe Perches			my $trail = $5;
7345179f8f40SJoe Perches			my $op = "!";
7346179f8f40SJoe Perches
7347179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
7348179f8f40SJoe Perches
7349179f8f40SJoe Perches			my $type = lc($otype);
7350179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
7351179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
7352179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
7353179f8f40SJoe Perches					$op = "";
7354179f8f40SJoe Perches				}
7355179f8f40SJoe Perches
7356179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
7357179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
7358179f8f40SJoe Perches
7359179f8f40SJoe Perches## maybe suggesting a correct construct would better
7360179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
7361179f8f40SJoe Perches
7362179f8f40SJoe Perches			}
7363179f8f40SJoe Perches		}
7364179f8f40SJoe Perches
73654882720bSThomas Gleixner# check for semaphores initialized locked
73664882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
7367000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
7368000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
7369773647a0SAndy Whitcroft		}
73706712d858SJoe Perches
737167d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
737267d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
7373000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
737467d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
7375773647a0SAndy Whitcroft		}
73766712d858SJoe Perches
7377ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
7378f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
7379000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
7380ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
7381f3db6639SMichael Ellerman		}
73826712d858SJoe Perches
73833d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
73843d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
73853d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
73863d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
73873d709ab5SPaul E. McKenney		}
73883d709ab5SPaul E. McKenney
73899189c7e7SJoe Perches# check for deprecated apis
73909189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
73919189c7e7SJoe Perches			my $deprecated_api = $1;
73929189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
73939189c7e7SJoe Perches			WARN("DEPRECATED_API",
73949189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
73959189c7e7SJoe Perches		}
73969189c7e7SJoe Perches
73970f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
7398d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
7399ced69da1SQuentin Monnet		if (defined($const_structs) &&
7400ced69da1SQuentin Monnet		    $line !~ /\bconst\b/ &&
7401d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
7402000d1cc1SJoe Perches			WARN("CONST_STRUCT",
7403d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
74042b6db5cbSAndy Whitcroft		}
7405773647a0SAndy Whitcroft
7406773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
7407773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
740835cdcbfcSPeng Wang# ignore designated initializers using NR_CPUS
7409773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
7410c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
7411c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
7412171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
7413171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
741435cdcbfcSPeng Wang		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&
741535cdcbfcSPeng Wang		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)
7416773647a0SAndy Whitcroft		{
7417000d1cc1SJoe Perches			WARN("NR_CPUS",
7418000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
7419773647a0SAndy Whitcroft		}
74209c9ba34eSAndy Whitcroft
742152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
742252ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
742352ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
742452ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
742552ea8506SJoe Perches		}
742652ea8506SJoe Perches
7427acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
74285b57980dSJoe Perches		if ($perl_version_ok &&
7429acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
7430acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
7431acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
7432acd9362cSJoe Perches		}
7433acd9362cSJoe Perches
7434fbe74541SJoe Perches# return sysfs_emit(foo, fmt, ...) fmt without newline
7435fbe74541SJoe Perches		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&
7436fbe74541SJoe Perches		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {
7437fbe74541SJoe Perches			my $offset = $+[6] - 1;
7438fbe74541SJoe Perches			if (WARN("SYSFS_EMIT",
7439fbe74541SJoe Perches				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&
7440fbe74541SJoe Perches			    $fix) {
7441fbe74541SJoe Perches				substr($fixed[$fixlinenr], $offset, 0) = '\\n';
7442fbe74541SJoe Perches			}
7443fbe74541SJoe Perches		}
7444fbe74541SJoe Perches
74458515e4a7SKees Cook# check for array definition/declarations that should use flexible arrays instead
74468515e4a7SKees Cook		if ($sline =~ /^[\+ ]\s*\}(?:\s*__packed)?\s*;\s*$/ &&
74478515e4a7SKees Cook		    $prevline =~ /^\+\s*(?:\}(?:\s*__packed\s*)?|$Type)\s*$Ident\s*\[\s*(0|1)\s*\]\s*;\s*$/) {
74488515e4a7SKees Cook			if (ERROR("FLEXIBLE_ARRAY",
74498515e4a7SKees Cook				  "Use C99 flexible arrays - see https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays\n" . $hereprev) &&
74508515e4a7SKees Cook			    $1 == '0' && $fix) {
74518515e4a7SKees Cook				$fixed[$fixlinenr - 1] =~ s/\[\s*0\s*\]/[]/;
74528515e4a7SKees Cook			}
74538515e4a7SKees Cook		}
74548515e4a7SKees Cook
7455de3f186fSDenis Efremov# nested likely/unlikely calls
7456de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
7457de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
7458de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
7459de3f186fSDenis Efremov		}
7460de3f186fSDenis Efremov
7461691d77b6SAndy Whitcroft# whine mightly about in_atomic
7462691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
7463691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
7464000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
7465000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
7466f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
7467000d1cc1SJoe Perches				WARN("IN_ATOMIC",
7468000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
7469691d77b6SAndy Whitcroft			}
7470691d77b6SAndy Whitcroft		}
74711704f47bSPeter Zijlstra
747284dd7f19SPaul E. McKenney# Complain about RCU Tasks Trace used outside of BPF (and of course, RCU).
747384dd7f19SPaul E. McKenney		our $rcu_trace_funcs = qr{(?x:
747484dd7f19SPaul E. McKenney			rcu_read_lock_trace |
747584dd7f19SPaul E. McKenney			rcu_read_lock_trace_held |
747684dd7f19SPaul E. McKenney			rcu_read_unlock_trace |
747784dd7f19SPaul E. McKenney			call_rcu_tasks_trace |
747884dd7f19SPaul E. McKenney			synchronize_rcu_tasks_trace |
747984dd7f19SPaul E. McKenney			rcu_barrier_tasks_trace |
748084dd7f19SPaul E. McKenney			rcu_request_urgent_qs_task
748184dd7f19SPaul E. McKenney		)};
748284dd7f19SPaul E. McKenney		our $rcu_trace_paths = qr{(?x:
748384dd7f19SPaul E. McKenney			kernel/bpf/ |
748484dd7f19SPaul E. McKenney			include/linux/bpf |
748584dd7f19SPaul E. McKenney			net/bpf/ |
748684dd7f19SPaul E. McKenney			kernel/rcu/ |
748784dd7f19SPaul E. McKenney			include/linux/rcu
748884dd7f19SPaul E. McKenney		)};
748984dd7f19SPaul E. McKenney		if ($line =~ /\b($rcu_trace_funcs)\s*\(/) {
749084dd7f19SPaul E. McKenney			if ($realfile !~ m{^$rcu_trace_paths}) {
749184dd7f19SPaul E. McKenney				WARN("RCU_TASKS_TRACE",
749284dd7f19SPaul E. McKenney				     "use of RCU tasks trace is incorrect outside BPF or core RCU code\n" . $herecurr);
749384dd7f19SPaul E. McKenney			}
749484dd7f19SPaul E. McKenney		}
749584dd7f19SPaul E. McKenney
74961704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
74971704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
74981704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
74991704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
75001704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
75011704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
7502000d1cc1SJoe Perches				ERROR("LOCKDEP",
7503000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
75041704f47bSPeter Zijlstra			}
75051704f47bSPeter Zijlstra		}
750688f8831cSDave Jones
7507b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
7508b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
7509000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
7510000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
751188f8831cSDave Jones		}
75122435880fSJoe Perches
751300180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
751400180468SJoe Perches# and whether or not function naming is typical and if
751500180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
75165b57980dSJoe Perches		if ($perl_version_ok &&
751700180468SJoe Perches		    defined $stat &&
751800180468SJoe 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*\)/) {
751900180468SJoe Perches			my $var = $1;
752000180468SJoe Perches			my $perms = $2;
752100180468SJoe Perches			my $show = $3;
752200180468SJoe Perches			my $store = $4;
752300180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
752400180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
752500180468SJoe Perches			    $store =~ /^${var}_store$/ &&
752600180468SJoe Perches			    $octal_perms eq "0644") {
752700180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
752800180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
752900180468SJoe Perches				    $fix) {
753000180468SJoe 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})/;
753100180468SJoe Perches				}
753200180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
753300180468SJoe Perches				 $store =~ /^NULL$/ &&
753400180468SJoe Perches				 $octal_perms eq "0444") {
753500180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
753600180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
753700180468SJoe Perches				    $fix) {
753800180468SJoe 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})/;
753900180468SJoe Perches				}
754000180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
754100180468SJoe Perches				 $store =~ /^${var}_store$/ &&
754200180468SJoe Perches				 $octal_perms eq "0200") {
754300180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
754400180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
754500180468SJoe Perches				    $fix) {
754600180468SJoe 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})/;
754700180468SJoe Perches				}
754800180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
754900180468SJoe Perches				 $octal_perms eq "0444" ||
755000180468SJoe Perches				 $octal_perms eq "0200") {
755100180468SJoe Perches				my $newshow = "$show";
755200180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
755300180468SJoe Perches				my $newstore = $store;
755400180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
755500180468SJoe Perches				my $rename = "";
755600180468SJoe Perches				if ($show ne $newshow) {
755700180468SJoe Perches					$rename .= " '$show' to '$newshow'";
755800180468SJoe Perches				}
755900180468SJoe Perches				if ($store ne $newstore) {
756000180468SJoe Perches					$rename .= " '$store' to '$newstore'";
756100180468SJoe Perches				}
756200180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
756300180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
756400180468SJoe Perches			} else {
756500180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
756600180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
756700180468SJoe Perches			}
756800180468SJoe Perches		}
756900180468SJoe Perches
7570515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
7571515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
757273121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
757373121534SJoe Perches#   specific definition of not visible in sysfs.
757473121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
757573121534SJoe Perches#   use the default permissions
75765b57980dSJoe Perches		if ($perl_version_ok &&
7577459cf0aeSJoe Perches		    defined $stat &&
7578515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
75792435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
75802435880fSJoe Perches				my $func = $entry->[0];
75812435880fSJoe Perches				my $arg_pos = $entry->[1];
75822435880fSJoe Perches
7583459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
7584459cf0aeSJoe Perches				$lc = $lc + $linenr;
75852a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
7586459cf0aeSJoe Perches
75872435880fSJoe Perches				my $skip_args = "";
75882435880fSJoe Perches				if ($arg_pos > 1) {
75892435880fSJoe Perches					$arg_pos--;
75902435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
75912435880fSJoe Perches				}
7592f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
7593459cf0aeSJoe Perches				if ($stat =~ /$test/) {
75942435880fSJoe Perches					my $val = $1;
75952435880fSJoe Perches					$val = $6 if ($skip_args ne "");
759673121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
759773121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
759873121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
75992435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
7600459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
7601f90774e1SJoe Perches					}
7602f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
7603c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
7604459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
76052435880fSJoe Perches					}
7606459cf0aeSJoe Perches				}
7607459cf0aeSJoe Perches			}
7608459cf0aeSJoe Perches		}
7609459cf0aeSJoe Perches
7610459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
7611bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
761200180468SJoe Perches			my $oval = $1;
761300180468SJoe Perches			my $octal = perms_to_octal($oval);
7614f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
7615459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
7616f90774e1SJoe Perches			    $fix) {
761700180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
76182435880fSJoe Perches			}
761913214adfSAndy Whitcroft		}
76205a6d20ceSBjorn Andersson
76215a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
76225a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
76235a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
76245a6d20ceSBjorn Andersson			my $valid_licenses = qr{
76255a6d20ceSBjorn Andersson						GPL|
76265a6d20ceSBjorn Andersson						GPL\ v2|
76275a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
76285a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
76295a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
76305a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
76315a6d20ceSBjorn Andersson						Proprietary
76325a6d20ceSBjorn Andersson					}x;
76335a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
76345a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
76355a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
76365a6d20ceSBjorn Andersson			}
76376e8f42dcSJoe Perches			if (!$file && $extracted_string eq '"GPL v2"') {
76386e8f42dcSJoe Perches				if (WARN("MODULE_LICENSE",
76396e8f42dcSJoe Perches				     "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&
76406e8f42dcSJoe Perches				    $fix) {
76416e8f42dcSJoe Perches					$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;
76426e8f42dcSJoe Perches				}
76436e8f42dcSJoe Perches			}
76445a6d20ceSBjorn Andersson		}
76456a8d76cbSMatteo Croce
76466a8d76cbSMatteo Croce# check for sysctl duplicate constants
76476a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
76486a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
76496a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
76506a8d76cbSMatteo Croce		}
7651515a235eSJoe Perches	}
765213214adfSAndy Whitcroft
765313214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
765413214adfSAndy Whitcroft	# so just keep quiet.
765513214adfSAndy Whitcroft	if ($#rawlines == -1) {
765613214adfSAndy Whitcroft		exit(0);
76570a920b5bSAndy Whitcroft	}
76580a920b5bSAndy Whitcroft
76598905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
76608905a67cSAndy Whitcroft	# things that appear to be patches.
76618905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
76628905a67cSAndy Whitcroft		exit(0);
76638905a67cSAndy Whitcroft	}
76648905a67cSAndy Whitcroft
7665e73d2715SDwaipayan Ray	# This is not a patch, and we are in 'no-patch' mode so
76668905a67cSAndy Whitcroft	# just keep quiet.
76678905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
76688905a67cSAndy Whitcroft		exit(0);
76698905a67cSAndy Whitcroft	}
76708905a67cSAndy Whitcroft
7671a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
7672000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
7673000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
76740a920b5bSAndy Whitcroft	}
7675cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
7676cd261496SGeert Uytterhoeven		if ($signoff == 0) {
7677000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
7678000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
767948ca2d8aSDwaipayan Ray		} elsif ($authorsignoff != 1) {
768048ca2d8aSDwaipayan Ray			# authorsignoff values:
768148ca2d8aSDwaipayan Ray			# 0 -> missing sign off
768248ca2d8aSDwaipayan Ray			# 1 -> sign off identical
768348ca2d8aSDwaipayan Ray			# 2 -> names and addresses match, comments mismatch
768448ca2d8aSDwaipayan Ray			# 3 -> addresses match, names different
768548ca2d8aSDwaipayan Ray			# 4 -> names match, addresses different
768648ca2d8aSDwaipayan Ray			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match
768748ca2d8aSDwaipayan Ray
768848ca2d8aSDwaipayan Ray			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'";
768948ca2d8aSDwaipayan Ray
769048ca2d8aSDwaipayan Ray			if ($authorsignoff == 0) {
769148ca2d8aSDwaipayan Ray				ERROR("NO_AUTHOR_SIGN_OFF",
7692cd261496SGeert Uytterhoeven				      "Missing Signed-off-by: line by nominal patch author '$author'\n");
769348ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 2) {
769448ca2d8aSDwaipayan Ray				CHK("FROM_SIGN_OFF_MISMATCH",
769548ca2d8aSDwaipayan Ray				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");
769648ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 3) {
769748ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
769848ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");
769948ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 4) {
770048ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
770148ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email address mismatch: $sob_msg\n");
770248ca2d8aSDwaipayan Ray			} elsif ($authorsignoff == 5) {
770348ca2d8aSDwaipayan Ray				WARN("FROM_SIGN_OFF_MISMATCH",
770448ca2d8aSDwaipayan Ray				     "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n");
770548ca2d8aSDwaipayan Ray			}
7706cd261496SGeert Uytterhoeven		}
77070a920b5bSAndy Whitcroft	}
77080a920b5bSAndy Whitcroft
7709f0a594c1SAndy Whitcroft	print report_dump();
771013214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
771113214adfSAndy Whitcroft		print "$filename " if ($summary_file);
77126c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
77136c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
77146c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
77156c72ffaaSAndy Whitcroft	}
77168905a67cSAndy Whitcroft
7717d2c0a235SAndy Whitcroft	if ($quiet == 0) {
7718ef212196SJoe Perches		# If there were any defects found and not already fixing them
7719ef212196SJoe Perches		if (!$clean and !$fix) {
7720ef212196SJoe Perches			print << "EOM"
7721ef212196SJoe Perches
7722ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
7723ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
7724ef212196SJoe PerchesEOM
7725ef212196SJoe Perches		}
7726d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
7727d2c0a235SAndy Whitcroft		# then suggest that.
7728d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
7729b0781216SMike Frysinger			$rpt_cleaners = 0;
7730d8469f16SJoe Perches			print << "EOM"
7731d8469f16SJoe Perches
7732d8469f16SJoe PerchesNOTE: Whitespace errors detected.
7733d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
7734d8469f16SJoe PerchesEOM
7735d2c0a235SAndy Whitcroft		}
7736d2c0a235SAndy Whitcroft	}
7737d2c0a235SAndy Whitcroft
7738d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
7739d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
7740d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
77419624b8d6SJoe Perches		my $newfile = $filename;
77429624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
77433705ce5bSJoe Perches		my $linecount = 0;
77443705ce5bSJoe Perches		my $f;
77453705ce5bSJoe Perches
7746d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
7747d752fcc8SJoe Perches
77483705ce5bSJoe Perches		open($f, '>', $newfile)
77493705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
77503705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
77513705ce5bSJoe Perches			$linecount++;
77523705ce5bSJoe Perches			if ($file) {
77533705ce5bSJoe Perches				if ($linecount > 3) {
77543705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
77553705ce5bSJoe Perches					print $f $fixed_line . "\n";
77563705ce5bSJoe Perches				}
77573705ce5bSJoe Perches			} else {
77583705ce5bSJoe Perches				print $f $fixed_line . "\n";
77593705ce5bSJoe Perches			}
77603705ce5bSJoe Perches		}
77613705ce5bSJoe Perches		close($f);
77623705ce5bSJoe Perches
77633705ce5bSJoe Perches		if (!$quiet) {
77643705ce5bSJoe Perches			print << "EOM";
7765d8469f16SJoe Perches
77663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
77673705ce5bSJoe Perches
77683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
77693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
77703705ce5bSJoe Perches
77713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
77723705ce5bSJoe PerchesNo warranties, expressed or implied...
77733705ce5bSJoe PerchesEOM
77743705ce5bSJoe Perches		}
77753705ce5bSJoe Perches	}
77763705ce5bSJoe Perches
7777d8469f16SJoe Perches	if ($quiet == 0) {
7778d8469f16SJoe Perches		print "\n";
7779d8469f16SJoe Perches		if ($clean == 1) {
7780d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
7781d8469f16SJoe Perches		} else {
7782d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
77830a920b5bSAndy Whitcroft		}
77840a920b5bSAndy Whitcroft	}
77850a920b5bSAndy Whitcroft	return $clean;
77860a920b5bSAndy Whitcroft}
7787